ih8sn1ff
# ih8Sn1ff
[](https://github.com/ih8w1nd/ih8sn1ff/actions/workflows/ci.yml)
[](https://github.com/ih8w1nd/ih8sn1ff/actions/workflows/ci-windows.yml)
[](LICENSE)
Repository: https://github.com/ih8w1nd/ih8sn1ff
Agent-first reverse-engineering toolkit with a native **MCP server** and a matching CLI.
Built for the workflow that actually cracks modern protected binaries: **run → dump →
rebuild → analyze → decompile**, with every step scriptable and every result
LLM-friendly.
```
run_and_dump → rebuild_pe → trim_pe → delphi_methods → ghidra_decompile
│ │ │ │ │
process memory→file analysis-sized RTTI name→RVA C pseudo-code
modules aligned PE PE for Ghidra (Delphi apps)
```
## Why another RE tool?
- **MCP-native.** Every capability is exposed as an MCP tool, so an agent (Claude,
or any MCP host) drives the analysis loop directly: scan strings, find xrefs,
decompile, dump the live process, re-scan.
- **Actually practical on packed binaries.** VMProtect- / Themida-class wrappers are
beaten at runtime, not statically. ih8Sn1ff ships the operational chain used for
that: elevated module dumping, memory-image → file-aligned PE rebuild,
analysis-sized PE trimming, per-function "decrypt-on-execute" workflows.
- **Delphi-aware.** Most commercial RE targets in this space are Delphi; ih8Sn1ff maps
published-method RTTI `name → code RVA` in one call — the trick that turns a
500 MB mystery dump into a navigable program.
- **Live debugging without plugins.** Launch Windows targets (x64 or WOW64 x86)
under a built-in debugger, set software breakpoints, read registers and memory,
dump modules at a stop, and continue — as MCP calls or `ih8sn1ff dbg shell`
commands.
- **Deterministic and auditable.** Plain Python, no hidden services. Every tool
returns bounds-checked, explicitly-limited results (offsets, digests, counts).
It does not replace Ghidra — it orchestrates it. Deep static analysis stays in
Ghidra (headless scripts included). For dynamic work ih8Sn1ff ships its own x64
debugger for scripted sessions; x64dbg remains better for manual GUI exploring.
## RE field notes
> The file is a suggestion. Memory is the confession.
A loader is a promise; a dump is a receipt. When the two disagree, trust the
one that actually executed.
```text
on-disk image live memory analysis image
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ encrypted │ │ decrypted │ │ readable │
│ sections │ ───▶ │ modules │ ───▶ │ functions │
└──────────────┘ └──────────────┘ └──────────────┘
loader dump rebuild
```
Field notes:
- **Run it before you trust it.** The static view is a proposal; execution is the vote.
- **Strings lie. References rarely do.** Follow the pointer, not the marketing copy.
- **First execution decrypts more than any static pass.** Stimulate the feature, then dump again.
- **If it decrypted once, it will decrypt again.** Reproduce the inputs, not just the bytes.
- **Patch only what you can restore.** Keep a clean copy and a log of every byte you touch.
### Murphy's laws of reversing
- The function you need is always one xref deeper.
- Nothing is unreachable once you find the indirect call table.
- `halt_baddata` is not a suggestion; it is a dare.
- The bug is never in the compiler. Except that one time, and it was your code anyway.
- A stack trace is just the program admitting where it gave up.
- Every obfuscator is a love letter to the next analyst.
### Why "ih8sn1ff"?
The `ih8` prefix follows the author's handle `ih8w1nd`; `sn1ff` is for the part
of reversing that feels like packet sniffing: watching what a program actually
does instead of what it claims. The `1` is not negotiable.
## Install
```bash
pip install ih8sn1ff # core: capstone + pefile
pip install ih8sn1ff[elf] # + ELF metadata (pyelftools)
pip install ih8sn1ff[emu] # + Unicorn emulation
pip install ih8sn1ff[yara] # + YARA (bundled packer/anti-debug rules)
pip install ih8sn1ff[all] # everything optional
```
Until the package is published, install from a checkout:
```bash
pip install -e ".[dev,elf]"
```
External engines (optional, auto-detected):
| Engine | Enable with |
|---|---|
| Ghidra 12.x | `GHIDRA_INSTALL_DIR` pointing at the extracted release |
| .NET decompiler | `dotnet tool install -g ilspycmd` |
| x64dbg | optional manual sessions; the built-in x64 debugger needs no extra engine |
## MCP quickstart
Register the stdio server (Claude Code example, `.mcp.json`):
```json
{
"mcpServers": {
"ih8sn1ff": {
"command": "ih8sn1ff-mcp",
"env": { "GHIDRA_INSTALL_DIR": "C:/tools/ghidra_12.1.4_PUBLIC" }
}
}
}
```
Full setup for Claude Code, Claude Desktop, Cursor and uv lives in
[docs/MCP-SETUP.md](docs/MCP-SETUP.md). One-liner for Claude Code:
```bash
claude mcp add ih8sn1ff -e GHIDRA_INSTALL_DIR=C:/tools/ghidra_12.1.4_PUBLIC -- ih8sn1ff-mcp
```
Then ask the agent:
> Dump the modules of PID 7123, rebuild a file-aligned PE, trim it for analysis,
> map Delphi published methods, and decompile everything that references
> `KSTRINGB`.
## CLI quickstart
```bash
ih8sn1ff info sample.exe
ih8sn1ff strings sample.exe --regex "AT\\+" --min-len 6
ih8sn1ff entropy sample.exe --window 1M
ih8sn1ff dump 7123 --out dumps/ --include-main
ih8sn1ff rebuild dumps/00_main.exe.bin -o out/rebuilt.exe
ih8sn1ff trim out/rebuilt.exe -o out/trimmed.exe --scratch-prefix-end 0x1A00000
ih8sn1ff delphi out/main.bin --names-file names.txt
ih8sn1ff disasm out/main.bin --addr 0x163a454 --count 80
ih8sn1ff xrefs out/main.bin --string "KSTRINGB"
ih8sn1ff ghidra import out/trimmed.exe --project out/ghidra_proj
ih8sn1ff ghidra decompile out/ghidra_proj --rva 0x163a454 --rva 0x165103c
ih8sn1ff imports dumps/00_main.exe.bin -o out/rebuilt.exe --meta dumps/dump_meta.json
ih8sn1ff xrefs-rip out/trimmed.exe --string "KSTRINGB"
ih8sn1ff callgraph out/trimmed.exe --root 0x163a454 --depth 2
ih8sn1ff emulate out/trimmed.exe --entry 0x163a454 --max-instructions 500
ih8sn1ff dbg once C:/target/app.exe --dump out/entrydump
ih8sn1ff yara sample.exe
```
## Tools
See [docs/TOOLS.md](docs/TOOLS.md) for the full parameter/output reference.
Highlights:
| Tool | Purpose |
|---|---|
| `bin_info` | format, arch, sections, entropy, compiler/linker markers |
| `strings_scan` | ASCII/UTF-16 strings with offsets, regex, min length |
| `entropy_map` | windowed entropy to separate code/data/packed regions |
| `run_and_dump` | launch (elevated) and snapshot module images — the unpacking step |
| `dump_process` | dump modules of an already-running PID |
| `rebuild_pe` | memory image → file-aligned PE (Scylla-style unmap) |
| `trim_pe` | analysis-sized PE for Ghidra (code sections + VA prefix) |
| `delphi_methods` | published-method RTTI: `name → code RVA` |
| `disasm` | Capstone listing with inline string-ref annotations |
| `xrefs` | absolute-immediate xrefs to strings/values inside code ranges |
| `xrefs_rip` / `callgraph` | RIP-relative refs and direct-call graphs |
| `emulate` | bounded Unicorn trace at an entry RVA |
| `debug_launch` … `debug_close` | live Windows sessions (x64 or WOW64 x86): breakpoints, registers, memory, module dumps |
| `rebuild_imports` | IAT/import directory rebuild from `dump_meta.json` |
| `evidence_list` / `evidence_read` | journaled tool results with digests |
| `ghidra_import` | headless import + auto-analysis into a project |
| `ghidra_decompile` | decompile by RVA list or by string keywords |
| `dotnet_types` / `dotnet_type` | ILSpy type inventory / decompile |
| `yara_scan` / `yara_pack` | YARA scan; bundled packer/anti-debug rules by default |
## Workflows
`docs/WORKFLOWS.md` covers, step by step:
1. Unpacking VMProtect/Themida-class targets by **runtime dumping** (including the
per-function encryption wrinkle — features must execute before their code decrypts).
2. Rebuilding PEs from memory images and rebuilding the IAT from `dump_meta.json`.
3. Delphi app triage: RTTI method tables, unit/class inventories, DFM islands.
4. Ghidra headless decompilation driven by strings, not symbol names.
5. Live x64 debugging and bounded emulation for decrypt-on-execute targets.
6. When to stop scripting and switch to manual x64dbg / Frida.
## Who builds this?
**ih8w1nd** is a reverse engineer and toolmaker who treats "impossible" as a
scheduling problem. Has built firmware flashing and device-service systems from
protocol captures, turned packed binaries into readable code, and convinced
devices that "unsupported" was a temporary opinion. ih8Sn1ff exists because the
available tools were not fast, honest, or strange enough.
- GitHub: [@ih8w1nd](https://github.com/ih8w1nd)
- Track record: protocol captures turned into working flashing pipelines; packed binaries turned into readable code; "unsupported" devices turned into success logs.
- Approach: ask the binary politely, then open a debugger.
- House motto: *"The file is a suggestion. Memory is the confession."*
## Ethics and legal
ih8Sn1ff is a dual-use engineering toolkit for **authorized** reverse engineering:
malware analysis, interoperability, security research, CTFs, and software you own
or are licensed to inspect. Do not use it to bypass licensing, DRM, or access
controls on systems you do not own. The authors take no responsibility for misuse.
## Status
v0.3 — 35 MCP tools: runtime dump + PE/IAT rebuild, live debugger (x64 and
WOW64 x86), Unicorn emulation, Delphi RTTI, Ghidra headless, .NET, YARA,
evidence journal. The `ih8sn1ff` name was available on PyPI on 2026-10-19
(HTTP 404); publishing still needs the owner's token. Known limits: import
rebuild is experimental on heavily obfuscated/hooked IATs; VMProtect/Themida
devirtualization is not automated (the runtime-dump workflow is).
Contributions welcome; see `CONTRIBUTING.md`.
TDQS
Scored across 35 tools
Each tool targets a distinct analysis action or resource, from static metadata (bin_info) to dynamic debugging (debug_*), decompilation (ghidra_*), and evidence journaling (evidence_*). Overlaps like yara_scan vs yara_pack are explicitly aliases, and the dump variants are scoped by context (run_and_dump, dump_process, debug_dump).
All names use snake_case, but the patterns vary: verb_noun (rebuild_pe), noun_noun (strings_scan), single words (disasm), and prefixed groups (debug_*, ghidra_*, dotnet_*). The grouping is consistent within subsystems, making the set readable despite not following one uniform convention.
With 35 tools, the set far exceeds the typical 3–15 range and crosses into heavy territory. While many tools have distinct purposes, several could be consolidated (e.g., debug operations into an action parameter, Ghidra operations into fewer endpoints), making the surface overwhelming.
The server covers a broad reverse-engineering lifecycle: static analysis, PE manipulation, dynamic debugging, decompilation, .NET, YARA, and evidence tracking. Minor gaps exist, such as no debug_attach for existing processes or a dedicated import table viewer, but agents can work around them with available tools.