/reverse-engineering
Reverse engineering skill for binary analysis. Use when decompiling with Ghidra, analyzing with radare2, scripting RE tools, triaging with strings/file/xxd, or diffing binaries. Activates on queries about Ghidra, radare2, r2, decompiler, Binary Ninja, Diaphora, or stripped
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill reverse-engineering --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/reverse-engineering
Context preview
The summary Claude sees to decide when to auto-load this skill.
Reverse engineering skill for binary analysis. Use when decompiling with Ghidra, analyzing with radare2, scripting RE tools, triaging with strings/file/xxd, or diffing binaries. Activates on queries about Ghidra, radare2, r2, decompiler, Binary Ninja, Diaphora, or stripped
SKILL.md
reverse-engineering.SKILL.mdname: reverse-engineering
description: Reverse engineering skill for binary analysis. Use when decompiling with Ghidra, analyzing with radare2, scripting RE tools, triaging with strings/file/xxd, or diffing binaries. Activates on queries about Ghidra, radare2, r2, decompiler, Binary Ninja, Diaphora, or stripped binary analysis.
Reverse Engineering
Purpose
Guide agents through reverse engineering binaries: Ghidra project setup and decompilation, radare2 analysis workflow, Binary Ninja scripting, initial triage with `strings`/`file`/`xxd`, identifying C++ patterns (vtables, RAII), analyzing stripped binaries, and diffing with Diaphora or BinDiff.
When to Use
- Analyzing an unknown binary without source code
- Recovering algorithm logic from compiled executables
- Comparing two firmware versions for vulnerability patches
- Understanding malware or CTF challenge binaries
- Recovering symbols from stripped ELF/PE files
- Automating analysis with Ghidra or r2 scripts
Workflow
1. Initial triage
file suspicious_binary
strings -n 8 suspicious_binary | head -50
strings -el suspicious_binary # UTF-16 LE
xxd suspicious_binary | head -20
readelf -h suspicious_binary # ELF
objdump -d -M intel suspicious_binary | head -40
# Check protections
checksec --file=suspicious_binary
| Command | Reveals | |---------|---------| | `file` | Architecture, static/dynamic, stripped | | `strings` | URLs, paths, error messages, keys | | `readelf -s` | Symbol table (if not stripped) | | `nm -D` | Dynamic symbols | | `checksec` | RELRO, NX, PIE, canary |
2. Ghidra workflow
# Headless analysis
analyzeHeadless /tmp/ghidra_projects MyProject \
-import suspicious_binary \
-postScript ExportDecompile.java
# GUI: File → New Project → Import File → Analyze (Yes)
Key steps: 1. **Auto-analysis** — let Ghidra complete disassembly 2. **Define functions** — `F` at entry points if missed 3. **Decompiler** — Window → Decompiler (C-like output) 4. **Rename** — `L` on variables/functions for clarity 5. **Cross-references** — `Ctrl+Shift+F` on function/data
// Ghidra script (Java) — list functions > 100 bytes
import ghidra.program.model.listing.*;
FunctionManager fm = currentProgram.getFunctionManager();
for (Function f : fm.getFunctions(true)) {
if (f.getBody().getNumAddresses() > 100)
println(f.getName() + " @ " + f.getEntryPoint());
}# Ghidra Python (Jython)
from ghidra.program.model.listing import FunctionManager
fm = currentProgram.getFunctionManager()
for f in fm.getFunctions(True):
print(f.getName(), f.getEntryPoint())3. radare2 workflow
r2 suspicious_binary
[0x00001000]> aaa # analyze all
[0x00001000]> afl # list functions
[0x00001000]> pdf @ main # disassemble function
[0x00001000]> VV # visual graph mode
[0x00001000]> iz # strings in data sections
[0x00001000]> s sym.main; pdf
Patching:
[0x00001000]> wx 9090 @ 0x401234 # write NOPs
[0x00001000]> wci 0x401234 # insert instruction
[0x00001000]> wt modified_binary
# r2 scripting
r2 -qc 'aaa; afl' suspicious_binary
r2 -i analysis.r2 suspicious_binary
4. Binary Ninja scripting
# BN Python API
import binaryninja as bn
bv = bn.load("suspicious_binary")
for func in bv.functions:
if func.name.startswith("sub_"):
hlil = func.hlil
for block in hlil:
print(block)5. C++ pattern recognition
// Vtable pattern in disassembly
// mov rax, [rdi] ; load vtable pointer
// call [rax+0x10] ; virtual call at offset
// Constructor pattern
// mov [obj], offset vtable
| Pattern | Indicator | |---------|-----------| | Vtable | `.data.rel.ro` section, array of function pointers | | RAII | paired ctor/dtor calls, exception landing pads | | Templates | Mangled names `_Z...`, duplicate logic per type | | std::string | SSO buffer inline or heap pointer at offset 0 |
# Demangle C++ symbols
c++filt _ZN4Math3addEii
6. Stripped binary recovery
# Find main via __libc_start_main
readelf -s binary | grep -E 'main|start'
# Or r2: afl~entry
# FLIRT signatures (Ghidra/BN) — match libc patterns
# Stack string analysis in Ghidra decompiler
Strategies:
- Identify `main` via libc init or entry point
- Find syscalls (`syscall` insn on Linux)
- String xref to locate error handlers
- Entropy analysis for encrypted sections
7. Binary diffing
# Diaphora (Ghidra/IDA plugin)
# Export from both binaries, run diff
# BinDiff (commercial, IDA/Ghidra)
bindiff old.i64 new.i64
# Simple hash diff
sha256sum firmware_v1 firmware_v2
diff <(objdump -d v1) <(objdump -d v2) | head
Use diffing to find patched vulnerability functions after updates.
8. RE decision tree
Binary type?
├── ELF/Linux → Ghidra + r2 + readelf
├── PE/Windows → Ghidra + PE-bear + x64dbg reference
├── Firmware → binwalk extract → Ghidra on architecture
└── Obfuscated → dynamic analysis (gdb/ltrace) first
Common Problems
| Symptom | Cause | Fix | |---------|-------|-----| | Ghidra decompiler fails | Indirect jumps, bad types | Fix function signature; define struct | | r2 analysis incomplete | Large binary | `aaa` then `aac` ; increase analysis depth | | Wrong architecture | ARM vs Thumb, MIPS | Set `-a arm` or correct Ghidra language | | Anti-debug trap | ptrace check | Patch or use `-gdb` in QEMU | | Packed binary | UPX/etc. | `upx -d` or manual unpack | | No xrefs to string | PIE/RELRO | Follow GOT; runtime analysis |
Related Skills
- `skills/binaries/elf-inspection` — ELF structure analysis
- `skills/debuggers/gdb` — dynamic analysis complement
- `skills/runtimes/binary-hardening` — understanding mitigations being bypassed
- `skills/security/kernel-security` — kernel RE and CVE analysis
- `skills/low-level-programming/assembly-x86` — reading disassembly
- `skills/low-level-programming
Read more
name: reverse-engineering description: Reverse engineering skill for binary analysis. Use when decompiling with Ghidra, analyzing with radare2, scripting RE tools, triaging with strings/file/xxd, or diffing binaries. Activates on queries about Ghidra, radare2, r2, decompiler, Binary Ninja, Diaphora, or stripped binary analysis.
Reverse Engineering
Purpose
Guide agents through reverse engineering binaries: Ghidra project setup and decompilation, radare2 analysis workflow, Binary Ninja scripting, initial triage with `strings`/`file`/`xxd`, identifying C++ patterns (vtables, RAII), analyzing stripped binaries, and diffing with Diaphora or BinDiff.
When to Use
- Analyzing an unknown binary without source code
- Recovering algorithm logic from compiled executables
- Comparing two firmware versions for vulnerability patches
- Understanding malware or CTF challenge binaries
- Recovering symbols from stripped ELF/PE files
- Automating analysis with Ghidra or r2 scripts
Workflow
1. Initial triage
file suspicious_binary strings -n 8 suspicious_binary | head -50 strings -el suspicious_binary # UTF-16 LE xxd suspicious_binary | head -20 readelf -h suspicious_binary # ELF objdump -d -M intel suspicious_binary | head -40 # Check protections checksec --file=suspicious_binary
| Command | Reveals | |---------|---------| | `file` | Architecture, static/dynamic, stripped | | `strings` | URLs, paths, error messages, keys | | `readelf -s` | Symbol table (if not stripped) | | `nm -D` | Dynamic symbols | | `checksec` | RELRO, NX, PIE, canary |
2. Ghidra workflow
# Headless analysis analyzeHeadless /tmp/ghidra_projects MyProject \ -import suspicious_binary \ -postScript ExportDecompile.java # GUI: File → New Project → Import File → Analyze (Yes)
Key steps: 1. **Auto-analysis** — let Ghidra complete disassembly 2. **Define functions** — `F` at entry points if missed 3. **Decompiler** — Window → Decompiler (C-like output) 4. **Rename** — `L` on variables/functions for clarity 5. **Cross-references** — `Ctrl+Shift+F` on function/data
// Ghidra script (Java) — list functions > 100 bytes
import ghidra.program.model.listing.*;
FunctionManager fm = currentProgram.getFunctionManager();
for (Function f : fm.getFunctions(true)) {
if (f.getBody().getNumAddresses() > 100)
println(f.getName() + " @ " + f.getEntryPoint());
}# Ghidra Python (Jython)
from ghidra.program.model.listing import FunctionManager
fm = currentProgram.getFunctionManager()
for f in fm.getFunctions(True):
print(f.getName(), f.getEntryPoint())3. radare2 workflow
r2 suspicious_binary
[0x00001000]> aaa # analyze all [0x00001000]> afl # list functions [0x00001000]> pdf @ main # disassemble function [0x00001000]> VV # visual graph mode [0x00001000]> iz # strings in data sections [0x00001000]> s sym.main; pdf
Patching:
[0x00001000]> wx 9090 @ 0x401234 # write NOPs [0x00001000]> wci 0x401234 # insert instruction [0x00001000]> wt modified_binary
# r2 scripting r2 -qc 'aaa; afl' suspicious_binary r2 -i analysis.r2 suspicious_binary
4. Binary Ninja scripting
# BN Python API
import binaryninja as bn
bv = bn.load("suspicious_binary")
for func in bv.functions:
if func.name.startswith("sub_"):
hlil = func.hlil
for block in hlil:
print(block)5. C++ pattern recognition
// Vtable pattern in disassembly // mov rax, [rdi] ; load vtable pointer // call [rax+0x10] ; virtual call at offset // Constructor pattern // mov [obj], offset vtable
| Pattern | Indicator | |---------|-----------| | Vtable | `.data.rel.ro` section, array of function pointers | | RAII | paired ctor/dtor calls, exception landing pads | | Templates | Mangled names `_Z...`, duplicate logic per type | | std::string | SSO buffer inline or heap pointer at offset 0 |
# Demangle C++ symbols c++filt _ZN4Math3addEii
6. Stripped binary recovery
# Find main via __libc_start_main readelf -s binary | grep -E 'main|start' # Or r2: afl~entry # FLIRT signatures (Ghidra/BN) — match libc patterns # Stack string analysis in Ghidra decompiler
Strategies:
- Identify `main` via libc init or entry point
- Find syscalls (`syscall` insn on Linux)
- String xref to locate error handlers
- Entropy analysis for encrypted sections
7. Binary diffing
# Diaphora (Ghidra/IDA plugin) # Export from both binaries, run diff # BinDiff (commercial, IDA/Ghidra) bindiff old.i64 new.i64 # Simple hash diff sha256sum firmware_v1 firmware_v2 diff <(objdump -d v1) <(objdump -d v2) | head
Use diffing to find patched vulnerability functions after updates.
8. RE decision tree
Binary type? ├── ELF/Linux → Ghidra + r2 + readelf ├── PE/Windows → Ghidra + PE-bear + x64dbg reference ├── Firmware → binwalk extract → Ghidra on architecture └── Obfuscated → dynamic analysis (gdb/ltrace) first
Common Problems
| Symptom | Cause | Fix | |---------|-------|-----| | Ghidra decompiler fails | Indirect jumps, bad types | Fix function signature; define struct | | r2 analysis incomplete | Large binary | `aaa` then `aac` ; increase analysis depth | | Wrong architecture | ARM vs Thumb, MIPS | Set `-a arm` or correct Ghidra language | | Anti-debug trap | ptrace check | Patch or use `-gdb` in QEMU | | Packed binary | UPX/etc. | `upx -d` or manual unpack | | No xrefs to string | PIE/RELRO | Follow GOT; runtime analysis |
Related Skills
- `skills/binaries/elf-inspection` — ELF structure analysis
- `skills/debuggers/gdb` — dynamic analysis complement
- `skills/runtimes/binary-hardening` — understanding mitigations being bypassed
- `skills/security/kernel-security` — kernel RE and CVE analysis
- `skills/low-level-programming/assembly-x86` — reading disassembly
- `skills/low-level-programming
A curated suite of AI agent skills for systems and low-level programming — C/C++, Rust, Zig, GPU, bare-metal firmware, Linux kernel/driver development, computer architecture, compiler internals, HPC, and more.
Repo: mohitmishra786/low-level-dev-skills
Other skills on low-level-dev-skills.
- /custom-allocators
Custom allocator skill for memory allocation strategies. Use when implementing pool/slab/arena allocators, tuning jemalloc/mimalloc, writing Rust GlobalAlloc, or benchmarking allocator performance. Activates on queries about jemalloc, mimalloc, tcmalloc, arena allocator,
Open skill - /numa-programming
NUMA programming skill for multi-socket memory locality. Use when detecting NUMA topology, binding processes with numactl, using libnuma API, building NUMA-aware data structures, or measuring remote access penalties. Activates on queries about numactl, libnuma, NUMA topology,
Open skill - /af-xdp
AF_XDP skill for high-performance XDP sockets. Use when creating AF_XDP sockets, configuring UMEM and XSK rings, XDP_REDIRECT programs, copy vs zero-copy mode, or comparing with DPDK. Activates on queries about AF_XDP, xsk_umem, XDP_REDIRECT, libbpf xsk, or zero-copy XDP.
Open skill - /dpdk
DPDK skill for userspace packet I/O. Use when initializing EAL, configuring PMD drivers, using mbuf pools and rte_ring, setting up huge pages, RSS, or testpmd validation. Activates on queries about DPDK, EAL, rte_eth_rx_burst, hugepages, PMD, or testpmd.
Open skill - /io-uring
io_uring skill for Linux async I/O. Use when building high-performance servers with liburing, multi-shot operations, provided buffers, fixed files, zero-copy send, or tokio-uring. Activates on queries about io_uring, SQE/CQE, liburing, IORING_OP_PROVIDE_BUFFERS, or io_uring vs
Open skill - /adc-dac-baremetal
Bare-metal ADC and DAC skill. Use when configuring analog sampling, DMA-driven ADC, calibration, or DAC output on MCUs. Activates on queries about ADC bare-metal, sampling time, DMA ADC, or DAC channel setup.
Open skill

