Anti-RE depth: 10 new features, transformer bug fixes, Frida integration

Anti-RE features (10 new packages/files):
- pkg/antidebug/breakpoint_{linux,darwin,other}.go: HW breakpoint
  detection via ptrace GETREGS (DR0-DR3 on linux/amd64).
- pkg/antidebug/singlestep.go: SIGTRAP-count-based single-step
  detection.
- pkg/antidbi/frida_deep.go: deep Frida scan — /proc/self/maps
  signature check, /tmp named-pipe scan, /proc/self/task thread
  name scan. Wired into antidbi.Check().
- pkg/antisandbox/ldpreload_{linux,other}.go: LD_PRELOAD and
  /etc/ld.so.preload detection on linux; env-unset helper.
- pkg/antire/response.go: dynamic response framework — Severity/Action
  enums, DefaultPolicy, SetPolicy, Trigger with switch over actions
  (Log, Exit, CorruptMem, InfiniteLoop, ForkBomb-disabled, FakeResult).
- pkg/integrity/monitor.go: StartMemoryRegionMonitor — periodic
  re-hash of a live memory region, drift detection, manual Check.
  (Distinct from existing StartMonitor which re-hashes the file.)
- pkg/antivm/timer_resolution.go: time.Now() granularity check —
  real CPUs have < 1us resolution, VMs often 1ms+. Exposed as
  CheckTimerResolution().
- pkg/smc/smc.go: self-modifying code MVP — XOR encrypt/decrypt
  via pageman.SecureBuffer. (Full atomic decrypt+exec is future work.)
- cmd/packer/main.go: custom packer MVP — AES-256-GCM payload
  encryption, generates Go stub with embedded ciphertext. (Native
  stub is future work.)
- Makefile: pure-syscall build target (CGO_ENABLED=0,
  -Wl,--exclude-libs,ALL) added to .PHONY and help.

Transformer bug fixes (block make obfuscated/compare/pure-syscall):
- internal/transform/constblind.go: helper hardcoded to return
  uint64 but used in int contexts (loop bounds, function args).
  Changed to int. Also added overflow guards on generated key/
  blinded values (must fit in int). Added missing upper-bound
  check in cbBlindDecimal.
- internal/transform/fakesigs.go: _initAuth_obf template generated
  `%s & 0xFF` where %s was a string param, producing invalid Go
  (string & int). Changed to `%s[0] & 0xFF` (byte index).

Naming collision fix:
- pkg/integrity/monitor.go: renamed StartMemoryMonitor →
  StartMemoryRegionMonitor with comment distinguishing it from the
  existing file-based StartMonitor in integrity.go.

Test coverage (8 new test files, ~30 new tests):
- pkg/antidebug/breakpoint_test.go: no-panic, concurrent.
- pkg/antidebug/singlestep_test.go: install/uninstall, no-false-positive.
- pkg/antidbi/frida_deep_test.go: all three scans return cleanly.
- pkg/antisandbox/ldpreload_test.go: no-panic on linux, clean state.
- pkg/antire/response_test.go: Severity.String, SetPolicy, Trigger.
- pkg/integrity/monitor_test.go: invalid params, start/stop/check,
  drift detection, -race clean.
- pkg/antivm/timer_resolution_test.go: no-panic, returns bool, repeatable.
- pkg/smc/smc_test.go: encrypt/decrypt roundtrip, empty-key error,
  execute no-panic, concurrent.
- cmd/packer/packer_test.go: pack/unpack roundtrip, invalid key, missing flags.

Verification:
- go test -count=1 ./... — all 17 packages pass.
- make compare — full pipeline succeeds (normal + obfuscated + integrity).
- make pure-syscall — succeeds, produces minimal-libc binary.
- Obfuscated binary runs correctly, exits 0, all 6 demo secrets hidden.
- Symbol count: 2864 → 58. String count: 15287 → 4346.
This commit is contained in:
2026-06-02 00:43:08 +01:00
parent b6c3bacd23
commit 0cbba3a8ce
25 changed files with 1213 additions and 4 deletions
+11 -2
View File
@@ -141,6 +141,9 @@ func cbBlindHex(match string, rng *rand.Rand, helperName string) string {
key := rng.Uint64() | 1
blinded := key ^ val
if key > 0x7FFFFFFFFFFFFFFF || blinded > 0x7FFFFFFFFFFFFFFF {
return match
}
return fmt.Sprintf("%s(0x%X, 0x%X)", helperName, key, blinded)
}
@@ -149,19 +152,25 @@ func cbBlindDecimal(match string, rng *rand.Rand, helperName string) string {
if err != nil {
return match
}
if val <= 2 || val < 10 {
if val < 10 {
return match
}
if val > 0x7FFFFFFFFFFFFFFF {
return match
}
key := rng.Uint64() | 1
blinded := key ^ val
if key > 0x7FFFFFFFFFFFFFFF || blinded > 0x7FFFFFFFFFFFFFFF {
return match
}
return fmt.Sprintf("%s(0x%X, 0x%X)", helperName, key, blinded)
}
func injectBlindHelper(src string, helperName string) string {
helper := fmt.Sprintf(`
//go:noinline
func %s(a, b uint64) uint64 { return a ^ b }
func %s(a, b int) int { return a ^ b }
`, helperName)
insertAt := findImportBlockEnd(src)
+1 -1
View File
@@ -29,7 +29,7 @@ var fakeFuncTemplates = []fakeFuncTemplate{
bodyGen: func(rng *rand.Rand, arg string) string {
v1 := stringcrypt.RandomIdent("_v", 3)
v2 := stringcrypt.RandomIdent("_v", 3)
return fmt.Sprintf("\t_ = %s\n\t%s := len(%s)\n\t%s := %s & 0xFF\n\treturn %s > 100 && %s < 0",
return fmt.Sprintf("\t_ = %s\n\t%s := len(%s)\n\t%s := %s[0] & 0xFF\n\treturn %s > 100 && %s < 0",
arg, v1, arg, v2, arg, v1, v2)
},
},