PE manipulation
Pure-Go Portable Executable analysis, sanitisation, identity
cloning, signature grafting, and conversion-to-shellcode. The
package tree is intentionally bottom-up: pe/parse and
pe/imports are read-only walkers, pe/strip, pe/morph,
pe/cert, pe/masquerade are byte-mutators on a []byte, and
pe/srdi is the producer of position-independent shellcode that
downstream inject/ chains consume. Runtime-side BOF and CLR
loaders moved to runtime/bof and
runtime/clr respectively.
flowchart LR
subgraph offline [Offline / build-host]
SRC[Source PE<br>signed donor]
PARSE[parse + imports<br>read-only walkers]
STRIP[strip<br>Go-toolchain scrub]
MORPH[morph<br>UPX header rename]
CERT[cert<br>Authenticode graft]
MASQ[masquerade<br>manifest + icon<br>+ VERSIONINFO clone]
SRDI[srdi<br>Donut PE → shellcode]
end
subgraph runtime [Runtime / target host]
INJECT[inject/*<br>execute shellcode]
BOF[runtime/bof<br>COFF loader]
CLR[runtime/clr<br>.NET hosting]
end
SRC --> PARSE
SRC --> STRIP
SRC --> MORPH
SRC --> CERT
SRC --> MASQ
SRC --> SRDI
SRDI --> INJECT
PARSE -. drives unhook scoping .-> RUNT[runtime evasion]
Packages
| Package | Tech page | Detection | One-liner |
|---|---|---|---|
pe/parse | (covered here + doc.go) | very-quiet | Read-only debug/pe wrapper for section / export / raw-byte access |
pe/imports | imports.md | very-quiet | Cross-platform import-table enumeration |
pe/strip | strip-sanitize.md | quiet | Go pclntab wipe + section rename + timestamp scrub |
pe/morph | morph.md | moderate | UPX header signature mutation |
pe/cert | certificate-theft.md | quiet | Authenticode security-directory read / copy / strip / write |
pe/masquerade | masquerade.md | quiet | manifest + icon + VERSIONINFO clone via .syso (preset or programmatic) |
pe/srdi | pe-to-shellcode.md | moderate | PE / .NET / script → Donut shellcode |
pe/dllproxy | dll-proxy.md | very-quiet | Pure-Go forwarder DLL emitter for DLL-hijack payloads |
Quick decision tree
| You want to… | Use |
|---|---|
| …read every DLL!Function pair from a PE | imports.List |
| …wipe the "Made in Go" markers | strip.Sanitize |
| …hide a UPX-packed binary from auto-unpackers | morph.UPXMorph |
| …graft a Microsoft signature onto an unsigned binary | cert.Copy |
| …make Process Explorer render the implant as svchost | preset blank-import |
| …clone any PE's identity programmatically | masquerade.Clone / Build |
| …convert a PE / .NET / script to position-independent shellcode | srdi.ConvertFile |
| …feed shellcode to remote-process injection | pe/srdi → inject |
| …enumerate sections / exports for tooling | pe/parse |
| …emit a forwarder DLL for hijack payloads (no MSVC) | dllproxy.Generate |
MITRE ATT&CK
| T-ID | Name | Packages | D3FEND counter |
|---|---|---|---|
| T1027.002 | Obfuscated Files or Information: Software Packing | pe/strip, pe/morph, pe/parse | D3-SEA, D3-FCA |
| T1027.005 | Indicator Removal from Tools | pe/strip | D3-SEA |
| T1036.005 | Masquerading: Match Legitimate Name or Location | pe/masquerade | D3-EAL, D3-SEA |
| T1055.001 | Process Injection: Dynamic-link Library Injection | pe/srdi (consumer) | D3-PA |
| T1106 | Native API | pe/imports | D3-SEA |
| T1574.001 | DLL Search Order Hijacking | pe/dllproxy | D3-PFV |
| T1574.002 | DLL Side-Loading | pe/dllproxy | D3-PFV |
| T1553.002 | Subvert Trust Controls: Code Signing | pe/cert | D3-EAL |
| T1620 | Reflective Code Loading | pe/srdi | D3-FCA, D3-PA |
Layered scrub recipe
The full identity scrub for a Go-built implant is a six-step build-host pipeline. None of the steps is enough alone; together they survive triage long enough to matter.
- Build with garble — symbol obfuscation at compile time.
pe/masquerade.Clone— clone svchost / cmd / explorer identity at link time via.syso.pe/strip.Sanitize— wipe pclntab + rename Go sections + scrub timestamp.- UPX pack +
pe/morph.UPXMorph— defeat signature-based unpackers. pe/cert.Copy— graft a Microsoft Authenticode blob.cleanup/timestomp.CopyFromFull— align MFT timestamps to the donor.
For payload delivery (separate from build):
pe/srdi.ConvertFile— convert the implant or downstream payload to Donut shellcode.inject/*— deliver the shellcode via any of the documented techniques.
See also
- Operator path: build-host pipeline — full scrub recipe.
- Detection eng path: PE-level artefacts.
runtime/bof— COFF (BOF) loader; consumes BOF objects produced upstream.runtime/clr— in-process .NET hosting; consumes managed payloads.inject— execution surface forpe/srdishellcode.crypto— payload encryption pre-conversion.hash— measure SHA-256 vs fuzzy-hash deltas after morph.