This commit is contained in:
2026-05-31 11:23:07 +01:00
parent 1d51b29b92
commit 5ea458fb06
18 changed files with 1367 additions and 220 deletions
+2
View File
@@ -0,0 +1,2 @@
build/
*.exe
+50 -5
View File
@@ -54,9 +54,9 @@ make transformer
```
Normal Obfuscated
Size: 2707026 3063458
Size: 2707026 3081170
Symbols: 2864 58
Strings: 15335 4302
Strings: 15335 4264
Secret leaks: 1 (LIC-*) 0
Function names: visible 0 (good)
```
@@ -249,6 +249,43 @@ Replaces simple functions with a custom stack-based bytecode VM.
| SWAP | 0x1A | i8 | Swap stack positions |
| ROT | 0x1B | none | Rotate top 3 |
**Junk opcodes:** The compiler inserts random junk opcodes (0x1C-0x1F) at ~33% probability between real instructions. The VM silently consumes them via the `default` case, breaking linear disassembly. Use `CompileWith(program, CompileOpts{NoJunk: true})` for deterministic output.
### 10. Anti-Disassembly Injection
Injects junk `[N]byte` variable declarations at ~15% per statement to confuse disassemblers and decompilers.
```go
// Injected junk — valid Go, but semantically dead
var _j1 = [7]byte{0x4e, 0x6f, 0x70, 0x65, 0x21, 0x00, 0x00}
var _j2 = [12]byte{0xde, 0xad, 0xbe, 0xef, ...}
```
These produce opaque byte sequences in the binary that disassemblers cannot reliably skip.
### 11. Junk String Injection
Adds 4-10 fake string constants per file to dilute the `strings` output and increase noise for analysts.
```go
var _js1 = "xK9mP2vL8nQ4wR7yT"
var _js2 = "aB3cD5eF7gH9iJ1kL"
```
These strings have no semantic effect but increase the string table from ~200 to ~4000+ entries, making secret extraction harder.
### 12. Function Pointer Dispatch
Wraps function calls through function pointer variables to obscure call targets.
```go
var _fptr0 = checkLicense_obf4721 // function pointer variable
//go:noinline
func checkLicense(args ...interface{}) interface{} {
return _fptr0(args...)
}
```
## Runtime Protection Packages
### Syscall Obfuscation (`pkg/syscallobf`)
@@ -257,7 +294,8 @@ Hides syscall numbers from static analysis using XOR-encoded dispatch.
- **Encoding:** Each syscall number is XOR'd with a random `uint64` dispatch key generated once via `sync.Once`
- **Linux (`syscall_linux.go`):** Wraps `ptrace` (101), `getpid` (39), `kill` (62), `open` (2), `close` (3), `read` (0), `lseek` (8), `mmap` (9), `mprotect` (10) via `syscall.RawSyscall`
- **Darwin (`syscall_darwin.go`):** Returns `ENOSYS` stubs (platform-specific implementation pending)
- **Darwin (`syscall_darwin.go`):** Real implementations via encoded SYS_* constants using `syscall.RawSyscall6` — `ptrace`, `sysctl`, `kill`, `getpid`, `mmap`, `mprotect`
- **Windows (`syscall_windows.go`):** `NtQueryInformationProcess`, `NtSetInformationThread` via `ntdll.dll` LazyDLL; `kernel32` ops; `NtProtectVirtualMemory` for mprotect
The anti-debugging package uses these for stealthy `/proc/self/mem` and `/proc/self/maps` access.
@@ -268,12 +306,17 @@ The anti-debugging package uses these for stealthy `/proc/self/mem` and `/proc/s
| Check | Platform | Description |
|-------|----------|-------------|
| `checkPtrace()` | Linux | Reads `/proc/self/status` for non-zero `TracerPid` |
| `checkPtrace()` | Darwin | `sysctl` P_TRACED flag check + `ptrace(PT_DENY_ATTACH)` |
| `disableCoreDump()` | Linux | Writes "0" to `/proc/self/coredump_filter` |
| `checkTiming()` | All | 1M loop iterations must complete in <200ms (detects single-stepping) |
| `checkEnv()` | All | Checks for `GODEBUG`, `DELVE_LISTENER`, `DEBUGINFOD_URL`, `RR_LOG_FILE`, `_JAVA_OPTIONS`, `LD_PRELOAD`, `DYLD_INSERT_LIBRARIES` |
| `checkParentProcess()` | Linux | Reads `/proc/<ppid>/comm`, matches against 12 debugger names |
| `checkFunctionPrologues()` | Linux | Reads `/proc/self/mem` at function addresses, checks for JMP hooks (0xE9, 0xEB, 0xFF 0x25) and INT3 breakpoints (0xCC) |
| `scanForBreakpoints()` | Linux | Parses `/proc/self/maps`, reads executable regions, flags ≥8 consecutive 0xCC bytes |
| Windows anti-debug | Windows | 5 API-based checks + PEB direct read + hardware BP scan + ThreadHideFromDebugger |
| Hook detection | Darwin | Function prologue scanning via reflect pointers, ARM64 B/BR hook detection, INT3 cluster scanning |
| Hook detection | Windows | `ReadProcessMemory` prologue scanning |
| Integrity check | Windows | PE `.text` section SHA-256 hashing via `debug/pe` |
**Background goroutines:**
- `AntiAttach()` — polls `checkPtrace()` every 500ms, exits with code 66 on detection
@@ -335,6 +378,8 @@ Flags:
-flatten Control-flow flattening (default true)
-vm Virtualize simple functions into VM bytecode (default true)
-buildid Inject unique build ID constant (default true)
-anti-disasm Inject anti-disassembly junk variables (default true)
-junk-strings Inject fake strings to dilute strings output (default true)
-seed int Build seed for polymorphic output (0 = use current timestamp)
```
@@ -383,7 +428,7 @@ The `make compare` target verifies all of these are hidden in the obfuscated bin
# Run all package tests
go test ./pkg/...
# VM tests (22 tests: arithmetic, bitwise, comparisons, jumps, callouts, determinism)
# VM tests (23 tests: arithmetic, bitwise, comparisons, jumps, callouts, determinism, junk opcodes)
go test ./pkg/vm/ -v
# Syscall obfuscation tests
@@ -402,6 +447,6 @@ go vet ./...
## Limitations
- **Text-based transformation:** The transformer operates on source text, not Go AST. This limits what can be reliably transformed (e.g., type inference for variable hoisting is heuristic).
- **Darwin syscall stubs:** `pkg/syscallobf` returns `ENOSYS` on macOS. Linux is the primary target for runtime protections.
- **Garble required:** Stage 2 depends on `mvdan.cc/garble` for name mangling, literal encryption, and binary stripping.
- **Simple function virtualization only:** The VM currently handles len-comparisons and arithmetic. Complex control flow is not virtualized.
- **Windows integrity check:** PE `.text` section hashing works but is less battle-tested than ELF/Mach-O paths.
Binary file not shown.
+56 -37
View File
@@ -8,38 +8,58 @@ import (
"os"
"time"
)
var _junkData = [...]string{
"Mozilla/5.0 (Windows NT 10.0)",
"Bearer eyJhbGciOiJIUzI1NiJ9",
"192.168.1.1:8080",
"Mozilla/5.0 (Windows NT 10.0)",
}
var _ = _junkData
var _buildID = "BUILD_1780185895842347000_5717911B" // polymorphic build marker
var _buildID = "BUILD_1780222823944864000_67EC3928" // polymorphic build marker
var _ = _buildID
func getVersion() string { return getVersion_obf2511() }
func getBuildID() string { return getBuildID_obf7656() }
func processRequest(userID string) { processRequest_obf1301(userID) }
func generateToken(userID string) string { return generateToken_obf5646(userID) }
func validateLicense(key string) bool { return validateLicense_obf9184(key) }
func maskString(s string) string { return maskString_obf9182(s) }
var _masterSeed = [32]byte{0xF0, 0x9C, 0xC8, 0x1C, 0xD9, 0x25, 0xA4, 0x69, 0xFE, 0xED, 0xA1, 0x92, 0xD6, 0x1A, 0x62, 0xF1, 0x0C, 0xA7, 0xD0, 0xB9, 0xC3, 0x3B, 0xB4, 0xE0, 0x41, 0x5F, 0x79, 0x14, 0x1F, 0xBB, 0xE1, 0xC5}
var _fptr0 = getVersion_obf1861
//go:noinline
func getVersion() string { return _fptr0() }
var _fptr1 = getBuildID_obf7802
//go:noinline
func getBuildID() string { return _fptr1() }
var _fptr2 = processRequest_obf4807
//go:noinline
func processRequest(userID string) { _fptr2(userID) }
var _fptr3 = generateToken_obf1103
//go:noinline
func generateToken(userID string) string { return _fptr3(userID) }
var _fptr4 = validateLicense_obf1490
//go:noinline
func validateLicense(key string) bool { return _fptr4(key) }
var _fptr5 = maskString_obf3138
//go:noinline
func maskString(s string) string { return _fptr5(s) }
var _masterSeed = [32]byte{0xCE, 0x9B, 0x3F, 0xDB, 0x78, 0xEB, 0xEF, 0xB1, 0xEB, 0x54, 0x01, 0x8E, 0x4E, 0x79, 0x40, 0xFA, 0xAF, 0x5D, 0xE3, 0xBB, 0x25, 0xDD, 0xD4, 0x98, 0x7A, 0x75, 0x36, 0x0D, 0xE8, 0x75, 0x54, 0x4D}
var _encEntries = []strenc.Entry{
{Ciphertext: []byte{0x97, 0xFC, 0x87, 0x6E, 0x07, 0xCF, 0xED, 0xBC, 0xA2, 0xCF, 0x6D, 0x5F, 0xE9, 0x9C, 0x51, 0x81, 0xEA, 0x72, 0x61, 0x41, 0xE0, 0x06, 0xC1, 0x62, 0x99, 0xFE, 0xB7, 0x72, 0xA0, 0x7C, 0x7D, 0xEC, 0x74, 0xF7, 0xA1, 0x88, 0xFE, 0x91, 0x69, 0xE1, 0x6A, 0xA4, 0x71, 0x73, 0xAB, 0x88, 0xBB, 0x91, 0xE5, 0x6E, 0x74, 0xBC, 0x56, 0xD5, 0x16, 0x88, 0x84, 0x96, 0x53, 0x56, 0xCA, 0x2D, 0x98, 0x1D, 0xB7, 0x3B, 0x15, 0xD3, 0xF7, 0x39, 0xCC, 0x73, 0x35, 0xE5, 0x72, 0x5F, 0x4E, 0x72, 0xB4, 0x51, 0x81, 0xA9, 0x9E, 0x5D, 0x1A, 0xF4, 0x53, 0x86, 0x81, 0x1C, 0x20, 0x00}, IV: [16]byte{0x97, 0xFC, 0x87, 0x6E, 0x07, 0xCF, 0xED, 0xBC, 0xA2, 0xCF, 0x6D, 0x5F, 0xF8, 0x65, 0x80, 0x84}},
{Ciphertext: []byte{0x67, 0xDC, 0x11, 0xFA, 0xDC, 0x10, 0x70, 0xA5, 0x8B, 0x78, 0xB7, 0x0B, 0xB2, 0x90, 0xB2, 0x38, 0xEB, 0x1D, 0xFD, 0x3F, 0x25, 0xA9, 0xE7, 0x28, 0x8A, 0x58, 0x82, 0x98, 0xDF, 0xB3, 0xE0, 0x65, 0x82, 0x22, 0x84, 0x91, 0x0E, 0xE0, 0x71, 0xF5, 0x6A, 0x7B, 0x2D, 0xEC, 0x8B, 0x67, 0x34, 0xB2, 0x71, 0xEE, 0x0C, 0xC4, 0xA2, 0x4E, 0x6C, 0x8C, 0x81, 0xCB, 0x41, 0x88, 0x90, 0x28, 0xDA, 0x78, 0x70, 0x45, 0x7A, 0xBB, 0xBD, 0xAD, 0x38, 0x06, 0x15, 0xCA, 0xF4, 0xA7, 0x36, 0xE8, 0xA9, 0x88, 0x8E, 0xFF, 0x72, 0x27, 0x96, 0x87, 0x92, 0xD1, 0x81, 0x0C, 0x7C, 0x80}, IV: [16]byte{0x67, 0xDC, 0x11, 0xFA, 0xDC, 0x10, 0x70, 0xA5, 0x8B, 0x78, 0xB7, 0x0B, 0x1F, 0xC3, 0xF1, 0xEA}},
{Ciphertext: []byte{0x80, 0xA2, 0x11, 0x9A, 0xE8, 0xEB, 0x2C, 0x1D, 0x2B, 0xBE, 0x8D, 0x1E, 0xD9, 0x87, 0x84, 0x25, 0xCD, 0xF5, 0x8E, 0xF7, 0xA2, 0xF2, 0x71, 0x01, 0x8A, 0xCC, 0xF3, 0x86, 0xC7, 0x93, 0x1B, 0xF6, 0xAC, 0xF0, 0x45, 0xA4, 0x62, 0x9F, 0xF7, 0x2B, 0x1C, 0x24, 0x4F, 0x82, 0xCA, 0x08, 0xC3, 0x9C, 0xB0, 0x2E, 0xFA, 0xAE, 0xF6, 0x27, 0x71, 0xDB, 0xE2, 0xC9, 0x50, 0x6E, 0x20, 0xA9, 0x39, 0x8A, 0x2D, 0x2C, 0x12, 0x24, 0x2C, 0x57, 0x16, 0x0A, 0x52, 0xB6, 0x4D, 0x12, 0xA0, 0x4F, 0x7F, 0x5D, 0x0F, 0xF0, 0xB0, 0x41, 0x5C, 0x57, 0x46, 0x4C, 0x7D, 0xAC, 0xB1, 0x00}, IV: [16]byte{0x80, 0xA2, 0x11, 0x9A, 0xE8, 0xEB, 0x2C, 0x1D, 0x2B, 0xBE, 0x8D, 0x1E, 0x82, 0xA5, 0xF5, 0x72}},
{Ciphertext: []byte{0xAE, 0x47, 0xCD, 0xAD, 0x46, 0x2C, 0xD7, 0xC2, 0xF4, 0x37, 0x25, 0xC9, 0x14, 0x8E, 0x90, 0xBD, 0x63, 0xA8, 0x0C, 0xA5, 0x86, 0x02, 0xE0, 0x9C, 0xCD, 0x70, 0xFC, 0x20, 0x51, 0x01, 0x0E, 0xCF, 0x7D, 0xD2, 0xB4, 0x6B, 0x07, 0xE9, 0x2A, 0x6E, 0x89, 0x2F, 0xAC, 0x7A, 0x07, 0xCA, 0x0B, 0x50, 0x12, 0x8F, 0x69, 0x29, 0xC4, 0x58, 0xB0, 0x0E, 0x6E, 0xBF, 0x0C, 0xBD, 0x9B, 0x8B, 0xC0, 0x10, 0xB8, 0x7F, 0x89, 0x7F, 0x85, 0xF8, 0x04, 0xFF, 0x24, 0xE8, 0x68, 0x12, 0x6D, 0xBC, 0x2E, 0xF3, 0xD0, 0xD5, 0x4A, 0x38, 0x1C, 0x12, 0x28, 0xD5, 0x1D, 0x55, 0xC8, 0xF6}, IV: [16]byte{0xAE, 0x47, 0xCD, 0xAD, 0x46, 0x2C, 0xD7, 0xC2, 0xF4, 0x37, 0x25, 0xC9, 0xE9, 0x58, 0x3C, 0x30}},
{Ciphertext: []byte{0x46, 0x59, 0xD5, 0x11, 0x98, 0xE7, 0xC9, 0x0F, 0x00, 0xB9, 0x73, 0xD7, 0x62, 0xF0, 0x2E, 0xC6, 0x19, 0xF9, 0x45, 0xF7, 0x0B, 0x57, 0x35, 0x1F, 0xC9, 0xEB, 0x80, 0xBE, 0x19, 0xBE, 0x6B, 0xE3, 0x82, 0x39, 0x88, 0xF6, 0x95, 0x67, 0x47, 0x7D, 0xBC, 0xC9, 0xD3, 0x83, 0x1C, 0xAE, 0x47, 0xEF, 0xD6, 0x6D, 0x49, 0x01, 0xEA, 0x7F, 0x9A, 0x96, 0xEC, 0xA8, 0x22, 0x7A, 0x1D, 0x49, 0x2B, 0x34, 0x22, 0x2A, 0xFF, 0x3F, 0xF1, 0xEB, 0xDD, 0x5B, 0xB5, 0xFD, 0xB3, 0x6B, 0x4A, 0x44, 0x16, 0xCB, 0x9A, 0x70, 0x1F, 0xD9, 0x32, 0x0C, 0x4D, 0x96, 0x6D, 0x26, 0xCB, 0x93}, IV: [16]byte{0x46, 0x59, 0xD5, 0x11, 0x98, 0xE7, 0xC9, 0x0F, 0x00, 0xB9, 0x73, 0xD7, 0x67, 0x7C, 0x66, 0x1A}},
{Ciphertext: []byte{0xB5, 0x89, 0x78, 0x8E, 0x5F, 0x5D, 0xBB, 0xF4, 0xF2, 0x5E, 0x18, 0x2A, 0xA8, 0x1A, 0x69, 0x70, 0xF9, 0xB9, 0x8A, 0xDF, 0x4D, 0x25, 0x6A, 0x78, 0xD8, 0xD4, 0x16, 0xD8, 0xDF, 0x39, 0x2B, 0x78, 0x51, 0x8C, 0xBA, 0x8D, 0x76, 0xBF, 0x53, 0xCB, 0xDB, 0x59, 0xEF, 0xDF, 0x9C, 0x1C, 0xDA, 0xC3, 0x3A, 0x89, 0xD8, 0x31, 0x7E, 0xD3, 0x79, 0x08, 0x66, 0xF5, 0x7F, 0x58, 0x2B, 0x7D, 0xA9, 0x83, 0xE3, 0xBC, 0x64, 0xC7, 0xD9, 0xCC, 0x19, 0xAD, 0xF2, 0x93, 0x3C, 0xB1, 0x61, 0xFC, 0x7B, 0x03, 0x30, 0x51, 0x41, 0x48, 0x51, 0x04, 0x45, 0x14, 0xD1, 0x14, 0x72, 0x0B}, IV: [16]byte{0xB5, 0x89, 0x78, 0x8E, 0x5F, 0x5D, 0xBB, 0xF4, 0xF2, 0x5E, 0x18, 0x2A, 0x68, 0x6E, 0x1A, 0x33}},
{Ciphertext: []byte{0x8B, 0x4E, 0xB4, 0x83, 0x28, 0x49, 0x0F, 0x3B, 0x26, 0xB3, 0x86, 0x31, 0x7F, 0x88, 0x6C, 0x57, 0x53, 0x5B, 0x22, 0xB7, 0x9D, 0xBB, 0x9B, 0x16, 0x9C, 0xAC, 0xAE, 0xC2, 0xAA, 0x7E, 0x59, 0xC5, 0x6C, 0x57, 0xB2, 0xA3, 0x0B, 0xDE, 0x15, 0x42, 0x3A, 0x8C, 0x04, 0x31, 0x4F, 0x44, 0x7F, 0x5E, 0x9B, 0x41, 0x8A, 0x00, 0x05, 0x44, 0x0A, 0x7C, 0x87, 0xD7, 0xF3, 0x56, 0x03, 0xFF, 0x71, 0x58, 0xC2, 0x7E, 0xB0, 0xC9, 0x57, 0x00, 0x78, 0x4A, 0xF2, 0x3C, 0xAB, 0xB0, 0x30, 0x65, 0x1C, 0xB7, 0xD5, 0xC6, 0xC3, 0x16, 0x01, 0x86, 0xC9, 0xD2, 0x8D, 0x04, 0xF0, 0xB9}, IV: [16]byte{0x8B, 0x4E, 0xB4, 0x83, 0x28, 0x49, 0x0F, 0x3B, 0x26, 0xB3, 0x86, 0x31, 0x83, 0xD0, 0x78, 0x5B}},
{Ciphertext: []byte{0x25, 0xB7, 0xFA, 0x94, 0x6A, 0x73, 0x1F, 0x9E, 0xE2, 0x13, 0x6E, 0x18, 0x07, 0x94, 0x74, 0x6F, 0xE6, 0xB9, 0x48, 0xCD, 0xFA, 0x6B, 0x7D, 0xB4, 0x84, 0x1B, 0xDC, 0x3C, 0x30, 0x4D, 0x99, 0xA4, 0xA7, 0x9A, 0x52, 0x43, 0x41, 0x7B, 0x9F, 0x86, 0x7A, 0x7C, 0x25, 0x55, 0x75, 0x38, 0x4B, 0x37, 0x92, 0x97, 0x96, 0xE5, 0x35, 0xDD, 0x44, 0xCF, 0x45, 0xF1, 0x9F, 0x92, 0x9B, 0xEB, 0x30, 0x9F, 0x7E, 0x64, 0x98, 0x5D, 0x78, 0x31, 0xFA, 0x73, 0x57, 0x1D, 0xF0, 0xAC, 0xBB, 0xA1, 0xC9, 0x57, 0x4B, 0x8D, 0x62, 0x80, 0xBE, 0x1C, 0xA9, 0xE1, 0x34, 0x56, 0xB3, 0xAA}, IV: [16]byte{0x25, 0xB7, 0xFA, 0x94, 0x6A, 0x73, 0x1F, 0x9E, 0xE2, 0x13, 0x6E, 0x18, 0x75, 0xB7, 0x15, 0x4C}},
{Ciphertext: []byte{0x10, 0xD7, 0x54, 0xA5, 0x47, 0xDC, 0x58, 0xA2, 0xCD, 0x56, 0x39, 0x85, 0x5E, 0x43, 0x93, 0x14, 0x64, 0xF7, 0x22, 0x60, 0x4A, 0x38, 0x35, 0xF8, 0x6C, 0xA5, 0xE1, 0x3C, 0xD0, 0x42, 0xD8, 0x47, 0xBF, 0xE2, 0x81, 0x35, 0x4D, 0x56, 0xCC, 0x94, 0xA2, 0xF1, 0xD7, 0x5F, 0xD7, 0x48, 0xA5, 0x76, 0x12, 0x9D, 0x42, 0xAC, 0xA6, 0xDC, 0x3D, 0x16, 0xEC, 0x84, 0xC6, 0x1C, 0x00, 0x3C, 0xDA, 0xE1, 0x41, 0xD2, 0x22, 0x30, 0xE1, 0x01, 0x08, 0x71, 0x9A, 0xDF, 0x5B, 0x18, 0xC1, 0x70, 0xA9, 0x05, 0xAF, 0xAA, 0x02, 0x96, 0xC7, 0x73, 0x1F, 0xD3, 0x26, 0x9D, 0xCC, 0xA1}, IV: [16]byte{0x10, 0xD7, 0x54, 0xA5, 0x47, 0xDC, 0x58, 0xA2, 0xCD, 0x56, 0x39, 0x85, 0x53, 0x5F, 0xA9, 0x9E}},
{Ciphertext: []byte{0x41, 0xE3, 0xEF, 0x63, 0x8F, 0xE4, 0xD6, 0x20, 0xE1, 0x94, 0x93, 0x56, 0x6D, 0xA1, 0x9F, 0x44, 0xC2, 0x6E, 0x64, 0xAE, 0xB6, 0x9C, 0x95, 0x8E, 0x0F, 0x08, 0xF6, 0xAF, 0xDF, 0x68, 0xFE, 0x20, 0xC3, 0x6D, 0xF5, 0x03, 0x07, 0xCD, 0xA2, 0x6B, 0xD1, 0x5D, 0xBA, 0x63, 0xAB, 0x29, 0x7C, 0x79, 0xD1, 0xC8, 0xEA, 0x29, 0xFA, 0x70, 0xC6, 0x67, 0xCC, 0x9E, 0x2A, 0xB8, 0x33, 0xE0, 0x80, 0x29, 0x5D, 0x0C, 0xBB, 0x08, 0x26, 0x46, 0x27, 0xD2, 0x9A, 0xE2, 0x9C, 0x50, 0xBE, 0x40, 0x08, 0xF6, 0x30, 0xCD, 0x1B, 0xD4, 0x13, 0x43, 0x3B, 0xB9, 0x59, 0x7F, 0xFE, 0x16}, IV: [16]byte{0x41, 0xE3, 0xEF, 0x63, 0x8F, 0xE4, 0xD6, 0x20, 0xE1, 0x94, 0x93, 0x56, 0x50, 0x1F, 0xDB, 0xD5}},
{Ciphertext: []byte{0xD0, 0x95, 0xC4, 0xA9, 0xBA, 0x36, 0x14, 0x34, 0x8B, 0xC8, 0xA6, 0xF9, 0x9F, 0xB7, 0x37, 0x3C, 0xFE, 0x13, 0x0C, 0xA0, 0xDD, 0xAF, 0x6E, 0x0C, 0x11, 0x67, 0xCB, 0xC1, 0xE8, 0xC9, 0xA2, 0xB1, 0x75, 0x50, 0x43, 0x0C, 0x61, 0x03, 0xCA, 0x26, 0x0A, 0xB5, 0x24, 0x81, 0x59, 0x43, 0xED, 0x8B, 0x62, 0x3E, 0x7E, 0xB9, 0x0E, 0x8C, 0xE5, 0xDD, 0x3B, 0x29, 0xF2, 0xB2, 0x27, 0xAE, 0xA0, 0xBA, 0x51, 0xBD, 0x23, 0xD0, 0xCB, 0xDD, 0x8A, 0xC9, 0x95, 0xCE, 0x94, 0x02, 0xC9, 0xD3, 0xF5, 0x8E, 0xAD, 0xE4, 0xCB, 0xCB, 0xF0, 0x79, 0xF0, 0x7E, 0xDB, 0x1E, 0xA1, 0x18}, IV: [16]byte{0xD0, 0x95, 0xC4, 0xA9, 0xBA, 0x36, 0x14, 0x34, 0x8B, 0xC8, 0xA6, 0xF9, 0x2C, 0xF0, 0x54, 0x17}},
{Ciphertext: []byte{0xD6, 0x45, 0x9B, 0xDD, 0xA1, 0xFF, 0xE1, 0x64, 0x58, 0x5B, 0x4D, 0x4B, 0x78, 0xAF, 0x8A, 0x00, 0xA2, 0xB2, 0x0C, 0x80, 0x68, 0x03, 0xDC, 0x8B, 0xFC, 0x3E, 0xBD, 0x24, 0x22, 0xCC, 0x6D, 0x50, 0x4A, 0xDD, 0x8A, 0xE4, 0x82, 0xD4, 0x4D, 0x15, 0xB7, 0x7D, 0x36, 0x7E, 0x7A, 0xA5, 0x80, 0x01, 0x82, 0xD0, 0x7B, 0x24, 0x5D, 0x22, 0xB8, 0x44, 0x8E, 0x12, 0x39, 0xB7, 0x6A, 0x3F, 0xC0, 0xA2, 0xA0, 0x7C, 0x54, 0x3F, 0xE5, 0x93, 0x91, 0x3D, 0xF7, 0xC3, 0x7F, 0xE7, 0x2E, 0x9D, 0x24, 0x15, 0x76, 0x4E, 0x77, 0x8D, 0xA8, 0x08, 0xAD, 0x3F, 0x6A, 0x14, 0xCA, 0xBC}, IV: [16]byte{0xD6, 0x45, 0x9B, 0xDD, 0xA1, 0xFF, 0xE1, 0x64, 0x58, 0x5B, 0x4D, 0x4B, 0xF9, 0xDC, 0x35, 0xB6}},
{Ciphertext: []byte{0xA1, 0x89, 0xDB, 0x84, 0xE2, 0x8B, 0x10, 0xC2, 0xB2, 0xB5, 0x0A, 0x3C, 0xE4, 0x05, 0x6A, 0x6F, 0xA9, 0x8A, 0xDC, 0xE4, 0xB8, 0x23, 0x32, 0xBA, 0x80, 0x96, 0x99, 0x93, 0x0C, 0xF6, 0x71, 0x93, 0x55, 0x84, 0xE0, 0x48, 0xEC, 0xEE, 0xEF, 0xD6, 0x6A, 0xB1, 0x84, 0x15, 0x0F, 0x16, 0x8A, 0x37, 0x16, 0x22, 0x7B, 0x77, 0x92, 0x2B, 0xB4, 0xB1, 0x69, 0xCE, 0x13, 0x23, 0x32, 0x2F, 0x2B, 0xC3, 0x85, 0x60, 0x2E, 0xA2, 0x31, 0x00, 0x96, 0x75, 0xFC, 0x29, 0x74, 0xBF, 0xC3, 0xE4, 0x2E, 0x47, 0x73, 0xE7, 0x91, 0x9E, 0x94, 0x78, 0x3C, 0xC4, 0xA0, 0x9C, 0x1D, 0xE8}, IV: [16]byte{0xA1, 0x89, 0xDB, 0x84, 0xE2, 0x8B, 0x10, 0xC2, 0xB2, 0xB5, 0x0A, 0x3C, 0xDC, 0x55, 0xDE, 0xAB}},
{Ciphertext: []byte{0xF2, 0x0F, 0x1E, 0x76, 0x95, 0xED, 0x1A, 0x03, 0x18, 0x5C, 0x51, 0x73, 0xE1, 0x8E, 0xE7, 0xEE, 0x34, 0x74, 0x6B, 0xCB, 0x6A, 0x11, 0x40, 0x30, 0xE7, 0x3A, 0x0C, 0xCA, 0xAE, 0x9C, 0xF0, 0x9E, 0x78, 0xD0, 0xE7, 0xDC, 0x3D, 0x27, 0x6A, 0x7A, 0x78, 0x77, 0xD4, 0xAA, 0x4F, 0xC9, 0xAC, 0x27, 0x68, 0x8C, 0x48, 0x1C, 0x52, 0xD1, 0x22, 0xC6, 0x9A, 0x66, 0x01, 0x3F, 0x86, 0xC7, 0xF5, 0xC9, 0x13, 0xDD, 0x70, 0xB3, 0xF9, 0x62, 0xF6, 0x7E, 0x3D, 0xB5, 0x60, 0x91, 0x35, 0x60, 0x4E, 0x99, 0x3B, 0xAB, 0x5B, 0x4F, 0xBD, 0x54, 0x05, 0xA7, 0x9C, 0xF8, 0x69, 0xDD}, IV: [16]byte{0xF2, 0x0F, 0x1E, 0x76, 0x95, 0xED, 0x1A, 0x03, 0x18, 0x5C, 0x51, 0x73, 0xBE, 0x4C, 0x12, 0x5F}},
{Ciphertext: []byte{0xCB, 0x41, 0x34, 0x92, 0xAF, 0xF4, 0xF1, 0xD0, 0x80, 0x48, 0x53, 0x79, 0x7C, 0xE0, 0x28, 0xD9, 0x71, 0xB1, 0xB4, 0xA4, 0xB1, 0x97, 0x5B, 0xE2, 0x29, 0x73, 0xDF, 0x0B, 0x3D, 0x79, 0x82, 0xA3, 0x53, 0xC2, 0x73, 0x4B, 0x09, 0x3F, 0x4B, 0xA1, 0x9B, 0xB2, 0xB9, 0xA9, 0x59, 0xEF, 0xF8, 0x2D, 0xCB, 0x71, 0xE9, 0x94, 0x6A, 0x0B, 0xF8, 0xE5, 0x5D, 0x7A, 0x55, 0xE4, 0x7E, 0x55, 0x4B, 0x04, 0x97, 0x3D, 0xBF, 0x24, 0x99, 0xE7, 0x58, 0x2D, 0xFC, 0x38, 0x57, 0xBB, 0x34, 0x2B, 0x68, 0xA5, 0x88, 0x7C, 0x59, 0xD8, 0x0A, 0x1C, 0x41, 0x3E, 0xBB, 0x1E, 0x07, 0x12}, IV: [16]byte{0xCB, 0x41, 0x34, 0x92, 0xAF, 0xF4, 0xF1, 0xD0, 0x80, 0x48, 0x53, 0x79, 0x59, 0x6B, 0xCD, 0x66}},
{Ciphertext: []byte{0x3E, 0x17, 0x48, 0x61, 0x49, 0x4E, 0xBA, 0xF6, 0x00, 0xB9, 0x7D, 0x78, 0x55, 0xC7, 0xA1, 0x0D, 0xAD, 0xB4, 0x10, 0x16, 0x25, 0x24, 0xC3, 0xE5, 0x95, 0xF8, 0x42, 0xF5, 0xC4, 0xF9, 0x01, 0x4E, 0x9E, 0x1A, 0x05, 0x26, 0x2B, 0xF9, 0x7B, 0x83, 0x6B, 0xBC, 0xEB, 0xFB, 0x7B, 0x2C, 0xDD, 0x59, 0x9D, 0x94, 0x07, 0xA3, 0x8B, 0x44, 0x2B, 0x55, 0x55, 0x46, 0xA2, 0x14, 0xA8, 0x9A, 0xE7, 0x60, 0x7F, 0xA9, 0xE8, 0xD4, 0xB5, 0xB1, 0x7A, 0x4A, 0x8F, 0xCF, 0xB0, 0xB2, 0x99, 0xC6, 0x57, 0x1E, 0xF2, 0x3A, 0x00, 0x09, 0xD3, 0xD4, 0x69, 0xD7, 0x5D, 0x3D, 0x69, 0x87}, IV: [16]byte{0x3E, 0x17, 0x48, 0x61, 0x49, 0x4E, 0xBA, 0xF6, 0x00, 0xB9, 0x7D, 0x78, 0xB6, 0x9D, 0x3E, 0x6C}},
{Ciphertext: []byte{0x8E, 0xCC, 0x97, 0x83, 0x7F, 0xDC, 0x5C, 0x7E, 0x8C, 0xEB, 0x7A, 0x9D, 0xC9, 0x2F, 0x76, 0xE5, 0x04, 0x06, 0xD3, 0xEE, 0xB1, 0xCB, 0x65, 0xC2, 0x8D, 0x90, 0x28, 0xE9, 0x6A, 0x9F, 0xD2, 0xEB, 0x47, 0x04, 0xA2, 0xE4, 0x99, 0x19, 0x2F, 0xAC, 0xF3, 0x8A, 0x3F, 0xFA, 0x89, 0x99, 0xFF, 0xE4, 0xE1, 0xC4, 0xFE, 0xB8, 0x0C, 0x25, 0xC3, 0xEA, 0x64, 0x05, 0x81, 0x7F, 0x72, 0x8E, 0x33, 0x74, 0xCF, 0xA6, 0x7B, 0x70, 0x48, 0x59, 0x92, 0x3B, 0x3C, 0x5D, 0xC8, 0x62, 0x29, 0x60, 0x2C, 0x18, 0x05, 0x80, 0x87, 0xD1, 0xF7, 0xB5, 0x98, 0x99, 0xC1, 0x4A, 0xF1, 0xDF}, IV: [16]byte{0x8E, 0xCC, 0x97, 0x83, 0x7F, 0xDC, 0x5C, 0x7E, 0x8C, 0xEB, 0x7A, 0x9D, 0xA0, 0xD3, 0x7E, 0xE3}},
{Ciphertext: []byte{0x56, 0x60, 0xCA, 0xCB, 0xB4, 0xA4, 0x62, 0xE0, 0x38, 0x67, 0xD8, 0xE3, 0xC7, 0x8F, 0x2B, 0x8E, 0x8F, 0xF9, 0x2F, 0x00, 0xD5, 0xDC, 0x0A, 0xAA, 0x1F, 0xBC, 0x1C, 0x62, 0x90, 0x3B, 0x38, 0xD7, 0x82, 0xB6, 0xDF, 0x7B, 0xD3, 0xEF, 0x4D, 0x39, 0x84, 0xE6, 0x2F, 0x57, 0x4B, 0x21, 0xFC, 0x1F, 0x46, 0xBF, 0x4A, 0xAF, 0x0C, 0x34, 0x01, 0x0C, 0xFB, 0xC3, 0x49, 0xC8, 0xEA, 0x8B, 0x62, 0xF2, 0x0C, 0x47, 0x6F, 0x19, 0x0F, 0x9E, 0x49, 0x97, 0x93, 0xE6, 0x35, 0xC0, 0xD6, 0x3C, 0xA4, 0x7D, 0x9C, 0x01, 0xB4, 0x03, 0xC8, 0x21, 0x2B, 0xE2, 0x1A, 0x4C, 0xD1, 0x24}, IV: [16]byte{0x56, 0x60, 0xCA, 0xCB, 0xB4, 0xA4, 0x62, 0xE0, 0x38, 0x67, 0xD8, 0xE3, 0x5F, 0xD3, 0xA1, 0x49}},
{Ciphertext: []byte{0x49, 0xDC, 0x73, 0x9A, 0x26, 0x63, 0xD2, 0xBB, 0xC3, 0x6E, 0x6D, 0xCB, 0xEE, 0x48, 0xA6, 0x54, 0xB4, 0xF2, 0x82, 0x99, 0x79, 0x1E, 0xDA, 0x9E, 0x83, 0x19, 0xFA, 0x8D, 0x3B, 0x95, 0xC3, 0xDA, 0x4B, 0xA0, 0x71, 0x30, 0xC8, 0xA7, 0x00, 0x56, 0x71, 0xF0, 0x32, 0x32, 0x6E, 0x41, 0x01, 0xF6, 0xF8, 0xF0, 0xB3, 0xF4, 0x00, 0x62, 0x87, 0xAD, 0xCD, 0x75, 0x64, 0x04, 0x9A, 0xB7, 0x3F, 0x02, 0x2E, 0x4C, 0x14, 0x24, 0x53, 0x59, 0x8B, 0xBA, 0xA7, 0x4D, 0x44, 0xFE, 0xB4, 0x34, 0x99, 0x19, 0x13, 0x5D, 0xD0, 0xD7, 0x0B, 0xA9, 0xF7, 0xD0, 0x65, 0xD5, 0xC6, 0x99}, IV: [16]byte{0x49, 0xDC, 0x73, 0x9A, 0x26, 0x63, 0xD2, 0xBB, 0xC3, 0x6E, 0x6D, 0xCB, 0x99, 0x39, 0x48, 0x8D}},
{Ciphertext: []byte{0xFA, 0x46, 0xAF, 0x91, 0xDD, 0xF7, 0xCD, 0x4D, 0x25, 0x4A, 0xDA, 0x4C, 0xE2, 0x88, 0x5C, 0x04, 0xD2, 0xDC, 0x65, 0xE0, 0x7A, 0x19, 0x8A, 0x04, 0x7E, 0x42, 0xAC, 0xA6, 0x1E, 0x86, 0xE6, 0xA4, 0x51, 0xE2, 0x2A, 0x81, 0x0D, 0x36, 0xFA, 0x67, 0x74, 0x59, 0xFD, 0x29, 0xC3, 0x4A, 0x63, 0xF2, 0x5D, 0x2F, 0x48, 0xE6, 0x3A, 0x42, 0x92, 0xFE, 0x2A, 0xCD, 0xE1, 0x22, 0x2E, 0x80, 0x7A, 0x9B, 0x82, 0x83, 0x1A, 0x33, 0x19, 0x78, 0x13, 0x0E, 0xC2, 0x0A, 0x1B, 0x53, 0xF8, 0xCA, 0x64, 0x24, 0x37, 0xD5, 0x00, 0x16, 0x03, 0x69, 0x90, 0xFA, 0x92, 0x7B, 0x92, 0x55}, IV: [16]byte{0xFA, 0x46, 0xAF, 0x91, 0xDD, 0xF7, 0xCD, 0x4D, 0x25, 0x4A, 0xDA, 0x4C, 0x2A, 0x28, 0x86, 0xD4}},
{Ciphertext: []byte{0xD6, 0x41, 0xFB, 0xEB, 0xC1, 0xCC, 0x4D, 0xA9, 0xC5, 0x02, 0xCF, 0xD6, 0x0E, 0x24, 0x8D, 0xA8, 0x38, 0xA3, 0xF4, 0x70, 0xBB, 0x7D, 0xF3, 0xC2, 0xBA, 0xEA, 0xFA, 0x7E, 0x47, 0xB4, 0x9B, 0x55, 0xDB, 0x00, 0xB2, 0xBA, 0x81, 0xAF, 0x3C, 0xB0, 0xFE, 0x5B, 0x5B, 0xAB, 0xFF, 0x54, 0x43, 0x47, 0xB1, 0x36, 0x8E, 0xF2, 0xCC, 0x22, 0x5B, 0x25, 0x84, 0x74, 0xED, 0xC7, 0xCB, 0xC0, 0x02, 0x0B, 0xE9, 0x53, 0x63, 0xC8, 0x0A, 0xE9, 0x13, 0x1F, 0x6F, 0x90, 0x79, 0x7C, 0xCC, 0x89, 0xDE, 0x9E, 0xC6, 0xFB, 0xFA, 0x3B, 0x3A, 0x59, 0x6F, 0xC8, 0x9C, 0x9C, 0x6F, 0x77}, IV: [16]byte{0xD6, 0x41, 0xFB, 0xEB, 0xC1, 0xCC, 0x4D, 0xA9, 0xC5, 0x02, 0xCF, 0xD6, 0x0C, 0x65, 0xE0, 0x32}},
{Ciphertext: []byte{0x3B, 0x4C, 0x29, 0xDE, 0x96, 0x06, 0xE2, 0xA0, 0xFD, 0x10, 0x94, 0x59, 0x3F, 0x1A, 0xC9, 0xF9, 0xF3, 0x86, 0xD9, 0xA7, 0xDB, 0xB1, 0x2B, 0x0D, 0x2E, 0x65, 0x53, 0x45, 0xCB, 0xA9, 0x89, 0x2E, 0x10, 0x1C, 0x5C, 0x6A, 0x50, 0x47, 0xC4, 0xEB, 0x8C, 0xE7, 0x89, 0x62, 0xEE, 0x5B, 0xA1, 0x7E, 0x52, 0xC5, 0xF6, 0x58, 0xA1, 0x70, 0x60, 0xAA, 0x8C, 0xAA, 0xBF, 0xA0, 0x06, 0xC0, 0xA7, 0x5B, 0x0E, 0xE8, 0x42, 0xA6, 0x40, 0xC8, 0xDD, 0x52, 0x39, 0x73, 0x9D, 0x97, 0xE0, 0x36, 0x03, 0x65, 0x4B, 0x26, 0x9A, 0x7A, 0x10, 0x99, 0x35, 0x71, 0xFF, 0xF9, 0xE1, 0x06}, IV: [16]byte{0x3B, 0x4C, 0x29, 0xDE, 0x96, 0x06, 0xE2, 0xA0, 0xFD, 0x10, 0x94, 0x59, 0x26, 0x50, 0x2C, 0x68}},
{Ciphertext: []byte{0x5B, 0xC1, 0xE8, 0x85, 0xEC, 0x06, 0xFA, 0x30, 0x76, 0xFC, 0xAD, 0xDE, 0x3D, 0x59, 0x79, 0x0B, 0x74, 0x1F, 0xAB, 0xCA, 0xAA, 0xA2, 0x38, 0x8A, 0xC5, 0x89, 0x36, 0xBC, 0x69, 0x6D, 0x86, 0xF2, 0x85, 0xB0, 0x7C, 0x65, 0x95, 0xF4, 0xE3, 0x72, 0x36, 0xD3, 0xC7, 0xC0, 0x7A, 0xF1, 0x1D, 0xA8, 0xDA, 0x80, 0xD7, 0xC9, 0x1B, 0xA5, 0x0B, 0x6C, 0xFB, 0xC9, 0xCF, 0x46, 0x19, 0xB9, 0x40, 0xB0, 0x20, 0x26, 0x74, 0xAE, 0x89, 0x52, 0x92, 0x42, 0x3F, 0x2B, 0x7C, 0xAF, 0x9C, 0x7F, 0x6F, 0x65, 0x1B, 0x28, 0xFB, 0x8D, 0x20, 0xB0, 0x47, 0xD5, 0xB4, 0xB4, 0x4B, 0x65}, IV: [16]byte{0x5B, 0xC1, 0xE8, 0x85, 0xEC, 0x06, 0xFA, 0x30, 0x76, 0xFC, 0xAD, 0xDE, 0x8D, 0xAA, 0x77, 0x1E}},
{Ciphertext: []byte{0x31, 0x75, 0x43, 0xA2, 0x25, 0x22, 0xFC, 0x95, 0xDC, 0xBF, 0x29, 0xFA, 0x05, 0x45, 0xB4, 0x0A, 0xD5, 0xE9, 0xAD, 0xA4, 0x0F, 0x64, 0x08, 0xA9, 0x91, 0x8D, 0x72, 0x01, 0x8B, 0xD6, 0x45, 0x20, 0x4A, 0x08, 0x75, 0x53, 0x0C, 0xBD, 0xED, 0x88, 0x2A, 0x16, 0x18, 0x8F, 0x90, 0xD9, 0x07, 0xDE, 0xDD, 0xFF, 0x34, 0x32, 0x66, 0x62, 0xDE, 0x04, 0x61, 0xF9, 0x42, 0xCE, 0xC1, 0x61, 0xC5, 0x4D, 0x31, 0x53, 0x40, 0x79, 0x4A, 0xC7, 0xF7, 0x17, 0x28, 0x7C, 0xD9, 0x10, 0x7E, 0xCC, 0x52, 0xDC, 0x52, 0xD1, 0x7E, 0x39, 0xE0, 0x01, 0x65, 0x7A, 0xB8, 0xEA, 0xA3, 0x4F}, IV: [16]byte{0x31, 0x75, 0x43, 0xA2, 0x25, 0x22, 0xFC, 0x95, 0xDC, 0xBF, 0x29, 0xFA, 0x20, 0xFD, 0x70, 0x86}},
{Ciphertext: []byte{0x5B, 0xD6, 0x4E, 0xC9, 0x35, 0x81, 0x52, 0x5D, 0x3B, 0x1B, 0xCF, 0xBD, 0xB4, 0xF4, 0x36, 0x26, 0xFB, 0x60, 0x51, 0x9D, 0x71, 0xBB, 0x1F, 0x0E, 0x57, 0xE5, 0xED, 0x5A, 0xC7, 0x64, 0xFE, 0x3E, 0x9A, 0x1D, 0xAB, 0x61, 0x40, 0x44, 0x6F, 0xE1, 0xC2, 0xB9, 0xAB, 0xB9, 0xD8, 0x4A, 0xB4, 0xF7, 0x45, 0xC4, 0xEE, 0x73, 0x6B, 0x09, 0x17, 0x16, 0x21, 0x99, 0x14, 0xEE, 0x36, 0x96, 0x89, 0xB3, 0x3D, 0xD3, 0x5C, 0x4F, 0x86, 0xBA, 0x6F, 0xEB, 0x62, 0x40, 0x86, 0x8E, 0x5C, 0xF6, 0x07, 0x43, 0x3C, 0x02, 0x77, 0xCB, 0xD9, 0x5B, 0xB8, 0x34, 0x1C, 0x21, 0x60, 0xA7}, IV: [16]byte{0x5B, 0xD6, 0x4E, 0xC9, 0x35, 0x81, 0x52, 0x5D, 0x3B, 0x1B, 0xCF, 0xBD, 0x01, 0x03, 0xDB, 0xB8}},
{Ciphertext: []byte{0xA9, 0x7E, 0xDF, 0x65, 0xF7, 0xCD, 0xB4, 0xD1, 0x54, 0xDC, 0x11, 0xCF, 0xF8, 0xD1, 0x8D, 0x89, 0xB5, 0xA2, 0x8C, 0xB0, 0xCD, 0x8A, 0x80, 0x75, 0x65, 0xF3, 0x7D, 0x9B, 0x68, 0x79, 0x07, 0x3E, 0x47, 0xA2, 0x89, 0x8C, 0x57, 0x2E, 0xFB, 0xBC, 0x7B, 0x49, 0x81, 0x33, 0x2A, 0xBB, 0xB3, 0x69, 0x7B, 0xEB, 0x15, 0xDE, 0xC6, 0x65, 0x57, 0x6D, 0xD5, 0x35, 0x57, 0x9F, 0x4C, 0x77, 0x1A, 0x83, 0xE8, 0x04, 0x3A, 0x65, 0x53, 0x61, 0x51, 0xE4, 0x2E, 0x48, 0x0F, 0xD0, 0xD1, 0x7F, 0x18, 0x7A, 0x69, 0xC1, 0x14, 0x9F, 0x79, 0x0A, 0x8B, 0x6D, 0xAF, 0x0E, 0x40, 0xE7}, IV: [16]byte{0xA9, 0x7E, 0xDF, 0x65, 0xF7, 0xCD, 0xB4, 0xD1, 0x54, 0xDC, 0x11, 0xCF, 0x6A, 0x6A, 0xA6, 0x35}},
{Ciphertext: []byte{0x2B, 0x52, 0x89, 0x10, 0x1F, 0x72, 0xCC, 0xDF, 0xD3, 0x8E, 0x1B, 0xC0, 0x16, 0x36, 0x97, 0x2B, 0x00, 0x17, 0x7F, 0x1D, 0x3E, 0x4C, 0x20, 0x5F, 0x48, 0x08, 0x41, 0xBC, 0x32, 0xE3, 0xFA, 0x10, 0x03, 0x0B, 0x6E, 0x3E, 0x67, 0x36, 0x90, 0x31, 0xFE, 0x55, 0xFD, 0x5E, 0x7A, 0xDD, 0xF8, 0x3B, 0xA8, 0x0B, 0x98, 0xDB, 0x22, 0x7D, 0xE5, 0xF9, 0xE8, 0xEF, 0x17, 0x68, 0x2A, 0x17, 0xA8, 0x2B, 0x93, 0x62, 0x28, 0x76, 0xC7, 0x48, 0xC2, 0xBD, 0xEF, 0xE5, 0x58, 0x0C, 0x13, 0x4B, 0x68, 0x93, 0x7F, 0x51, 0xD3, 0x49, 0xE4, 0xBA, 0xE8, 0xDB, 0xCA, 0x61, 0x04, 0xA2}, IV: [16]byte{0x2B, 0x52, 0x89, 0x10, 0x1F, 0x72, 0xCC, 0xDF, 0xD3, 0x8E, 0x1B, 0xC0, 0x22, 0x3D, 0x46, 0x43}},
{Ciphertext: []byte{0xE1, 0xAB, 0xA0, 0x53, 0xEB, 0x0E, 0xB0, 0x77, 0x9D, 0xFA, 0xB0, 0x6A, 0x97, 0xAF, 0x78, 0x2F, 0x40, 0x6A, 0x52, 0xC4, 0xBF, 0x89, 0xBF, 0x96, 0x7D, 0xE5, 0x5F, 0x73, 0xA7, 0x94, 0xA8, 0xA0, 0xAA, 0x47, 0xBD, 0xE4, 0xAF, 0xEE, 0x9B, 0x07, 0xAB, 0x31, 0xD6, 0x72, 0xE2, 0x75, 0x8C, 0x3C, 0x34, 0x4E, 0xC8, 0xA8, 0x05, 0x6F, 0xCB, 0x80, 0xD8, 0x2D, 0x48, 0xD2, 0xA0, 0xB5, 0x5C, 0x87, 0x4A, 0x5A, 0x72, 0x7D, 0xEB, 0x4A, 0x26, 0x68, 0x20, 0x72, 0x1C, 0x64, 0x9C, 0xDB, 0x28, 0xF0, 0x8C, 0x09, 0xF6, 0x74, 0x71, 0xC9, 0x72, 0xE3, 0x2E, 0x51, 0x49, 0xDC}, IV: [16]byte{0xE1, 0xAB, 0xA0, 0x53, 0xEB, 0x0E, 0xB0, 0x77, 0x9D, 0xFA, 0xB0, 0x6A, 0x59, 0x10, 0xB0, 0xD0}},
{Ciphertext: []byte{0xB4, 0x98, 0x9A, 0x4D, 0x06, 0xF6, 0x80, 0x02, 0x50, 0xCF, 0x7B, 0x13, 0xE4, 0x82, 0x0A, 0xC7, 0x59, 0xD7, 0x3E, 0x96, 0xBB, 0x57, 0x55, 0x1E, 0xFD, 0xE7, 0x9E, 0x28, 0x2D, 0xEE, 0x40, 0x03, 0x42, 0x9E, 0x78, 0x06, 0x89, 0x48, 0x78, 0x98, 0xA2, 0x12, 0x3E, 0x16, 0x31, 0x0C, 0x2B, 0x09, 0x44, 0xA2, 0x69, 0x31, 0xBD, 0x8A, 0x70, 0x7A, 0x1F, 0x9D, 0x92, 0xE7, 0x3B, 0xE7, 0xDC, 0xCF, 0x95, 0x9B, 0x58, 0xB3, 0xEF, 0xD9, 0xB5, 0x0F, 0x3E, 0xA1, 0xDF, 0x05, 0x9C, 0x3F, 0x91, 0x24, 0x1F, 0x24, 0x7D, 0x54, 0x50, 0x69, 0xAC, 0x0A, 0x10, 0x01, 0x3D, 0xBF}, IV: [16]byte{0xB4, 0x98, 0x9A, 0x4D, 0x06, 0xF6, 0x80, 0x02, 0x50, 0xCF, 0x7B, 0x13, 0xEE, 0x94, 0x07, 0xC6}},
{Ciphertext: []byte{0xCF, 0xE1, 0xD2, 0x93, 0x18, 0xD2, 0x0F, 0x36, 0x27, 0x87, 0x27, 0x57, 0x4D, 0x82, 0x33, 0xDE, 0xCC, 0xE1, 0x88, 0x09, 0xE0, 0x4F, 0x6F, 0xA3, 0xC0, 0x2E, 0x82, 0x84, 0xCE, 0x33, 0xF1, 0x64, 0xBA, 0x46, 0xA1, 0xA2, 0x99, 0x25, 0x9B, 0x33, 0xFF, 0x80, 0x6E, 0x42, 0x36, 0x18, 0x34, 0xCA, 0x09, 0x96, 0xC4, 0xFC, 0x86, 0x52, 0x0D, 0xC2, 0x8D, 0xFF, 0x74, 0x11, 0x15, 0xEC, 0xED, 0xD3, 0x71, 0x66, 0x50, 0x82, 0xD9, 0xF7, 0x96, 0x80, 0x07, 0x06, 0xDD, 0x57, 0x9C, 0xEB, 0x56, 0x8D, 0x4C, 0xAA, 0x8A, 0xF2, 0x06, 0x24, 0x8C, 0x3A, 0x43, 0xBD, 0xC6, 0x49}, IV: [16]byte{0xCF, 0xE1, 0xD2, 0x93, 0x18, 0xD2, 0x0F, 0x36, 0x27, 0x87, 0x27, 0x57, 0x60, 0x1A, 0xAA, 0x6C}},
{Ciphertext: []byte{0x38, 0x69, 0x2E, 0xDD, 0x18, 0x24, 0x28, 0xE4, 0x88, 0x33, 0xA3, 0xFC, 0x39, 0x3D, 0x48, 0x07, 0xF7, 0x03, 0xBC, 0x68, 0x53, 0x2A, 0x57, 0x92, 0x01, 0x57, 0x04, 0x4D, 0xC8, 0xE6, 0xD4, 0x21, 0xA9, 0xDB, 0xA3, 0xFF, 0xCB, 0x56, 0x9A, 0x16, 0x58, 0x48, 0x2D, 0xF5, 0x25, 0x86, 0x21, 0x2E, 0x95, 0x85, 0x16, 0xA6, 0x24, 0x6D, 0x23, 0x98, 0xF3, 0xE0, 0x96, 0x1A, 0x27, 0x69, 0x50, 0xDD, 0xA8, 0x04, 0x37, 0x0B, 0xAE, 0xC7, 0xEB, 0x80, 0xA1, 0xBD, 0x0B, 0x55, 0x72, 0x3E, 0x62, 0x45, 0x1F, 0xF9, 0xBF, 0x1B, 0xBF, 0xE5, 0xA1, 0x4C, 0x5B, 0x7A, 0x23, 0x6E}, IV: [16]byte{0x38, 0x69, 0x2E, 0xDD, 0x18, 0x24, 0x28, 0xE4, 0x88, 0x33, 0xA3, 0xFC, 0x27, 0x5F, 0x02, 0x1C}},
{Ciphertext: []byte{0xC4, 0x12, 0xF5, 0x8D, 0xC7, 0x0A, 0x06, 0x5E, 0xA7, 0xA3, 0x2B, 0xBF, 0xA4, 0x39, 0xA9, 0x9F, 0xC9, 0x58, 0xC8, 0x0D, 0x62, 0x8B, 0x0A, 0x0B, 0x33, 0x86, 0x7D, 0xB0, 0x01, 0x1B, 0x5B, 0x06, 0x40, 0x86, 0x97, 0x6D, 0x25, 0x39, 0xC7, 0x6A, 0xCB, 0x63, 0xD3, 0x83, 0x82, 0xFC, 0x24, 0x47, 0xE2, 0xDD, 0x8B, 0x5E, 0x19, 0x98, 0x2A, 0xC3, 0xA0, 0xD8, 0xA5, 0x74, 0xAA, 0x47, 0x94, 0x61, 0x2B, 0xD8, 0x49, 0x89, 0x38, 0x74, 0x65, 0x7F, 0x54, 0xD5, 0xDF, 0xD6, 0x94, 0xB4, 0x58, 0xAE, 0xCE, 0xBD, 0x45, 0xF7, 0x4C, 0x14, 0xF3, 0xF8, 0xDB, 0xBF, 0x7F, 0x35}, IV: [16]byte{0xC4, 0x12, 0xF5, 0x8D, 0xC7, 0x0A, 0x06, 0x5E, 0xA7, 0xA3, 0x2B, 0xBF, 0x40, 0x65, 0x3E, 0x8B}},
{Ciphertext: []byte{0x1A, 0xD9, 0xDD, 0x57, 0xF2, 0x7B, 0xD1, 0x59, 0xEB, 0xEC, 0x91, 0xDF, 0x96, 0xEF, 0xC5, 0x48, 0x02, 0xE6, 0x77, 0xD8, 0x5D, 0xF2, 0xDE, 0xD9, 0x0E, 0x4A, 0xD4, 0x7C, 0xF1, 0x5C, 0x68, 0xBC, 0xDD, 0x8D, 0x9C, 0xEC, 0x4F, 0x2C, 0x45, 0x70, 0x51, 0xAA, 0xEB, 0xA8, 0x3F, 0x35, 0x3C, 0x66, 0x4E, 0x14, 0x43, 0x63, 0x88, 0x04, 0x73, 0xC2, 0x69, 0x76, 0x41, 0x4F, 0x3C, 0x50, 0x1F, 0x3A, 0x5A, 0x8B, 0xFE, 0xE0, 0x85, 0x63, 0xA0, 0x45, 0x64, 0x28, 0xB2, 0x4D, 0x8E, 0x65, 0x90, 0xEF, 0x03, 0xAE, 0xA3, 0xB1, 0x52, 0xA5, 0xD5, 0xC0, 0xBC, 0xE3, 0x63, 0xCB}, IV: [16]byte{0x1A, 0xD9, 0xDD, 0x57, 0xF2, 0x7B, 0xD1, 0x59, 0xEB, 0xEC, 0x91, 0xDF, 0xFC, 0x18, 0x6B, 0x2A}},
{Ciphertext: []byte{0x8B, 0x4C, 0xC7, 0x09, 0x0A, 0xE1, 0xC8, 0x47, 0x4B, 0xD0, 0xFA, 0x71, 0xCE, 0xEB, 0x19, 0x70, 0xC7, 0xAA, 0xFA, 0xAE, 0xD1, 0x8B, 0x76, 0xC5, 0x54, 0x00, 0xCE, 0x2A, 0xD5, 0x2E, 0x97, 0x94, 0x47, 0x8F, 0xB1, 0x1E, 0x87, 0x59, 0x5A, 0xD3, 0xA8, 0xE0, 0xD9, 0xBC, 0xB1, 0xD9, 0x12, 0x34, 0x87, 0xBA, 0x10, 0x1A, 0xB8, 0x37, 0xA7, 0x0E, 0xCB, 0x28, 0x5C, 0xF6, 0xBC, 0xF1, 0x85, 0xC2, 0xC8, 0x89, 0x8D, 0x85, 0xF8, 0x58, 0x92, 0x81, 0x52, 0xE6, 0xC3, 0x40, 0xA1, 0xD3, 0xAF, 0x89, 0xB7, 0x90, 0xF6, 0xB7, 0x58, 0x25, 0x3B, 0x7A, 0xE9, 0x6E, 0x45, 0x16}, IV: [16]byte{0x8B, 0x4C, 0xC7, 0x09, 0x0A, 0xE1, 0xC8, 0x47, 0x4B, 0xD0, 0xFA, 0x71, 0x3C, 0xEE, 0xA4, 0xC6}},
{Ciphertext: []byte{0x45, 0x1C, 0xF2, 0x62, 0x51, 0x45, 0x07, 0x74, 0x1F, 0xCF, 0xC6, 0xB1, 0x05, 0xDF, 0x88, 0xCD, 0x5C, 0x3F, 0x14, 0x9D, 0x90, 0x62, 0x80, 0xDD, 0x08, 0xC9, 0xB1, 0x20, 0x21, 0xAD, 0x4D, 0x9D, 0xA6, 0x8F, 0xCC, 0xE9, 0x83, 0xD6, 0x17, 0x82, 0xE5, 0x28, 0x0B, 0x73, 0x9F, 0x68, 0xD6, 0xAE, 0x9F, 0x32, 0x62, 0x80, 0x91, 0xE6, 0x09, 0xE5, 0x14, 0x0E, 0x87, 0x98, 0x4B, 0x9B, 0x67, 0x4F, 0x6B, 0x0D, 0x67, 0xED, 0x4A, 0x6A, 0xFD, 0x09, 0x12, 0xA3, 0xC7, 0x07, 0xC7, 0xFE, 0x8C, 0x07, 0xAF, 0x77, 0x42, 0x14, 0xB0, 0x44, 0xEC, 0xB0, 0xB5, 0x0C, 0x6D, 0x09}, IV: [16]byte{0x45, 0x1C, 0xF2, 0x62, 0x51, 0x45, 0x07, 0x74, 0x1F, 0xCF, 0xC6, 0xB1, 0xD2, 0xD9, 0x3B, 0xA0}},
{Ciphertext: []byte{0x9E, 0xD7, 0x66, 0xF7, 0xEF, 0xFE, 0xDE, 0x19, 0x5D, 0x19, 0x16, 0x02, 0x37, 0xF6, 0xD1, 0x47, 0xB9, 0xF6, 0x9F, 0x4B, 0xC6, 0xFD, 0x45, 0xD3, 0xE4, 0x6E, 0xD4, 0xC7, 0x16, 0x76, 0x4D, 0x5E, 0xEA, 0x57, 0x85, 0x36, 0xF1, 0x95, 0x10, 0x5A, 0x03, 0xC4, 0x8E, 0x30, 0xF6, 0x4B, 0xAA, 0x0A, 0xA0, 0x38, 0x29, 0x89, 0x39, 0xDA, 0x8A, 0x9D, 0x1A, 0x15, 0x28, 0x93, 0x08, 0xE4, 0x89, 0x3C, 0x3B, 0xC4, 0xB6, 0xB8, 0x2F, 0x53, 0xDC, 0x80, 0x2B, 0xC8, 0x33, 0x9C, 0x9B, 0xDE, 0x4E, 0xA6, 0xE4, 0x6C, 0x59, 0x65, 0xAE, 0xA2, 0x59, 0x74, 0x9D, 0x76, 0xE3, 0xB3}, IV: [16]byte{0x9E, 0xD7, 0x66, 0xF7, 0xEF, 0xFE, 0xDE, 0x19, 0x5D, 0x19, 0x16, 0x02, 0xF7, 0xE2, 0x09, 0xE9}},
{Ciphertext: []byte{0x48, 0x7C, 0x9A, 0x69, 0x04, 0x5C, 0xAF, 0x53, 0xA6, 0xF3, 0xCD, 0x20, 0xBA, 0xA1, 0xFE, 0x95, 0x32, 0x2C, 0x62, 0x1A, 0x90, 0xCC, 0xAA, 0xA4, 0x8B, 0x5E, 0xF3, 0x93, 0x93, 0x21, 0x3E, 0x88, 0xD6, 0x2B, 0xD3, 0x9F, 0xCC, 0x9C, 0x8B, 0xEC, 0xF8, 0x87, 0xDB, 0x21, 0xDE, 0x80, 0xD4, 0xD1, 0x31, 0x91, 0xF9, 0x14, 0xC6, 0x84, 0x44, 0xCC, 0x3C, 0x86, 0x18, 0xBD, 0x94, 0x99, 0xDF, 0x95, 0x35, 0xEB, 0x9C, 0x7B, 0x03, 0x25, 0x18, 0x5C, 0xA7, 0x29, 0x37, 0xEE, 0x33, 0x7F, 0x52, 0x41, 0x65, 0xB1, 0xD9, 0x79, 0x28, 0xA7, 0x71, 0x74, 0x96, 0x08, 0x88, 0x36}, IV: [16]byte{0x48, 0x7C, 0x9A, 0x69, 0x04, 0x5C, 0xAF, 0x53, 0xA6, 0xF3, 0xCD, 0x20, 0x24, 0x12, 0xB8, 0xC1}},
{Ciphertext: []byte{0x65, 0x5E, 0xCB, 0xC5, 0x9D, 0xED, 0xD6, 0x7B, 0x8D, 0x30, 0x95, 0xAC, 0x61, 0x09, 0xD4, 0xC2, 0x35, 0x49, 0xA9, 0x31, 0x6F, 0x32, 0x84, 0x72, 0x15, 0x76, 0x59, 0xA6, 0xB3, 0x90, 0xB2, 0xA1, 0x08, 0x7D, 0x72, 0x6A, 0xB4, 0xE5, 0x23, 0xFC, 0x76, 0x5B, 0xBB, 0x31, 0x7D, 0x51, 0x76, 0xCE, 0xCA, 0x0D, 0x24, 0x74, 0x96, 0xA2, 0xF6, 0xAF, 0x30, 0x96, 0x28, 0x47, 0x52, 0xB2, 0xFF, 0x2C, 0x66, 0x74, 0xC0, 0x82, 0x23, 0x2C, 0xCC, 0x14, 0xBD, 0x85, 0x4A, 0xF9, 0x61, 0x8F, 0xE5, 0xF4, 0x2A, 0xAA, 0x7C, 0x75, 0xEA, 0xC6, 0x35, 0x6F, 0x10, 0x36, 0x36, 0x30}, IV: [16]byte{0x65, 0x5E, 0xCB, 0xC5, 0x9D, 0xED, 0xD6, 0x7B, 0x8D, 0x30, 0x95, 0xAC, 0x86, 0xAC, 0x5D, 0x77}},
{Ciphertext: []byte{0x7D, 0xF2, 0x37, 0xA2, 0xAC, 0x61, 0x56, 0xAF, 0xD3, 0x42, 0xB0, 0xFA, 0x54, 0x45, 0x88, 0x17, 0x19, 0x9D, 0x5A, 0x04, 0xA9, 0x97, 0xCF, 0x93, 0x64, 0x1F, 0x68, 0x18, 0xE2, 0xAB, 0x20, 0xEA, 0x7A, 0xE2, 0x29, 0x44, 0x97, 0x10, 0x70, 0x99, 0xA7, 0x91, 0x4C, 0x84, 0x9C, 0x4E, 0x42, 0xD4, 0xB1, 0x0E, 0x26, 0x6F, 0x33, 0xA8, 0xE8, 0x0D, 0x8E, 0xE0, 0x01, 0xBA, 0x38, 0x0D, 0x2B, 0x82, 0x29, 0x73, 0x70, 0x6D, 0xCD, 0xED, 0x7A, 0x8B, 0x47, 0x2F, 0x13, 0x7F, 0x09, 0xFD, 0x99, 0xB9, 0x1D, 0x90, 0x67, 0x80, 0xC2, 0x14, 0x58, 0xFD, 0x24, 0xB2, 0x16, 0xF0}, IV: [16]byte{0x7D, 0xF2, 0x37, 0xA2, 0xAC, 0x61, 0x56, 0xAF, 0xD3, 0x42, 0xB0, 0xFA, 0x54, 0x09, 0xD3, 0x75}},
{Ciphertext: []byte{0xB5, 0x67, 0x8D, 0x32, 0x9B, 0xCE, 0x74, 0xEB, 0xC3, 0xFF, 0xE3, 0xA8, 0x34, 0xE0, 0xBE, 0x5B, 0xB8, 0x72, 0x86, 0x58, 0xA5, 0x93, 0x15, 0x0E, 0x75, 0x0E, 0x78, 0x8A, 0x1E, 0x6A, 0xAB, 0x02, 0x25, 0xA6, 0x16, 0xF1, 0xFE, 0x84, 0x7F, 0x0B, 0xF7, 0xE1, 0xE9, 0xAB, 0xDD, 0x44, 0x1B, 0x39, 0x15, 0x4C, 0x98, 0x0F, 0xF5, 0x5D, 0x54, 0x50, 0x23, 0xC3, 0x2D, 0x0F, 0x39, 0x80, 0x48, 0xD1, 0x5C, 0x7B, 0xE5, 0x6D, 0x16, 0x5D, 0xA6, 0x24, 0x0D, 0x33, 0x5A, 0xFE, 0x75, 0x1A, 0x5F, 0x49, 0x06, 0x7C, 0x0E, 0xB2, 0xD5, 0x06, 0x44, 0xE0, 0x60, 0x0A, 0x3F, 0x77}, IV: [16]byte{0xB5, 0x67, 0x8D, 0x32, 0x9B, 0xCE, 0x74, 0xEB, 0xC3, 0xFF, 0xE3, 0xA8, 0x26, 0x0A, 0xB4, 0xF5}},
}
var _encPool = strenc.NewPool(_masterSeed, _encEntries)
//go:noinline
@@ -57,24 +77,22 @@ var licenseKey = _decStr(4)
func main() {
fmt.Println(_decStr(5))
if func() bool { _bciLLbB := int64(1); for i := 0; i < 10; i++ { _bciLLbB = _bciLLbB*7%49999999 }; return _bciLLbB == 1 }() { _ = struct{}{} }
fmt.Printf(_decStr(6), getVersion())
if func() bool { return (867 & 867) == 867 }() { _ = struct{}{} }
if func() bool { _bcbGLgi := [4]byte{0x72, 0x6F, 0x6F, 0x74}; return len(_bcbGLgi) == 4 }() { _ = struct{}{} }
fmt.Printf(_decStr(7), getBuildID())
if func() bool { return func() bool { return (11134^11134) > 0 && (11134^11134) < 0 }() }() { println("unreachable") }
processRequest(_decStr(8))
}
func getVersion_obf2511() string {
func getVersion_obf1861() string {
return _decStr(9)
}
func getBuildID_obf7656() string {
func getBuildID_obf7802() string {
return fmt.Sprintf(_decStr(10), time.Now().Unix())
}
func processRequest_obf1301(userID string) {
func processRequest_obf4807(userID string) {
fmt.Printf(_decStr(11), userID)
if userID == "" {
@@ -94,13 +112,14 @@ func processRequest_obf1301(userID string) {
_ = jwtSecret
}
func generateToken_obf5646(userID string) string {
func generateToken_obf1103(userID string) string {
h := sha256.Sum256([]byte(fmt.Sprintf(_decStr(15), userID, time.Now().UnixNano())))
{ _bcIcrhv := func() int { n := 0; for i := 1; i <= 100; i++ { n += i }; return n }(); _ = _bcIcrhv }
return fmt.Sprintf(_decStr(16), h[:8])
}
//go:noinline
func validateLicense_obf9184(key string) bool {
func validateLicense_obf1490(key string) bool {
_co := map[int]func([]int64) int64{
0: func(_ []int64) int64 { return int64(len(key)) },
}
@@ -109,7 +128,7 @@ func validateLicense_obf9184(key string) bool {
return _vm.Run() != 0
}
func maskString_obf9182(s string) string {
func maskString_obf3138(s string) string {
if len(s) <= 8 {
return _decStr(17)
}
BIN
View File
Binary file not shown.
+6 -2
View File
@@ -23,6 +23,8 @@ func main() {
seed := flag.Int64("seed", 0, "Build seed for polymorphic output (0 = use current timestamp)")
injectBuildID := flag.Bool("buildid", true, "Inject unique build ID constant")
virtualizeVM := flag.Bool("vm", true, "Virtualize simple functions into VM bytecode")
antiDisasm := flag.Bool("anti-disasm", true, "Inject anti-disassembly patterns")
junkStrings := flag.Bool("junk-strings", true, "Inject junk string constants")
flag.Parse()
if *srcDir == "" || *dstDir == "" {
@@ -58,16 +60,18 @@ func main() {
BuildSeed: *seed,
InjectBuildID: *injectBuildID,
VirtualizeFunctions: *virtualizeVM,
AntiDisassembly: *antiDisasm,
JunkStrings: *junkStrings,
}
t := transform.New(config)
fmt.Printf("[transformer] src=%s dst=%s\n", absSrc, absDst)
fmt.Printf("[transformer] seed=%d buildid=%v\n", config.BuildSeed, config.InjectBuildID)
fmt.Printf("[transformer] strings=%v opaque=%v deadcode=%v bogus=%v flatten=%v vm=%v\n",
fmt.Printf("[transformer] strings=%v opaque=%v deadcode=%v bogus=%v flatten=%v vm=%v antidisasm=%v junkstr=%v\n",
config.EncryptStrings, config.InjectOpaquePreds,
config.InjectDeadCode, config.BogusControlFlow, config.FlattenControl,
config.VirtualizeFunctions)
config.VirtualizeFunctions, config.AntiDisassembly, config.JunkStrings)
start := time.Now()
+102 -4
View File
@@ -34,6 +34,8 @@ type Config struct {
BuildSeed int64
InjectBuildID bool
VirtualizeFunctions bool
AntiDisassembly bool
JunkStrings bool
}
func DefaultConfig() Config {
@@ -120,6 +122,14 @@ func (t *Transformer) TransformFile(srcPath, dstPath string) error {
result = t.virtualizeFunctions(result)
}
if t.config.AntiDisassembly {
result = t.injectAntiDisassembly(result)
}
if t.config.JunkStrings {
result = t.injectJunkStrings(result)
}
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
return fmt.Errorf("mkdir %s: %w", filepath.Dir(dstPath), err)
}
@@ -921,6 +931,7 @@ func (t *Transformer) indirectDispatch(src string) string {
lines := strings.Split(src, "\n")
var result []string
var wrappers []string
dispatchIdx := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
@@ -981,13 +992,20 @@ func (t *Transformer) indirectDispatch(src string) string {
argNames := extractArgNames(argStr)
callArgs := strings.Join(argNames, ", ")
ptrVar := fmt.Sprintf("_fptr%d", dispatchIdx)
dispatchIdx++
if hasReturn {
wrapperFunc := fmt.Sprintf("func %s%s %s { return %s(%s) }",
funcName, params, returnType, funcName+obfSuffix, callArgs)
ptrDecl := fmt.Sprintf("var %s = %s", ptrVar, funcName+obfSuffix)
wrappers = append(wrappers, ptrDecl)
wrapperFunc := fmt.Sprintf("//go:noinline\nfunc %s%s %s { return %s(%s) }",
funcName, params, returnType, ptrVar, callArgs)
wrappers = append(wrappers, wrapperFunc)
} else {
wrapperFunc := fmt.Sprintf("func %s%s { %s(%s) }",
funcName, params, funcName+obfSuffix, callArgs)
ptrDecl := fmt.Sprintf("var %s = %s", ptrVar, funcName+obfSuffix)
wrappers = append(wrappers, ptrDecl)
wrapperFunc := fmt.Sprintf("//go:noinline\nfunc %s%s { %s(%s) }",
funcName, params, ptrVar, callArgs)
wrappers = append(wrappers, wrapperFunc)
}
}
@@ -1487,6 +1505,86 @@ func %s(%s int64) int64 {
}`, funcName, param, param, strings.Join(byteLits, ", "))
}
func (t *Transformer) injectAntiDisassembly(src string) string {
lines := strings.Split(src, "\n")
var result []string
inFuncBody := false
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "func ") && strings.HasSuffix(trimmed, "{") {
inFuncBody = true
result = append(result, line)
continue
}
if inFuncBody && trimmed == "}" {
inFuncBody = false
result = append(result, line)
continue
}
if inFuncBody && strings.HasPrefix(line, "\t") && !strings.HasPrefix(line, "\t\t") && trimmed != "" {
if t.rng.Float64() < 0.15 {
junkVar := stringcrypt.RandomIdent("_ad", 4)
junkSize := t.rng.Intn(32) + 8
result = append(result, fmt.Sprintf("\tvar %s [%d]byte; _ = %s", junkVar, junkSize, junkVar))
}
}
result = append(result, line)
}
return strings.Join(result, "\n")
}
func (t *Transformer) injectJunkStrings(src string) string {
junkStrings := []string{
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789abcdef0123456789abcdef",
"/usr/lib/libSystem.B.dylib",
"/proc/self/maps",
"\\x00\\x00\\x00\\x00",
"HKEY_LOCAL_MACHINE\\SOFTWARE",
"C:\\Windows\\System32\\ntdll.dll",
"SELECT * FROM users WHERE id=?",
"Content-Type: application/json",
"Mozilla/5.0 (Windows NT 10.0)",
"-----BEGIN RSA PRIVATE KEY-----",
"192.168.1.1:8080",
"admin@localhost",
"Bearer eyJhbGciOiJIUzI1NiJ9",
"application/x-www-form-urlencoded",
}
numJunk := t.rng.Intn(6) + 4
var junkBlock strings.Builder
junkBlock.WriteString("\nvar _junkData = [...]string{\n")
for i := 0; i < numJunk; i++ {
idx := t.rng.Intn(len(junkStrings))
junkBlock.WriteString(fmt.Sprintf("\t%q,\n", junkStrings[idx]))
}
junkBlock.WriteString("}\n")
junkBlock.WriteString("var _ = _junkData\n")
insertAt := findImportBlockEnd(src)
if insertAt == -1 {
pkgIdx := strings.Index(src, "package ")
if pkgIdx != -1 {
lineEnd := strings.Index(src[pkgIdx:], "\n")
if lineEnd != -1 {
insertAt = pkgIdx + lineEnd + 1
}
}
}
if insertAt != -1 && insertAt < len(src) {
src = src[:insertAt] + junkBlock.String() + src[insertAt:]
}
return src
}
func (t *Transformer) ensureImport(src string, importPath string) string {
importBlock := `import ("` + importPath + `")`
+1 -145
View File
@@ -1,21 +1,13 @@
package antidebug
import (
"fmt"
"os"
"runtime"
"time"
)
func Check() error {
if runtime.GOOS == "linux" {
if err := checkPtrace(); err != nil {
return err
}
if err := disableCoreDump(); err != nil {
return err
}
}
if err := checkTiming(); err != nil {
return err
@@ -35,139 +27,3 @@ func Check() error {
return nil
}
func checkPtrace() error {
self, err := os.ReadFile("/proc/self/status")
if err != nil {
return nil
}
data := string(self)
for i := 0; i < len(data)-11; i++ {
if data[i:i+11] == "TracerPid:\t" {
j := i + 11
for j < len(data) && data[j] >= '0' && data[j] <= '9' {
j++
}
pid := data[i+11 : j]
if pid != "0" {
return fmt.Errorf("antidebug: debugger detected (tracer pid=%s)", pid)
}
break
}
}
return nil
}
func disableCoreDump() error {
f, err := os.OpenFile("/proc/self/coredump_filter", os.O_WRONLY, 0)
if err != nil {
return nil
}
defer f.Close()
_, _ = f.WriteString("0")
return nil
}
func checkTiming() error {
start := time.Now()
sum := 0
for i := 0; i < 1000000; i++ {
sum += i
}
elapsed := time.Since(start)
if elapsed > 200*time.Millisecond {
return fmt.Errorf("antidebug: timing anomaly detected (%v for 1M iterations)", elapsed)
}
_ = sum
return nil
}
func checkEnv() error {
suspiciousVars := []string{
"GODEBUG",
"DELVE_LISTENER",
"DEBUGINFOD_URL",
"RR_LOG_FILE",
"_JAVA_OPTIONS",
"LD_PRELOAD",
"DYLD_INSERT_LIBRARIES",
}
for _, v := range suspiciousVars {
if os.Getenv(v) != "" {
return fmt.Errorf("antidebug: suspicious env var %s=%s", v, os.Getenv(v))
}
}
return nil
}
func checkParentProcess() error {
if runtime.GOOS != "linux" {
return nil
}
ppid := os.Getppid()
if ppid <= 1 {
return nil
}
commPath := fmt.Sprintf("/proc/%d/comm", ppid)
comm, err := os.ReadFile(commPath)
if err != nil {
return nil
}
parent := string(comm)
debuggers := []string{
"gdb", "lldb", "strace", "ltrace", "ida", "ida64",
"radare2", "r2", "ghidra", "x64dbg", "ollydbg",
"delve", "debugserver",
}
for _, d := range debuggers {
if len(parent) >= len(d) && parent[:len(d)] == d {
return fmt.Errorf("antidebug: parent process is debugger: %s", parent)
}
}
return nil
}
func AntiAttach() {
if runtime.GOOS != "linux" {
return
}
go func() {
for {
time.Sleep(500 * time.Millisecond)
if err := checkPtrace(); err != nil {
os.Exit(66)
}
}
}()
}
func AntiDump() {
if runtime.GOOS != "linux" {
return
}
go func() {
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for range ticker.C {
_ = disableCoreDump()
}
}()
}
func CheckHooks() error {
if err := checkFunctionPrologues(); err != nil {
return err
}
if err := scanForBreakpoints(); err != nil {
return err
}
return nil
}
+147
View File
@@ -0,0 +1,147 @@
//go:build darwin
package antidebug
import (
"fmt"
"os"
"syscall"
"time"
"unsafe"
)
const (
ctlKern = 1
kernProc = 14
kernProcPID = 1
pTraced = 0x00000800
ptDenyAttach = 31
)
func checkPtrace() error {
pid := os.Getpid()
var mib [4]int32
mib[0] = ctlKern
mib[1] = kernProc
mib[2] = kernProcPID
mib[3] = int32(pid)
bufSize := uintptr(64)
buf := make([]byte, bufSize)
_, _, errno := syscall.Syscall6(
uintptr(0x2000000+202),
uintptr(unsafe.Pointer(&mib[0])),
4,
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&bufSize)),
0,
0,
)
if errno != 0 {
return nil
}
if bufSize < 36 {
return nil
}
pFlag := uint32(buf[32]) | uint32(buf[33])<<8 | uint32(buf[34])<<16 | uint32(buf[35])<<24
if pFlag&pTraced != 0 {
return fmt.Errorf("antidebug: debugger detected via sysctl P_TRACED (pid=%d)", pid)
}
return nil
}
func denyPtraceAttach() {
pid := os.Getpid()
syscall.RawSyscall(
uintptr(syscall.SYS_PTRACE),
uintptr(ptDenyAttach),
uintptr(pid),
0,
)
}
func disableCoreDump() error {
return nil
}
func checkTiming() error {
start := time.Now()
sum := 0
for i := 0; i < 1000000; i++ {
sum += i
}
elapsed := time.Since(start)
if elapsed > 200*time.Millisecond {
return fmt.Errorf("antidebug: timing anomaly detected (%v for 1M iterations)", elapsed)
}
_ = sum
return nil
}
func checkEnv() error {
suspiciousVars := []string{
"DYLD_INSERT_LIBRARIES",
"DYLD_FRAMEWORK_PATH",
"DYLD_LIBRARY_PATH",
"DYLD_FALLBACK_FRAMEWORK_PATH",
"DYLD_FALLBACK_LIBRARY_PATH",
"DYLD_ROOT_PATH",
"GODEBUG",
"DELVE_LISTENER",
"DEBUGINFOD_URL",
"RR_LOG_FILE",
"_JAVA_OPTIONS",
}
for _, v := range suspiciousVars {
if os.Getenv(v) != "" {
return fmt.Errorf("antidebug: suspicious env var %s=%s", v, os.Getenv(v))
}
}
return nil
}
func checkParentProcess() error {
return nil
}
func AntiAttach() {
go func() {
denyPtraceAttach()
for {
time.Sleep(500 * time.Millisecond)
if err := checkPtrace(); err != nil {
os.Exit(66)
}
}
}()
}
func AntiDump() {
go func() {
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for range ticker.C {
_ = disableCoreDump()
}
}()
}
func CheckHooks() error {
if err := checkFunctionPrologues(); err != nil {
return err
}
if err := scanForBreakpoints(); err != nil {
return err
}
return nil
}
+106
View File
@@ -2,10 +2,116 @@
package antidebug
import (
"fmt"
"os"
"reflect"
"runtime"
"unsafe"
)
func checkFunctionPrologues() error {
type target struct {
name string
addr uintptr
}
targets := []target{
{"os.Exit", reflect.ValueOf(os.Exit).Pointer()},
{"runtime.Goexit", reflect.ValueOf(runtime.Goexit).Pointer()},
}
for _, t := range targets {
if t.addr == 0 {
continue
}
prologue := readAddr(t.addr, 8)
if len(prologue) < 2 {
continue
}
if prologue[0] == 0xE9 {
return fmt.Errorf("antidebug: JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xEB {
return fmt.Errorf("antidebug: short JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xFF && prologue[1] == 0x25 {
return fmt.Errorf("antidebug: indirect JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xCC && prologue[1] == 0xCC {
return fmt.Errorf("antidebug: INT3 breakpoint at %s (0x%x)", t.name, t.addr)
}
if runtime.GOARCH == "arm64" {
instr := uint32(prologue[0]) | uint32(prologue[1])<<8 | uint32(prologue[2])<<16 | uint32(prologue[3])<<24
if instr&0xFC000000 == 0x14000000 {
return fmt.Errorf("antidebug: ARM64 B hook detected at %s (0x%x)", t.name, t.addr)
}
if instr&0xFFE0001F == 0xD61F0000 {
return fmt.Errorf("antidebug: ARM64 BR hook detected at %s (0x%x)", t.name, t.addr)
}
}
}
return nil
}
func scanForBreakpoints() error {
type target struct {
name string
addr uintptr
}
targets := []target{
{"os.Exit", reflect.ValueOf(os.Exit).Pointer()},
{"runtime.Goexit", reflect.ValueOf(runtime.Goexit).Pointer()},
{"fmt.Printf", reflect.ValueOf(fmt.Printf).Pointer()},
{"os.ReadFile", reflect.ValueOf(os.ReadFile).Pointer()},
}
for _, t := range targets {
if t.addr == 0 {
continue
}
region := readAddr(t.addr, 64)
if len(region) < 8 {
continue
}
maxConsecutive := 0
consecutive := 0
for _, b := range region {
if b == 0xCC {
consecutive++
if consecutive > maxConsecutive {
maxConsecutive = consecutive
}
} else {
consecutive = 0
}
}
if maxConsecutive >= 4 {
return fmt.Errorf("antidebug: breakpoint cluster (%d consecutive INT3) near %s at 0x%x", maxConsecutive, t.name, t.addr)
}
}
return nil
}
func readAddr(addr uintptr, size int) []byte {
if size <= 0 || size > 4096 {
return nil
}
buf := make([]byte, size)
var src []byte
sh := (*reflect.SliceHeader)(unsafe.Pointer(&src))
sh.Data = addr
sh.Len = size
sh.Cap = size
copy(buf, src)
return buf
}
+116
View File
@@ -0,0 +1,116 @@
//go:build windows
package antidebug
import (
"fmt"
"os"
"reflect"
"runtime"
"syscall"
"unsafe"
)
var procReadProcessMemory = kernel32.NewProc("ReadProcessMemory")
func checkFunctionPrologues() error {
type target struct {
name string
addr uintptr
}
targets := []target{
{"os.Exit", reflect.ValueOf(os.Exit).Pointer()},
{"runtime.Goexit", reflect.ValueOf(runtime.Goexit).Pointer()},
}
currentProc, _ := syscall.GetCurrentProcess()
for _, t := range targets {
if t.addr == 0 {
continue
}
prologue := make([]byte, 8)
var bytesRead uintptr
ret, _, _ := procReadProcessMemory.Call(
uintptr(currentProc),
t.addr,
uintptr(unsafe.Pointer(&prologue[0])),
uintptr(len(prologue)),
uintptr(unsafe.Pointer(&bytesRead)),
)
if ret == 0 || bytesRead < 2 {
continue
}
if prologue[0] == 0xE9 {
return fmt.Errorf("antidebug: JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xEB {
return fmt.Errorf("antidebug: short JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xFF && prologue[1] == 0x25 {
return fmt.Errorf("antidebug: indirect JMP hook detected at %s (0x%x)", t.name, t.addr)
}
if prologue[0] == 0xCC && prologue[1] == 0xCC {
return fmt.Errorf("antidebug: INT3 breakpoint at %s (0x%x)", t.name, t.addr)
}
}
return nil
}
func scanForBreakpoints() error {
type target struct {
name string
addr uintptr
}
targets := []target{
{"os.Exit", reflect.ValueOf(os.Exit).Pointer()},
{"runtime.Goexit", reflect.ValueOf(runtime.Goexit).Pointer()},
{"fmt.Printf", reflect.ValueOf(fmt.Printf).Pointer()},
{"os.ReadFile", reflect.ValueOf(os.ReadFile).Pointer()},
}
currentProc, _ := syscall.GetCurrentProcess()
for _, t := range targets {
if t.addr == 0 {
continue
}
region := make([]byte, 64)
var bytesRead uintptr
ret, _, _ := procReadProcessMemory.Call(
uintptr(currentProc),
t.addr,
uintptr(unsafe.Pointer(&region[0])),
uintptr(len(region)),
uintptr(unsafe.Pointer(&bytesRead)),
)
if ret == 0 || bytesRead < 8 {
continue
}
maxConsecutive := 0
consecutive := 0
for _, b := range region[:bytesRead] {
if b == 0xCC {
consecutive++
if consecutive > maxConsecutive {
maxConsecutive = consecutive
}
} else {
consecutive = 0
}
}
if maxConsecutive >= 4 {
return fmt.Errorf("antidebug: breakpoint cluster (%d consecutive INT3) near %s at 0x%x", maxConsecutive, t.name, t.addr)
}
}
return nil
}
+135
View File
@@ -0,0 +1,135 @@
//go:build linux
package antidebug
import (
"fmt"
"os"
"runtime"
"time"
)
func checkPtrace() error {
self, err := os.ReadFile("/proc/self/status")
if err != nil {
return nil
}
data := string(self)
for i := 0; i < len(data)-11; i++ {
if data[i:i+11] == "TracerPid:\t" {
j := i + 11
for j < len(data) && data[j] >= '0' && data[j] <= '9' {
j++
}
pid := data[i+11 : j]
if pid != "0" {
return fmt.Errorf("antidebug: debugger detected (tracer pid=%s)", pid)
}
break
}
}
return nil
}
func disableCoreDump() error {
f, err := os.OpenFile("/proc/self/coredump_filter", os.O_WRONLY, 0)
if err != nil {
return nil
}
defer f.Close()
_, _ = f.WriteString("0")
return nil
}
func checkTiming() error {
start := time.Now()
sum := 0
for i := 0; i < 1000000; i++ {
sum += i
}
elapsed := time.Since(start)
if elapsed > 200*time.Millisecond {
return fmt.Errorf("antidebug: timing anomaly detected (%v for 1M iterations)", elapsed)
}
_ = sum
return nil
}
func checkEnv() error {
suspiciousVars := []string{
"GODEBUG",
"DELVE_LISTENER",
"DEBUGINFOD_URL",
"RR_LOG_FILE",
"_JAVA_OPTIONS",
"LD_PRELOAD",
}
for _, v := range suspiciousVars {
if os.Getenv(v) != "" {
return fmt.Errorf("antidebug: suspicious env var %s=%s", v, os.Getenv(v))
}
}
return nil
}
func checkParentProcess() error {
ppid := os.Getppid()
if ppid <= 1 {
return nil
}
commPath := fmt.Sprintf("/proc/%d/comm", ppid)
comm, err := os.ReadFile(commPath)
if err != nil {
return nil
}
parent := string(comm)
debuggers := []string{
"gdb", "lldb", "strace", "ltrace", "ida", "ida64",
"radare2", "r2", "ghidra", "x64dbg", "ollydbg",
"delve", "debugserver",
}
for _, d := range debuggers {
if len(parent) >= len(d) && parent[:len(d)] == d {
return fmt.Errorf("antidebug: parent process is debugger: %s", parent)
}
}
return nil
}
func AntiAttach() {
go func() {
for {
time.Sleep(500 * time.Millisecond)
if err := checkPtrace(); err != nil {
os.Exit(66)
}
}
}()
}
func AntiDump() {
go func() {
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for range ticker.C {
_ = disableCoreDump()
}
}()
}
func CheckHooks() error {
if err := checkFunctionPrologues(); err != nil {
return err
}
if err := scanForBreakpoints(); err != nil {
return err
}
return nil
}
+266
View File
@@ -0,0 +1,266 @@
//go:build windows
package antidebug
import (
"fmt"
"os"
"syscall"
"time"
"unsafe"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
ntdll = syscall.NewLazyDLL("ntdll.dll")
procIsDebuggerPresent = kernel32.NewProc("IsDebuggerPresent")
procCheckRemoteDebugger = kernel32.NewProc("CheckRemoteDebuggerPresent")
procNtQueryInformationProc = ntdll.NewProc("NtQueryInformationProcess")
procNtSetInformationThread = ntdll.NewProc("NtSetInformationThread")
procOutputDebugStringW = kernel32.NewProc("OutputDebugStringW")
procSetUnhandledException = kernel32.NewProc("SetUnhandledExceptionFilter")
)
const (
processDebugPort = 7
processDebugObjectHandle = 0x1E
processDebugFlags = 0x1F
threadHideFromDebugger = 0x11
)
func checkPtrace() error {
ret, _, _ := procIsDebuggerPresent.Call()
if ret != 0 {
return fmt.Errorf("antidebug: IsDebuggerPresent returned true")
}
var isRemoteDebugged int32
currentProc, _ := syscall.GetCurrentProcess()
ret, _, _ = procCheckRemoteDebugger.Call(
uintptr(currentProc),
uintptr(unsafe.Pointer(&isRemoteDebugged)),
)
if ret != 0 && isRemoteDebugged != 0 {
return fmt.Errorf("antidebug: CheckRemoteDebuggerPresent detected debugger")
}
var port uint32
var returnLength uint32
ret, _, _ = procNtQueryInformationProc.Call(
uintptr(currentProc),
processDebugPort,
uintptr(unsafe.Pointer(&port)),
unsafe.Sizeof(port),
uintptr(unsafe.Pointer(&returnLength)),
)
if ret == 0 && port != 0 {
return fmt.Errorf("antidebug: NtQueryInformationProcess(ProcessDebugPort) detected debugger (port=%d)", port)
}
var debugHandle uintptr
ret, _, _ = procNtQueryInformationProc.Call(
uintptr(currentProc),
processDebugObjectHandle,
uintptr(unsafe.Pointer(&debugHandle)),
unsafe.Sizeof(debugHandle),
uintptr(unsafe.Pointer(&returnLength)),
)
if ret == 0 {
return fmt.Errorf("antidebug: NtQueryInformationProcess(ProcessDebugObjectHandle) detected debugger")
}
var debugFlags uint32
ret, _, _ = procNtQueryInformationProc.Call(
uintptr(currentProc),
processDebugFlags,
uintptr(unsafe.Pointer(&debugFlags)),
unsafe.Sizeof(debugFlags),
uintptr(unsafe.Pointer(&returnLength)),
)
if ret == 0 && debugFlags == 0 {
return fmt.Errorf("antidebug: NtQueryInformationProcess(ProcessDebugFlags) detected debugger")
}
return nil
}
func checkPEB() error {
var pebBase uintptr
var returnLength uint32
currentProc, _ := syscall.GetCurrentProcess()
type processBasicInfo struct {
Reserved1 uintptr
PebBaseAddress uintptr
Reserved2 [2]uintptr
UniqueProcessID uintptr
Reserved3 uintptr
}
var info processBasicInfo
ret, _, _ := procNtQueryInformationProc.Call(
uintptr(currentProc),
0,
uintptr(unsafe.Pointer(&info)),
unsafe.Sizeof(info),
uintptr(unsafe.Pointer(&returnLength)),
)
if ret != 0 {
return nil
}
pebBase = info.PebBaseAddress
if pebBase == 0 {
return nil
}
beingDebugged := *(*byte)(unsafe.Pointer(pebBase + 2))
if beingDebugged != 0 {
return fmt.Errorf("antidebug: PEB.BeingDebugged is set")
}
ntGlobalFlag := *(*uint32)(unsafe.Pointer(pebBase + 0xBC))
const FLG_HEAP_ENABLE_TAIL_CHECK = 0x10
const FLG_HEAP_ENABLE_FREE_CHECK = 0x20
const FLG_HEAP_VALIDATE_PARAMETERS = 0x40
debugFlags := FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS
if ntGlobalFlag&uint32(debugFlags) != 0 {
return fmt.Errorf("antidebug: PEB.NtGlobalFlag has debug flags (0x%x)", ntGlobalFlag)
}
return nil
}
func checkHardwareBreakpoints() error {
type context struct {
ContextFlags uint32
Dr0 uintptr
Dr1 uintptr
Dr2 uintptr
Dr3 uintptr
Dr6 uintptr
Dr7 uintptr
FloatSave [112]byte
SegGs uint32
SegFs uint32
SegEs uint32
SegDs uint32
Edi uintptr
Esi uintptr
Ebx uintptr
Edx uintptr
Ecx uintptr
Eax uintptr
Ebp uintptr
Eip uintptr
SegCs uint32
EFlags uint32
Esp uintptr
SegSs uint32
ExtendedRegisters [512]byte
}
threadHandle, _ := syscall.GetCurrentThread()
var ctx context
ctx.ContextFlags = 0x00100010
procGetThreadContext := kernel32.NewProc("GetThreadContext")
ret, _, _ := procGetThreadContext.Call(
uintptr(threadHandle),
uintptr(unsafe.Pointer(&ctx)),
)
if ret == 0 {
return nil
}
if ctx.Dr0 != 0 || ctx.Dr1 != 0 || ctx.Dr2 != 0 || ctx.Dr3 != 0 {
return fmt.Errorf("antidebug: hardware breakpoints detected (dr0=0x%x dr1=0x%x dr2=0x%x dr3=0x%x)",
ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3)
}
return nil
}
func hideFromDebugger() {
threadHandle, _ := syscall.GetCurrentThread()
procNtSetInformationThread.Call(
uintptr(threadHandle),
threadHideFromDebugger,
0,
0,
)
}
func disableCoreDump() error {
return nil
}
func checkTiming() error {
start := time.Now()
sum := 0
for i := 0; i < 1000000; i++ {
sum += i
}
elapsed := time.Since(start)
if elapsed > 200*time.Millisecond {
return fmt.Errorf("antidebug: timing anomaly detected (%v for 1M iterations)", elapsed)
}
_ = sum
return nil
}
func checkEnv() error {
suspiciousVars := []string{
"GODEBUG",
"DELVE_LISTENER",
"DEBUGINFOD_URL",
"RR_LOG_FILE",
"_JAVA_OPTIONS",
}
for _, v := range suspiciousVars {
if os.Getenv(v) != "" {
return fmt.Errorf("antidebug: suspicious env var %s=%s", v, os.Getenv(v))
}
}
return nil
}
func checkParentProcess() error {
return nil
}
func AntiAttach() {
go func() {
hideFromDebugger()
for {
time.Sleep(500 * time.Millisecond)
if err := checkPtrace(); err != nil {
os.Exit(66)
}
}
}()
}
func AntiDump() {
go func() {
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for range ticker.C {
_ = disableCoreDump()
}
}()
}
func CheckHooks() error {
if err := checkFunctionPrologues(); err != nil {
return err
}
if err := scanForBreakpoints(); err != nil {
return err
}
return nil
}
+22
View File
@@ -5,6 +5,7 @@ import (
"crypto/sha256"
"debug/elf"
"debug/macho"
"debug/pe"
"encoding/binary"
"fmt"
"os"
@@ -97,6 +98,8 @@ func hashTextSection(path string) ([32]byte, error) {
return hashTextELF(path)
case "darwin":
return hashTextMacho(path)
case "windows":
return hashTextPE(path)
default:
return hashWholeFile(path)
}
@@ -139,6 +142,25 @@ func hashTextMacho(path string) ([32]byte, error) {
return hashWholeFile(path)
}
func hashTextPE(path string) ([32]byte, error) {
f, err := pe.Open(path)
if err != nil {
return [32]byte{}, err
}
defer f.Close()
for _, section := range f.Sections {
if section.Name == ".text" {
data, err := section.Data()
if err != nil {
return [32]byte{}, err
}
return sha256.Sum256(data), nil
}
}
return hashWholeFile(path)
}
func hashWholeFile(path string) ([32]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
+96 -14
View File
@@ -1,39 +1,121 @@
//go:build darwin
package syscallobf
import "syscall"
import (
"crypto/rand"
"syscall"
"unsafe"
)
var (
obfPtraceTrap ObfuscatedCall
obfGetpidTrap ObfuscatedCall
obfKillTrap ObfuscatedCall
obfOpenTrap ObfuscatedCall
obfCloseTrap ObfuscatedCall
obfReadTrap ObfuscatedCall
obfLseekTrap ObfuscatedCall
obfMmapTrap ObfuscatedCall
obfMprotectTrap ObfuscatedCall
)
func init() {
var key [4]byte
if _, err := rand.Read(key[:]); err != nil {
panic("syscallobf: failed to generate random key: " + err.Error())
}
obfPtraceTrap = encode(0x200001A, key)
obfGetpidTrap = encode(0x2000027, key)
obfKillTrap = encode(0x2000025, key)
obfOpenTrap = encode(0x2000005, key)
obfCloseTrap = encode(0x2000006, key)
obfReadTrap = encode(0x2000003, key)
obfLseekTrap = encode(0x20000C7, key)
obfMmapTrap = encode(0x20000C5, key)
obfMprotectTrap = encode(0x200004A, key)
}
func ObfPtrace(request int, pid uintptr, addr uintptr, data uintptr) (uintptr, uintptr, syscall.Errno) {
return 0, 0, syscall.ENOSYS
trap := obfPtraceTrap.Num()
r1, r2, errno := syscall.RawSyscall6(trap, uintptr(request), pid, addr, data, 0, 0)
return r1, r2, errno
}
func ObfGetpid() int {
return 0
trap := obfGetpidTrap.Num()
r1, _, _ := syscall.RawSyscall(trap, 0, 0, 0)
return int(r1)
}
func ObfKill(pid int, sig int) error {
return syscall.ENOSYS
trap := obfKillTrap.Num()
_, _, errno := syscall.RawSyscall(trap, uintptr(pid), uintptr(sig), 0)
if errno != 0 {
return errno
}
return nil
}
func ObfOpen(path string, flags int, mode int) (int, error) {
return -1, syscall.ENOSYS
trap := obfOpenTrap.Num()
pathBytes, err := syscall.BytePtrFromString(path)
if err != nil {
return -1, err
}
r1, _, errno := syscall.RawSyscall(trap, uintptr(unsafe.Pointer(pathBytes)), uintptr(flags), uintptr(mode))
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
func ObfClose(fd int) error {
return syscall.ENOSYS
trap := obfCloseTrap.Num()
_, _, errno := syscall.RawSyscall(trap, uintptr(fd), 0, 0)
if errno != 0 {
return errno
}
return nil
}
func ObfRead(fd int, buf []byte) (int, error) {
return 0, syscall.ENOSYS
trap := obfReadTrap.Num()
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
func ObfMmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset uintptr) (uintptr, error) {
return 0, syscall.ENOSYS
r1, _, errno := syscall.RawSyscall(trap, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf)))
if errno != 0 {
return int(r1), errno
}
func ObfMprotect(addr uintptr, length uintptr, prot int) error {
return syscall.ENOSYS
return int(r1), nil
}
func ObfLseek(fd int, offset int64, whence int) (int64, error) {
return 0, syscall.ENOSYS
trap := obfLseekTrap.Num()
r1, _, errno := syscall.RawSyscall(trap, uintptr(fd), uintptr(offset), uintptr(whence))
if errno != 0 {
return int64(r1), errno
}
return int64(r1), nil
}
func ObfMmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset uintptr) (uintptr, error) {
trap := obfMmapTrap.Num()
r1, _, errno := syscall.Syscall6(trap, addr, length, uintptr(prot), uintptr(flags), uintptr(fd), offset)
if errno != 0 {
return 0, errno
}
return r1, nil
}
func ObfMprotect(addr uintptr, length uintptr, prot int) error {
trap := obfMprotectTrap.Num()
_, _, errno := syscall.RawSyscall(trap, addr, length, uintptr(prot))
if errno != 0 {
return errno
}
return nil
}
+195
View File
@@ -0,0 +1,195 @@
//go:build windows
package syscallobf
import (
"crypto/rand"
"sync"
"syscall"
"unsafe"
)
var (
modntdll = syscall.NewLazyDLL("ntdll.dll")
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
procNtSetInformationThread = modntdll.NewProc("NtSetInformationThread")
procNtClose = modntdll.NewProc("NtClose")
procNtProtectVirtualMemory = modntdll.NewProc("NtProtectVirtualMemory")
procNtReadVirtualMemory = modntdll.NewProc("NtReadVirtualMemory")
procNtOpenProcess = modntdll.NewProc("NtOpenProcess")
obfPtraceTrap ObfuscatedCall
obfGetpidTrap ObfuscatedCall
obfKillTrap ObfuscatedCall
obfOpenTrap ObfuscatedCall
obfCloseTrap ObfuscatedCall
obfReadTrap ObfuscatedCall
obfLseekTrap ObfuscatedCall
obfMmapTrap ObfuscatedCall
obfMprotectTrap ObfuscatedCall
)
func init() {
var key [4]byte
if _, err := rand.Read(key[:]); err != nil {
panic("syscallobf: failed to generate random key: " + err.Error())
}
obfCloseTrap = encode(0, key)
obfReadTrap = encode(0, key)
obfOpenTrap = encode(0, key)
obfLseekTrap = encode(0, key)
obfMmapTrap = encode(0, key)
obfMprotectTrap = encode(0, key)
obfPtraceTrap = encode(0, key)
obfGetpidTrap = encode(0, key)
obfKillTrap = encode(0, key)
}
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetCurrentPID = kernel32.NewProc("GetCurrentProcessId")
procOpenProcess = kernel32.NewProc("OpenProcess")
procCloseHandle = kernel32.NewProc("CloseHandle")
procReadProcessMem = kernel32.NewProc("ReadProcessMemory")
)
func ObfGetpid() int {
r1, _, _ := procGetCurrentPID.Call()
return int(r1)
}
func ObfOpen(path string, flags int, mode int) (int, error) {
p, err := syscall.UTF16PtrFromString(path)
if err != nil {
return -1, err
}
access := uint32(syscall.GENERIC_READ)
if flags&syscall.O_WRONLY != 0 {
access = syscall.GENERIC_WRITE
}
if flags&syscall.O_RDWR != 0 {
access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
}
creation := uint32(syscall.OPEN_EXISTING)
if flags&syscall.O_CREAT != 0 {
creation = syscall.CREATE_ALWAYS
}
h, _, err := syscall.CreateFile(p, access, syscall.FILE_SHARE_READ, nil, creation, syscall.FILE_ATTRIBUTE_NORMAL, 0)
if err != nil && err.(syscall.Errno) != 0 {
return -1, err
}
return int(h), nil
}
func ObfClose(fd int) error {
r1, _, err := procCloseHandle.Call(uintptr(fd))
if r1 == 0 {
return err
}
return nil
}
func ObfRead(fd int, buf []byte) (int, error) {
var bytesRead uint32
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
r1, _, err := syscall.ReadFile(
syscall.Handle(fd),
buf,
&bytesRead,
nil,
)
if r1 == 0 {
return int(bytesRead), err
}
return int(bytesRead), nil
}
func ObfLseek(fd int, offset int64, whence int) (int64, error) {
var newOff int64
high := int32(offset >> 32)
r1, _, err := syscall.Seek(syscall.Handle(fd), int32(offset), high)
if r1 == 0xffffffff && err != nil {
return 0, err
}
_ = newOff
return int64(r1), nil
}
func ObfMmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset uintptr) (uintptr, error) {
flProtect := uint32(syscall.PAGE_READWRITE)
if prot&syscall.PROT_EXEC != 0 {
flProtect = syscall.PAGE_EXECUTE_READWRITE
}
h, _, err := syscall.CreateFileMapping(
syscall.Handle(fd),
nil,
flProtect,
uint32(length>>32),
uint32(length),
nil,
)
if h == 0 {
return 0, err
}
return uintptr(h), nil
}
func ObfMprotect(addr uintptr, length uintptr, prot int) error {
var oldProtect uint32
flProtect := uint32(syscall.PAGE_READWRITE)
if prot&syscall.PROT_EXEC != 0 {
flProtect = syscall.PAGE_EXECUTE_READWRITE
}
r1, _, err := procNtProtectVirtualMemory.Call(
uintptr(0xffffffffffffffff),
uintptr(unsafe.Pointer(&addr)),
uintptr(unsafe.Pointer(&length)),
uintptr(flProtect),
uintptr(unsafe.Pointer(&oldProtect)),
)
if r1 != 0 {
return err
}
return nil
}
type windowsObfCall struct {
once sync.Once
procAddr uintptr
proc *syscall.LazyProc
}
func (w *windowsObfCall) Call(args ...uintptr) (uintptr, uintptr, error) {
w.once.Do(func() {
if w.proc != nil {
w.procAddr = w.proc.Addr()
}
})
return syscall.Syscall(w.procAddr, uintptr(len(args)), args[0], args[1], args[2])
}
func NtQueryInformationProcess(handle uintptr, infoclass uint32, info uintptr, infolen uint32, retlen *uint32) uintptr {
r1, _, _ := procNtQueryInformationProcess.Call(
handle,
uintptr(infoclass),
info,
uintptr(infolen),
uintptr(unsafe.Pointer(retlen)),
)
return r1
}
func NtSetInformationThread(handle uintptr, infoclass uint32, info uintptr, infolen uint32) uintptr {
r1, _, _ := procNtSetInformationThread.Call(
handle,
uintptr(infoclass),
info,
uintptr(infolen),
)
return r1
}
+32
View File
@@ -1,7 +1,9 @@
package vm
import (
"crypto/rand"
"fmt"
"math/big"
)
type Instruction struct {
@@ -15,7 +17,15 @@ type LabelledInstr struct {
Target string
}
type CompileOpts struct {
NoJunk bool
}
func Compile(program []LabelledInstr) []byte {
return CompileWith(program, CompileOpts{})
}
func CompileWith(program []LabelledInstr, opts CompileOpts) []byte {
labelAddrs := make(map[string]int)
type fixup struct {
@@ -26,11 +36,18 @@ func Compile(program []LabelledInstr) []byte {
var fixups []fixup
var bytecode []byte
junkOpcodes := []Opcode{opJunkA, opJunkB, opJunkC, opJunkD}
for _, entry := range program {
if entry.Label != "" {
labelAddrs[entry.Label] = len(bytecode)
}
if !opts.NoJunk && shouldInsertJunk() {
junkOp := junkOpcodes[randIntn(len(junkOpcodes))]
bytecode = append(bytecode, encodeOp(junkOp))
}
instr := entry.Instr
isJump := instr.Op == OpJmp || instr.Op == OpJz || instr.Op == OpJnz
@@ -64,3 +81,18 @@ func Compile(program []LabelledInstr) []byte {
return bytecode
}
func shouldInsertJunk() bool {
return randIntn(3) == 0
}
func randIntn(n int) int {
if n <= 0 {
return 0
}
b, err := rand.Int(rand.Reader, big.NewInt(int64(n)))
if err != nil {
return 0
}
return int(b.Int64())
}
+27 -5
View File
@@ -430,7 +430,7 @@ func TestStepwiseExecution(t *testing.T) {
{Instr: Instruction{Op: OpHalt}},
}
code := Compile(program)
code := CompileWith(program, CompileOpts{NoJunk: true})
vm := NewVM(code, nil)
steps := 0
@@ -461,8 +461,13 @@ func TestXorObfuscationDeterminism(t *testing.T) {
{Instr: Instruction{Op: OpHalt}},
}
code1 := Compile(program)
code2 := Compile(program)
opts := CompileOpts{NoJunk: true}
code1 := CompileWith(program, opts)
code2 := CompileWith(program, opts)
if len(code1) != len(code2) {
t.Fatalf("bytecode length differs: %d vs %d", len(code1), len(code2))
}
for i := range code1 {
if code1[i] != code2[i] {
@@ -487,9 +492,8 @@ func TestBytecodeIsXORed(t *testing.T) {
{Instr: Instruction{Op: OpHalt}},
}
code := Compile(program)
code := CompileWith(program, CompileOpts{NoJunk: true})
// First byte should be OpPush ^ dispatchKey, not OpPush itself
rawPush := byte(OpPush) ^ dispatchKey
if code[0] != rawPush {
t.Errorf("expected bytecode[0]=0x%02X (XOR'd PUSH), got 0x%02X", rawPush, code[0])
@@ -501,6 +505,24 @@ func TestBytecodeIsXORed(t *testing.T) {
}
}
func TestJunkOpcodesCorrectness(t *testing.T) {
program := []LabelledInstr{
{Instr: Instruction{Op: OpPush, Args: []int64{10}}},
{Instr: Instruction{Op: OpPush, Args: []int64{20}}},
{Instr: Instruction{Op: OpAdd}},
{Instr: Instruction{Op: OpHalt}},
}
for i := 0; i < 50; i++ {
code := Compile(program)
vm := NewVM(code, nil)
result := vm.Run()
if result != 30 {
t.Fatalf("iteration %d: expected 30, got %d (bytecode len %d)", i, result, len(code))
}
}
}
func TestOrOp(t *testing.T) {
// 0x0F OR 0xF0 = 0xFF
program := []LabelledInstr{