Reverse Engineering
Use this skill for static-first binary analysis. Start with format/runtime identification, then switch into the relevant language/runtime reference. Detailed references are bundled for Go and packaged JavaScript CLIs; add more references as workflows are tested.
Default posture
- Treat "do not run this binary" as a hard constraint.
- Default to static inspection even when the user does not say it explicitly.
- Do not modify the target binary. Write extracted artefacts to a separate workspace under
/tmpunless the user asks for a specific location. - If a tool is missing in dotfiles, follow
AGENTS.mddependency ownership: host-global and well-packaged tools go in Nix; project/version-selected tools go in mise; macOS vendor bundles go in Homebrew. - Avoid printing credential-like values verbatim. Record that they exist and where they were found; show only enough prefix/context to identify the finding.
Workflow
-
Create a workspace:
mkdir -p /tmp/re-<target-name> -
Run baseline static triage:
file <binary> shasum -a 256 <binary> # macOS strings -a <binary> > strings.txt -
Identify the likely runtime/language:
- Go:
go version -mworks,.gopclntab/__gopclntabexists, or strings mention Go runtime paths such asruntime.main. - Rust: symbols or strings mention
rustc,panic_unwind,core::,alloc::, or cargo metadata. - .NET: PE metadata, CLR headers,
mscoree.dll,System.*,Microsoft.*. - Java/Kotlin: JAR/APK/classes,
META-INF, JVM constant pools. - Packaged JS CLI: single-file executables with Bun/JSC, Node SEA,
pkg/nexe, Denocompile,NODE_SEA_BLOB,__BUN,/$bunfs/,/snapshot/,denort, or bundlednode_modulesstrings. - Electron/Node app: app archives,
app.asar, V8 snapshots,node_modules, Chromium strings. - Native C/C++/Obj-C/Swift: no managed runtime, platform ABI symbols, Objective-C/Swift metadata, dynamic library imports.
- Go:
-
Read the matching reference before deeper analysis. Current reference:
- references/go.md for Go binaries.
- references/package-js-cli.md for single-file packaged JavaScript/TypeScript CLIs.
-
For Go binaries, the bundled helper can run the static triage ladder:
python scripts/go_binary_triage.py <binary> --out /tmp/re-<target-name>If
gois a mise shim without a selected version, pass the Go command explicitly:python scripts/go_binary_triage.py <binary> --go-cmd "mise exec go@1.25 -- go" --out /tmp/re-<target-name> -
Recover runtime-specific metadata with at least two independent paths when possible. For Go:
GoReSym -t -d -p -strings <binary> > goresym.json redress info <binary> > redress-info.txt redress packages <binary> > redress-packages.txt redress source <binary> > redress-source.txtTool failure is evidence about the tooling, not proof the binary lacks metadata. Record the failure and try the next parser.
-
Use strings as a lead generator, not as proof:
strings -a <binary> > strings.txtFor important literals, confirm pointer/length use or code xrefs before claiming a value is used at runtime.
-
For decompilation, import recovered names/types into the best available workbench:
- Ghidra latest for free decompilation.
- IDA 9.2+ if available for stronger Go ABI decompilation.
- Binary Ninja + Go plugins if available for type-heavy workflows.
- radare2 when a headless annotation pipeline is more useful than a GUI.
Evidence Levels
Use explicit confidence language:
- Confirmed: backed by build info, recovered function/package metadata, disassembly/xref, or data-flow from reachable code.
- Likely: multiple independent static signals align, but exact control flow is not fully proven.
- Present: a string, package, symbol, or type exists in the binary, but usage is unproven.
- Unclear: tool output conflicts or version/obfuscation limits prevent a stronger claim.
Report Shape
Keep reports compact and evidence-backed:
## Target
- Path:
- Format / arch:
- Runtime / version:
- Hash:
- Execution constraint:
## Static Findings
- Build info:
- Packages / dependencies:
- Recovered user packages:
- Notable endpoints / model routes / config keys:
## Behavioural Claims
| Claim | Evidence | Confidence |
|---|---|---|
## Tool Notes
- Succeeded:
- Failed / limitations:
- Useful next tools:
If the user asks how to reproduce the behaviour elsewhere, add a short Reusable Pattern section that separates control plane, local identity/state, transport, reconciliation, execution attachment, failure handling, and security implications.
Tooling Discussion
If the useful tools are missing, propose a small install set rather than a broad RE toolbox:
- Core CLI: Go toolchain,
GoReSym,redress,radare2,binutils,upx,yara,jq,ripgrep. In dotfiles, the RE-specific CLI tools are expected to be Nix-owned. - Binary format tools:
binutilsor LLVM tools on Linux;otool/lldbalready exist on macOS. - Workbench: Ghidra first if a free GUI decompiler is needed; IDA/Binary Ninja only if already available or explicitly desired.
- Obfuscation extras: GoStringUngarbler only when garble
-literalsevidence exists.
Discuss GUI workbenches, vendor bundles, and language-specific extras before adding them.