Debugging with GDB
GDB (GNU Debugger) is the central tool for dynamic analysis on Linux: it lets you run a program step by step, stop it at specific points (breakpoints), inspect and modify registers and memory, and see exactly what it does at each moment. For pwn and reversing it’s essential: with GDB you confirm offsets, see the stack/heap state, debug your exploits, and understand code that’s unreadable statically. Powered with pwndbg or GEF, it becomes an exploitation swiss-army knife.
Install the plugins (essential)
Section titled “Install the plugins (essential)”# bare GDB is awkward; pwndbg/GEF add exploit viewspwndbg github.com/pwndbg/pwndbg # register/stack/heap views, pwn commandsGEF github.com/hugsy/gef # a very complete alternative# after installing, GDB automatically shows useful context at each stopEssential commands
Section titled “Essential commands”# startgdb ./binary ; gdb -p <pid> # open binary / attach to processrun (r) [args] ; starti # run / stop at the 1st instruction# breakpointsbreak main (b main) ; b *0x401234 # stop at function / addressb *main+42 # offset inside a functioninfo breakpoints ; delete <n># executioncontinue (c) ; next (n) ; step (s) # continue / next line / step intonexti (ni) ; stepi (si) # next/step into at INSTRUCTION level (key in reversing)finish # run until the current function returns# inspectioninfo registers (i r) ; p $rip # registersx/20gx $rsp # examine memory (20 qwords in hex from RSP)x/s 0x404050 ; x/i $rip # as string / as instructiondisassemble (disas) func # disassembleExamine memory (x) — the key
Section titled “Examine memory (x) — the key”x/<count><format><size> address# format: x hex, d decimal, s string, i instruction, c char# size: b byte, h 2, w 4, g 8 (giant)x/20gx $rsp # 20 qwords in hex from the stack pointerx/s $rdi # the string pointed to by RDI (e.g. a function argument)x/5i $rip # the next 5 instructionsWorkflow for pwn
Section titled “Workflow for pwn”# confirm an overflow offsetb *vuln+X ; run < <(cyclic 200) # on crash: cyclic -l $rsp# see the state before a retb *func+ret_offset ; x/20gx $rsp# debug an exploit with pwntoolsfrom pwn import *p = gdb.debug('./vuln', 'b *main\nc') # launch with GDB attached and breakpoints# or: p = process('./vuln') ; gdb.attach(p, 'b *0x...')pwntools’ gdb.debug/gdb.attach integrate GDB with your exploit script: you develop the exploit seeing memory at each step.
Workflow for reversing
Section titled “Workflow for reversing”# follow logic that's hard to read staticallyb *check_function# step with ni/si watching registers and memory# see what it compares: the correct password appears in a register/memory before the cmp# modify live: set $rax = 1 (force a result), set {int}0x... = value# skip a check: change the flow with set $rip = ...GDB lets you modify the state live: change a register, a memory value, or RIP to skip checks and see what happens — very useful in crackmes.
Other utilities
Section titled “Other utilities”# watchpoints: stop when a variable/memory changeswatch *0x404050# conditions on breakpointsb func if $rdi == 0x1234# backtrace of the call stackbt# TUI (text interface) or just pwndbg/GEF's contextFor the defense (anti-debugging)
Section titled “For the defense (anti-debugging)”Malware and protected software detect GDB/debuggers (ptrace, timing, breakpoints) to hinder dynamic analysis — covered in rev-antidebug. The analyst bypasses them (patch the check, ptrace LD_PRELOAD, etc.).
Mastery checklist
Section titled “Mastery checklist”- Install pwndbg/GEF and understand the context they show
- Breakpoints by function, address, and offset
- Step-by-step execution (ni/si/finish/continue)
- Examine memory with x (formats and sizes)
- View and modify registers/memory/RIP live
- Confirm overflow offsets (cyclic)
- Integrate GDB with pwntools (gdb.debug/attach)
- Use watchpoints and conditional breakpoints