reverse-engineering
Binary reverse engineering with static and dynamic analysis across all platforms
You are a reverse engineering specialist. Analyze binaries through static and dynamic methods across PE, ELF, and Mach-O formats.
Binary Format Identification
file binary # Identify format and architecture
strings binary # Extract readable strings
strings -n 6 binary # Strings with minimum length 6
strings -e l binary # Unicode/UTF-16 strings
xxd binary | head -50 # Hex dump of header
Format Signatures
| Format | Magic Bytes | Tooling |
|--------|------------|---------|
| PE (Windows) | MZ (4D 5A) | Ghidra, IDA, x64dbg, PE-bear |
| ELF (Linux) | \x7fELF | Ghidra, IDA, radare2, GDB |
| Mach-O (macOS) | FE ED FA CE / CE FA ED FE | Ghidra, IDA, Hopper, LLDB |
| Universal binary | CA FE BA BE (Fat binary) | lipo, Ghidra |
| .NET | MZ + metadata | dnSpy, ILSpy, dotPeek |
| Java class | CA FE BA BE | jadx, procyon, CFR |
Static Analysis
Header Inspection
# ELF
readelf -h binary # ELF header
readelf -S binary # Section headers
readelf -l binary # Program headers (segments)
readelf -s binary # Symbol table
readelf -r binary # Relocations
objdump -d binary # Disassembly
objdump -t binary # Symbol table
# PE
pev binary # PE information
pe -a binary # All PE info
pe -s binary # Sections
pe -i binary # Import table
pe -e binary # Export table
# Mach-O
otool -f binary # Fat binary info
otool -l binary # Load commands
otool -t binary # Text section
nm binary # Symbols
nm -u binary # Undefined (imported) symbols
Symbol Recovery
# Stripped binary detection
file binary # "stripped" in output
nm binary # "no symbols" if stripped
# FLIRT signatures (Ghidra/IDA)
# Apply standard library signatures to recover function names
# Demangling
c++filt _ZN7MyClass8myMethodEv # Demangle C++ names
swift demangle $SYMBOL # Demangle Swift names
Disassembly vs Decompilation
| Tool | Disassembly | Decompilation | Scripting | |------|-------------|---------------|-----------| | Ghidra | Yes | Yes (C) | Java, Python (Jython) | | IDA Pro | Yes | Yes (C, via Hex-Rays) | IDC, IDAPython | | Binary Ninja | Yes | Yes (C/BNIL) | Python, Rust, C++ | | radare2 / rizin | Yes | Yes (C via r2dec) | r2pipe, Python | | Hopper (macOS) | Yes | Yes (C/pseudo-code) | Python |
Dynamic Analysis
Debugging
# GDB
gdb -q binary
(gdb) info functions # List functions
(gdb) break main # Set breakpoint
(gdb) run arg1 arg2 # Run with args
(gdb) info registers # Register state
(gdb) x/10i $rip # Examine instructions
(gdb) x/s 0x7fffffff... # Examine string
(gdb) continue / stepi / nexti # Execution control
(gdb) backtrace # Call stack
# GDB with pwndbg/peda/gef extensions
pip install pwndbg # Modern GDB enhancement
# LLDB (macOS)
lldb binary
(lldb) breakpoint set --name main
(lldb) run
(lldb) register read
(lldb) disassemble --frame
Tracing
strace -o syscalls.log ./binary # System call tracing
strace -e trace=open,read ./binary # Filter specific syscalls
ltrace ./binary # Library call tracing
ltrace -e malloc+free ./binary # Filter specific lib calls
# Sysdig (container-aware tracing)
sysdig -c topprocs_cpu # Process CPU usage
sysdig proc.name=binary # Filter by process
Frida (Dynamic Instrumentation)
# frida-trace: auto-generate hooks
frida-trace -i "recv" ./binary # Hook recv function
# Custom hook script (JavaScript)
# hook.js
Interceptor.attach(Module.findExportByName(null, "strcmp"), {
onEnter: function(args) {
console.log("strcmp(" + args[0].readCString() + ", " + args[1].readCString() + ")");
},
onLeave: function(retval) {
console.log(" returned: " + retval);
}
});
frida ./binary -l hook.js # Run with hook
frida -p PID -l hook.js # Attach to running process
# Frida Python bindings
import frida
session = frida.attach("target")
script = session.create_script("""...""")
script.load()
Symbolic Execution (angr)
import angr
# Load binary
proj = angr.Project("binary", auto_load_libs=False)
# Get CFG
cfg = proj.analyses.CFGFast()
# Symbolic execution to find path to target
state = proj.factory.entry_state()
simgr = proj.factory.simulation_manager(state)
simgr.explore(find=0x400000, avoid=0x400010) # Addresses
if simgr.found:
found = simgr.found[0]
print(found.solver.eval(proj.arch.registers['rax']))
Anti-Analysis Bypass
Anti-Debug
# ptrace detection: tracee can only be traced by one tracer
# Solution: LD_PRELOAD wrapper that returns 0 for ptrace
# Timing checks: is_debugger_present()
# Solution: NOP out the check or patch the comparison
# /proc/self/status TracerPid check (Linux)
# Solution: LD_PRELOAD to intercept fopen/fread on /proc
Anti-VM
# Hypervisor bit check (CPUID)
# MAC address prefix check (00:05:69, 00:0C:29, 00:50:56 for VMware)
# Registry keys (HKLM\HARDWARE\DEVICEMAP\Scsi\)
# Solution: patch the checks or use VM escape
Obfuscation
# Control flow flattening: switch-case dispatch (deobfuscate with angr/triton)
# Opaque predicates: always-true/false conditions (simplify with SMT solver)
# String encryption: XOR/RC4 encoded strings (extract decryptor, run in emulator)
# JMP/CALL obfuscation: push/ret, call/pop (normalize with re-assembler)
Patching
# radare2 patch
r2 -w binary
> s 0x1234 # Seek to address
> wa nop # Write NOP instruction
> wc 0x90 # Write bytes
> q # Quit
# Ghidra patching
# Right-click instruction -> Patch Instruction
# Export -> Original File -> Apply patches
# Binary diffing (for patch analysis)
# Ghidra: File -> Export -> Export as .gzf (Ghidra Zip File)
# Diaphora: IDA plugin for binary diffing
Common RE Workflows
Malware Analysis
- Extract sample (password-protected archive or sandbox)
- Run
stringsandfilefor quick triage - Check entropy (packed? use
binwalk -Eorent) - Unpack with generic unpackers or manual OEP find
- Load in Ghidra/IDA, identify imports, trace execution
- Set up Frida hooks on network/registry/file APIs
- Document IoCs, C2 addresses, capabilities
Vulnerability Research
- Fuzz target (AFL++, libFuzzer, Honggfuzz)
- Triage crash (unique via
!exploitable/analyze.py) - Root cause analysis in debugger
- Exploit primitive identification (control of RIP, SEH, type confusion)
- ASLR/DEP bypass analysis
- Exploit development and testing
Protocol Reverse Engineering
- Capture traffic with tcpdump/Wireshark
- Use Frida to hook send/recv functions
- Identify message framing (length prefix, magic bytes)
- Reconstruct protocol structure
- Write dissector for Wireshark (Lua/C)