Dynamic Analysis for Reverse Engineering
Run and debug binaries to understand their behavior - GDB, strace, ltrace, and angr.
Dynamic Analysis for Reverse Engineering
Dynamic analysis runs the binary (in a safe environment) and observes its behavior. It complements static analysis — especially when code is obfuscated, packed, or when you need to see actual runtime values. The two most powerful dynamic techniques are ltrace (see library calls with arguments) and GDB breakpoints at comparison functions.
Always run unknown CTF binaries inside a VM. Never execute them on your host machine — even "safe" CTF binaries can be malicious.
Analysis Flow
Before You Run Anything
Set Up a Safe Environment
Always run in a VM — never on your host. Snapshot the VM before running anything.
Check Architecture & Dependencies
file ./challenge # architecture, 32/64-bit, linked?
ldd ./challenge # which libraries are needed?Optionally Disable ASLR
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
# Restore: echo 2 | sudo tee /proc/sys/kernel/randomize_va_spaceDisabling ASLR makes addresses predictable, so breakpoints at fixed addresses work every run.
Start with Lightweight Tools
Run strace and ltrace first — they often reveal the answer in seconds with no setup.
strace — System Call Tracer
strace intercepts all Linux syscalls. Great for understanding what files a binary reads and how it compares input.
strace ./challenge # basic trace
strace -e trace=file ./challenge # only file-related calls
strace -e trace=read,write ./challenge # read/write only
echo "test_input" | strace ./challenge # trace with inputCommon things to look for:
open("/flag.txt", ...) → binary reads a flag file
read(3, "flag{...}", ...) → flag is read into memory
write(1, "Wrong!\n", ...) → output indicates wrong inputltrace — Library Call Tracer
ltrace intercepts calls to shared library functions (libc). Excellent for crackmes.
ltrace ./challenge
# Common pattern: see strcmp with the expected password
# strcmp("your_input", "s3cr3t_p4ss") = -1ltrace is often the fastest solve for beginner crackmes. The second argument to strcmp or memcmp is usually the expected answer — it appears directly in the output.
GDB with GEF/PEDA/pwndbg
gdb ./challenge
# Breakpoints
(gdb) break main # breakpoint at main
(gdb) break *0x401234 # breakpoint at address
(gdb) break strcmp # breakpoint at libc strcmp
# Execution control
(gdb) run # run the binary
(gdb) run < input.txt # run with file as stdin
(gdb) next # step over
(gdb) step # step into
(gdb) continue # continue to next breakpoint
# Inspection
(gdb) info registers # show all registers
(gdb) x/20gx $rsp # examine stack (20 qwords)
(gdb) x/s $rdi # first arg as string
(gdb) x/s $rsi # second arg as string
# Modification
(gdb) set $rip = 0x401234 # change instruction pointer
(gdb) set $rax = 0 # force return valuePatching Binaries
gdb ./challenge
(gdb) break *0x401234
(gdb) run
(gdb) set $eax = 0 # force a comparison result
(gdb) jump *0x401256 # jump to a different addressRuntime patches don't modify the file on disk.
angr — Symbolic Execution
angr finds inputs that reach a desired state automatically. Great for crackmes with complex input validation.
import angr
proj = angr.Project('./crackme', auto_load_libs=False)
initial_state = proj.factory.entry_state()
simgr = proj.factory.simulation_manager(initial_state)
simgr.explore(find=0x4012a0, avoid=0x4012b5)
if simgr.found:
sol = simgr.found[0]
print(sol.posix.dumps(0)) # print stdin that reaches 'find'angr is most useful when input validation is complex (multiple loops, math, mixed comparisons). Find the "Correct!" address with strings -t x ./crackme | grep -i correct, then use that as find=.
Checklist
- Run in a VM (never on host)
-
ltrace— library calls, strcmp arguments often reveal password directly -
strace— check if binary opens a flag file, reads from a specific path - GDB: break at strcmp/memcmp →
x/s $rsishows expected value - GDB: break at comparison instructions → inspect registers
- Patch JNE→JMP or conditional to NOP if needed
- Use angr if input space is large and manual analysis is slow
Last updated on