Loading...
Loading...
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.
npx skill4agent add mohitmishra786/low-level-dev-skills reverse-engineeringstringsfilexxdfile 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 |
|---|---|
| Architecture, static/dynamic, stripped |
| URLs, paths, error messages, keys |
| Symbol table (if not stripped) |
| Dynamic symbols |
| RELRO, NX, PIE, canary |
# Headless analysis
analyzeHeadless /tmp/ghidra_projects MyProject \
-import suspicious_binary \
-postScript ExportDecompile.java
# GUI: File → New Project → Import File → Analyze (Yes)FLCtrl+Shift+F// 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())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[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# 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)// 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 | |
| RAII | paired ctor/dtor calls, exception landing pads |
| Templates | Mangled names |
| std::string | SSO buffer inline or heap pointer at offset 0 |
# Demangle C++ symbols
c++filt _ZN4Math3addEii# 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 decompilermainsyscall# 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) | headBinary 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| Symptom | Cause | Fix |
|---|---|---|
| Ghidra decompiler fails | Indirect jumps, bad types | Fix function signature; define struct |
| r2 analysis incomplete | Large binary | |
| Wrong architecture | ARM vs Thumb, MIPS | Set |
| Anti-debug trap | ptrace check | Patch or use |
| Packed binary | UPX/etc. | |
| No xrefs to string | PIE/RELRO | Follow GOT; runtime analysis |
skills/binaries/elf-inspectionskills/debuggers/gdbskills/runtimes/binary-hardeningskills/security/kernel-securityskills/low-level-programming/assembly-x86skills/low-level-programming/assembly-arm