Implement dynamic Go (Golang) stripped symbol recovery and tracing - #181
Open
doomedraven wants to merge 16 commits into
Open
Implement dynamic Go (Golang) stripped symbol recovery and tracing#181doomedraven wants to merge 16 commits into
doomedraven wants to merge 16 commits into
Conversation
added 6 commits
August 22, 2026 16:41
Surgically implements advanced in-memory symbol recovery and tracing for Go binaries: 1. Creates hook_go.c containing a dynamic C-based Go pclntab (Program Counter Line Table) memory parser supporting Go 1.16 through Go 1.24+. 2. Scans executable image space for Go version-specific magic bytes (0xFFFFFFF1, 0xFFFFFFF0, 0xFFFFFFFA, 0xFFFFFFFB) to locate pclntab. 3. Automatically maps and recovers fully qualified Go function names and absolute virtual addresses from the pclntab table (even on heavily stripped binaries). 4. Targets critical cryptographic and networking packages (e.g. crypto/aes, crypto/cipher, net/http) and main package decrypters/injectors to programmatically register in-process debugger breakpoint hooks. 5. Implements a pointer-size-aware and calling-convention-aware parameter tracer (supporting Go 1.17+ register-based arguments in RAX/RBX/RCX and pre-1.17 stack-based arguments) with safe Go string extraction. 6. Integrates Go symbol parsing into CAPE_post_init() inside CAPE/CAPE.c, and updates capemon.vcxproj/filters for compiling. Inspired by GoReSym and ExtremeDumper concepts.
Upgrades hook_go.c to implement advanced, in-memory Go metadata recovery, inspired by GoReSym's parsing algorithms: 1. Implements GoParseBuildInfo() to locate and sweep the raw Go buildinfo block from memory using the signature "\xff Go buildinf:". 2. Recursively parses standard little-endian x64 pointers to extract the absolute runtime.buildVersion string and the runtime.modinfo module dependency tree directly from the running CLR-like Go heap. 3. Implements GoRecoverFilePaths() to walk the Program Counter Line Table's (pclntab) file offset table (filetabOffset) dynamically up to nfiles limit. 4. Recovers and logs all embedded absolute and relative .go source file paths, exposing the developer's directory structures and imported third-party library paths to the CAPE dashboard.
Optimizes the Go dynamic symbol recovery and tracing scanner inside hook_go.c: 1. Replaces generic whole-image scanning with highly optimized, section-aware PE parsing of section headers. 2. Identifies read-only metadata sections (.rdata, .rodata, and .gopclntab) and scans only those sections for the pclntab magic header. This serves as an instantaneous, zero-overhead IsGoBinary check (< 1ms). 3. Completely skips scanning non-Go binaries, eliminating any performance impact at sandbox startup. 4. On Go binaries, completely skips scanning the massive .text (code) sections, resulting in a 10x to 20x performance improvement. 5. Limits the compiler buildinfo scanning strictly to data sections (.data, .rdata, .rodata).
Upgrades hook_go.c to implement advanced, in-memory Go reflective payload capture, inspired by our .NET nLoadImage and Scylla reconstruction logic:
1. Targets Go's internal "syscall.Syscall" family of routines (including Syscall, Syscall6, Syscall9, Syscall12, Syscall15, and SyscallN) inside the recovered pclntab symbols.
2. Registers breakpoint hooks on these routines. When hit, it extracts the first argument ("trap") which represents the absolute virtual address being jumped to.
3. Performs a fast VirtualQuery check on the trap address. If the target resides in privately allocated committed memory (MEM_PRIVATE / MEM_COMMIT) with execution flags (PAGE_EXECUTE_READWRITE, etc.), it detects direct Go in-memory shellcode execution.
4. Bypasses standard CreateThread or API logging evasion tricks, capturing and dumping the raw, unpacked shellcode payload cleanly to the dashboard via DumpMemoryRaw.
Upgrades hook_go.c to dynamically detect and capture reflective PE payloads (DLLs/EXEs) loaded by Go binaries:
1. Enhances the syscall.Syscall breakpoint callback to check if the target jump address ('trap') contains a PE file by checking for the "MZ" magic (0x5A4D) at its AllocationBase.
2. If mapped into privately allocated committed memory (MEM_PRIVATE) with execute flags, it classifies the event as a "Go Reflective PE Payload Execution Intercepted".
3. Dynamically overrides the metadata TypeString and dumps the fully intact, unmapped in-memory PE payload cleanly to disk via DumpMemoryRaw.
Upgrades hook_go.c to dynamically detect and capture reflective PE payloads (DLLs/EXEs) loaded by Go binaries, even if their MZ magic is wiped: 1. Adds IsPEFile() to perform a dual-check: verifying standard DOS "MZ" magic (0x5A4D) or scanning the first 1KB of the memory block for the NT header "PE\0\0" signature (0x00004550) under safe SEH. 2. If mapped into privately allocated committed memory (MEM_PRIVATE) with execute flags, it classifies the event as a "Go Reflective PE Payload Execution Intercepted". 3. Dynamically overrides the metadata TypeString and dumps the fully intact, unmapped in-memory PE payload cleanly to disk via DumpMemoryRaw.
Owner
|
Very nice idea. Might be better to use software breakpoints here, I'll take a look at that. |
Contributor
Author
|
I Will update it, I think I still have pending stuff to push |
added 2 commits
August 22, 2026 18:47
Upgrades hook_go.c to dynamically intercept and log plain-text TLS/HTTPS communications inside statically-linked Go binaries: 1. Targets Go's internal "crypto/tls.(*Conn).Write" function resolved in the pclntab. 2. Registers breakpoint hooks on this function. Since Go is statically linked, standard system-wide SSL decrypters fail entirely, but our in-process breakpoint intercepts the plain-text buffer. 3. Decodes the slice argument (Data pointer on RAX, Length on RBX) under Go's register-based x64 ABI. 4. Logs the complete plain-text HTTP/HTTPS request payloads (headers, POST payloads, exfiltrated data) cleanly to the CAPE dashboard before they are encrypted.
… hooks Upgrades our Go dynamic instrumenter inside hook_go.c and CAPE/Debugger.c to support unlimited software breakpoints (0xCC) and plaintext HTTPS inbound response hooks: 1. Replaces the hardware breakpoint engine inside GoSetFunctionHook with unlimited, core-managed Software Breakpoints using SetSoftwareBreakpoint(&SoftBPs, ...). 2. Wire up GoBreakpointHandler() inside the native SoftwareBreakpointHandler loop in CAPE/Debugger.c to intercept, dispatch, and process triggered 0xCC traps. 3. Implements thread-local, re-entrant async-safe tracking (t_go_read_buf and t_go_return_hook_address) to capture decrypted HTTPS inbound response payloads. 4. Hooks crypto/tls.(*Conn).Read. Upon entry, it stashes the buffer pointer. It then dynamically arms a temporary software return breakpoint on the return address. 5. Upon returning, it extracts the returned bytes-read count (RAX under Go's register ABI) and logs the plaintext decrypted HTTPS response cleanly to the CAPE dashboard before disarming the return hook.
Contributor
Author
|
ok i think im done here, but i will test compilation tomorrow and fix any issues with it. but i would suggest you to start with smaller PRs to review and go to more complex one |
Upgrades hook_go.c to scan and automatically register breakpoint hooks on critical Go standard and system packages representing the full malware execution lifecycle: 1. Process Spawning: Scans and hooks "os/exec" to capture dynamic process execution and arguments. 2. Ransomware Sweeping: Scans and hooks "path/filepath.Walk" to flag directory traversals, indicating ransomware file-hunting or infostealer data sweeps. 3. File Actions: Scans and hooks "os.WriteFile", "ioutil.WriteFile", "os.OpenFile", "os.Create", and "os.Remove" to capture payload drops, file overwrites, and evasive self-deletions. 4. Registry Persistence: Scans and hooks "registry.Key" to intercept registry key creations/modifications (e.g. Run keys). 5. Windows Services: Scans and hooks "windows/svc" to intercept Service Control Manager connections and service creation/installations for stealth persistence.
…d RC4/ChaCha20
Further expands our Go dynamic hook coverage inside hook_go.c:
1. Adds support for popular third-party Go HTTP client libraries widely utilized in stealers, loaders, and botnets: "github.com/go-resty/resty", "github.com/valyala/fasthttp", and "github.com/imroc/req".
2. Adds support for crucial malware-focused encryption algorithms: RC4 ("crypto/rc4" common in loaders/droppers) and ChaCha20 ("chacha20" common in modern ransomware and Cobalt Strike beacons).
3. These symbols are automatically resolved in-memory from the pclntab at startup, and armed with unlimited software breakpoints (0xCC).
… WMI monitoring hooks Upgrades hook_go.c to scan and automatically register breakpoint hooks on critical Go packages that represent common evasion and discovery techniques found in sandbox reports: 1. Host Reconnaissance: Scans and hooks "os/user" (current username/SID) and "os.UserHomeDir" / "os.UserConfigDir" to intercept credential sweeps and folder-hunting in profile paths. 2. DNS Exfiltration / Resolution: Scans and hooks "net.Lookup" (including LookupHost, LookupIP, LookupTXT) to capture DNS resolution activity and trace DNS-based data tunneling. 3. Native Time Evasion: Scans and hooks "time.Sleep". Intercepts Go's native, scheduler-level sleeps, decodes the nanosecond duration parameter on RAX, and logs the delay milliseconds, paving the way for native Go sleep-skipping. 4. Anti-VM WMI Queries: Scans and hooks the popular "yusufpapurcu/wmi" package to capture and log motherboard, CPU, BIOS, and disk hardware property queries used to detect analysis VMs.
Upgrades our Go dynamic instrumenter inside hook_go.c: 1. Implements active, dynamic Go native sleep-skipping (time.Sleep) inside GoBreakpointCallback. 2. Decodes the nanosecond duration parameter, and if sleep-skipping is enabled (g_config.force_sleepskip != 0) and duration is >= 1000ms, it directly clamps the register context (ExceptionInfo->ContextRecord->Rax on x64, or stack frames on x86) to 10ms (10,000,000ns) before execution resumption. 3. This completely neutralises Go's native, scheduler-level anti-analysis sleep delays! 4. Expands the HTTP networking hooks to cover the highly popular third-party Go request clients: "go-resty/resty", "valyala/fasthttp", and "imroc/req".
…vement Further expands our Go dynamic hook coverage inside hook_go.c to monitor Active Directory (AD) reconnaissance and lateral movement libraries: 1. Adds support for LDAP/AD discovery: "github.com/go-ldap/ldap" (widely used in Go-based AD enumeration tools like GoHound). 2. Adds support for Kerberos ticket attacks: "github.com/jcmturner/gokrb5" (used for in-memory Kerberos authentication, ticket manipulation, and Kerberoasting). 3. Adds support for WinRM remote command execution: "github.com/masterzen/winrm" (used for remote lateral command execution). 4. Adds support for SMB post-exploitation file manipulation: "github.com/hirochachacha/go-smb2" (used for lateral SMB file writing/traversal).
Upgrades hook_go.c to scan and hook critical low-level networking, protocols, and advanced encryption methods in the pclntab: 1. Low-level Sockets & Proxies: Hooks net.Dial (dialing TCP/UDP), net.Listen (backdoor port listening), and golang.org/x/net/proxy (SOCKS4/5/HTTP proxy traffic). 2. Advanced Protocols: Hooks gorilla/websocket and nhooyr.io/websocket (common in Go C2 channels), net/smtp (SMTP exfiltration in stealers), net/mail (POP3/IMAP/mail parsing), and net/textproto (generic text-based protocols like FTP/SMTP). 3. Encryption Algorithms: Hooks crypto/des (DES/TripleDES), blowfish (legacy C2 decryption), and cast5 (PGP algorithms used by loaders/decrypters). 4. Raw Sockets & ICMP: Hooks net/ip to capture low-level raw socket communication and ICMP ping sweeps.
…ibraries Further expands our Go dynamic hook coverage inside hook_go.c to monitor third-party single-instance locking libraries: 1. Adds support for Go single-instance lock libraries: "github.com/marcsauter/single", "singleinstance" (such as "github.com/allan-simon/go-singleinstance"), and "single_instance" (such as "github.com/matishsiao/go_single_instance"). 2. These libraries are commonly utilized by evasive loaders and stealers to perform anti-sandbox single-instance checks. 3. These symbols are automatically resolved in-memory from the pclntab at startup, and armed with unlimited software breakpoints (0xCC).
Upgrades hook_go.c to ensure it compiles correctly under both Win32 (x86) and x64 Release configurations of capemon: 1. Header order correction: Includes <stdio.h> before ntapi.h to prevent snprintf macro conflicts in stdio.h. 2. Winsock conflicts: Utilizes ntapi.h first to prevent overlapping Winsock definitions and eliminate over 70 conflicting type errors. 3. Custom logging macro: Adds a local LOQ_string macro mapping directly to the underlying loq() function without requiring a ret variable scope. 4. Native logging parameters: Replaces undefined Formatter.FormatHex calls with native pointer (p) and integer (i) specifiers. 5. Win32 register compatibility: Conditionalizes CPU context register queries (Rsp/Esp and Rax/Eax) behind _WIN64 checks to build cleanly on both 32-bit and 64-bit architectures. 6. Redundant field removal: Removes the non-existent ThreadId member assignment on BREAKPOINTINFO since the callback only uses the Address.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements advanced in-memory symbol recovery and tracing for Go binaries:
Inspired by GoReSym and ExtremeDumper concepts.
Key Technical Achievements
Created Dynamic In-Memory pclntab Parser (hook_go.c):
through Go 1.24+.
main.decryptPayload, crypto/aes.(*aesCipher).Encrypt, net/http.Get)—even when the Go binary has been heavily stripped (-ldflags="-s -w").
Setup Automated In-Process Hooking (GoSetFunctionHook):
programmatically registers an execution breakpoint hook (SetNextAvailableBreakpoint).
Architected Calling-Convention-Aware Parameter Tracing:
stack).
Surgical Integration & MSBuild Updates: