GDB + Pwndbg Cheat Sheet
Guide to using pwndbg, a GDB plugin for exploit development, covering its enhanced commands for heap analysis, register display, and memory inspection.
Contents
- Starting GDB
- Execution Control
- Breakpoints
- Examining Memory (x command)
- Registers
- Key Registers for Exploitation
- Pwndbg-Specific Commands
- Debugging Exploitation Techniques
- Finding Buffer Overflow Offset
- Setting Up for Pwntools GDB Attach
- Examining the Stack Frame
- Verifying Exploit Payloads
- Tips & Tricks
- GDB Plugin Comparison
- References
GDB + Pwndbg Cheat Sheet
Sources: Pwndbg GitHub | Crypto-Cat CTF | HackTricks
Starting GDB
gdb-pwndbg ./binary # With pwndbg
gdb-peda ./binary # With PEDA
gdb-gef ./binary # With GEF
gdb ./binary # Vanilla GDB
gdb -q ./binary # Quiet mode (no banner)
gdb -p <PID> # Attach to running process
Execution Control
run # Start program
run < input.txt # Run with file as stdin
run $(python3 -c 'print("A"*100)') # Run with argument
continue (c) # Continue execution
nexti (ni) # Step one instruction (OVER calls)
stepi (si) # Step one instruction (INTO calls)
finish # Run until current function returns
until *0x401234 # Run until address
set $rip = 0x401234 # Jump to address (change EIP/RIP)
jump *main+525 # Jump directly to address
Breakpoints
break main # Break at function
break *0x8049123 # Break at exact address
break *main+42 # Break at offset into function
break *0x401234 if $rax == 0 # Conditional breakpoint
info breakpoints (info b) # List all breakpoints
delete 1 # Delete breakpoint #1
delete # Delete ALL breakpoints
disable 1 # Disable breakpoint #1
enable 1 # Enable breakpoint #1
tbreak *0x401234 # Temporary (hit once, auto-delete)
Examining Memory (x command)
Format: x/NFU address → N=count, F=format, U=unit size
# Formats: x=hex, d=decimal, s=string, i=instruction, c=char
# Units: b=byte, h=halfword(2), w=word(4), g=giant(8)
x/10i $rip # 10 instructions at RIP
x/20gx $rsp # 20 qwords (8-byte) hex at stack top
x/40wx $esp # 40 words (4-byte) hex at ESP (32-bit)
x/s 0x402000 # String at address
x/10s $rsp # 10 strings starting at RSP
x/20bx $rsp # 20 bytes hex at RSP
x/i $rip # Single instruction at RIP
x/50i main # Disassemble 50 instructions of main
Registers
info registers (info reg) # All general registers
info all-registers # ALL registers (including FP, SSE)
p $rax # Print single register
p/x $rax # Print in hex
p/d $rax # Print in decimal
p/t $rax # Print in binary
set $rax = 0x41414141 # Modify register value
set $rip = 0x401234 # Redirect execution
Key Registers for Exploitation
x86-64:
| Register | Purpose |
|---|---|
RIP | Instruction pointer (next instruction) |
RSP | Stack pointer (top of stack) |
RBP | Base pointer (stack frame base) |
RDI | 1st argument |
RSI | 2nd argument |
RDX | 3rd argument |
RCX | 4th argument |
R8 | 5th argument |
R9 | 6th argument |
RAX | Return value |
x86 (32-bit): Arguments are pushed on the stack right-to-left.
Pwndbg-Specific Commands
# Context display
context # Refresh full display
set context-sections all # Show everything
set context-sections regs,disasm,stack,backtrace
# Security
checksec # Show binary protections
# Memory map
vmmap # Memory mappings (like /proc/pid/maps)
vmmap libc # Find libc base address
# GOT / PLT
got # Display GOT entries (resolved addresses)
plt # Display PLT entries
# Stack
stack 30 # Show 30 stack entries
canary # Show stack canary value
retaddr # Show return address on stack
# Heap (critical for heap exploitation)
heap # Heap overview
vis_heap_chunks # Visual heap layout
bins # All bins (tcache, fast, unsorted, small, large)
tcachebins # Tcache bins specifically
fastbins # Fastbin entries
unsortedbin # Unsorted bin
smallbins # Small bins
largebins # Large bins
top_chunk # Top chunk info
malloc_chunk <addr> # Inspect specific chunk
# Search
search -s "/bin/sh" # Search for string in memory
search -p 0xdeadbeef # Search for pointer/value
search -s "flag{" . # Search in current binary only
# ROP
rop # Find ROP gadgets
rop --grep "pop rdi" # Filter ROP gadgets
# Cyclic pattern (for offset finding)
cyclic 200 # Generate pattern
cyclic -l 0x61616166 # Find offset from pattern value
Debugging Exploitation Techniques
Finding Buffer Overflow Offset
# Method 1: Pwndbg cyclic
pwndbg> cyclic 200 # Generate pattern
pwndbg> run # Paste pattern as input
# After crash:
pwndbg> cyclic -l $rsp # x64: look at RSP
pwndbg> cyclic -l $eip # x86: look at EIP
# Method 2: Manual
pwndbg> run <<< $(python3 -c 'print("A"*100 + "BBBB")')
# Check if EIP/RIP = 0x42424242
Setting Up for Pwntools GDB Attach
# In your exploit script:
io = gdb.debug('./binary', '''
break main
break *0x401234
continue
''')
Examining the Stack Frame
# After hitting breakpoint in vulnerable function:
info frame # Current frame info
backtrace (bt) # Full call stack
x/20gx $rbp-0x40 # Look at local variables
x/20gx $rsp # Look at stack from top
# Find distance from buffer to return address
p/d $rbp - <buffer_address> + 8 # +8 for saved RBP (x64)
Verifying Exploit Payloads
# Before function return:
x/gx $rbp+8 # Check what return address will be
x/10gx $rsp # After ret, check ROP chain on stack
# Check if shellcode landed correctly:
x/20i <shellcode_address> # Disassemble your shellcode
Tips & Tricks
# Follow the child in fork
set follow-fork-mode child
set detach-on-fork off
# Disable ASLR in GDB (default)
set disable-randomization on # Already default
# Continue on signals (useful for SIGSEGV analysis)
handle SIGSEGV nostop noprint pass
# Python in GDB
python print(hex(gdb.parse_and_eval("$rsp")))
# Log all output
set logging on
set logging file gdb.log
# Load symbols from separate file
symbol-file ./binary.debug
# Disassemble in Intel syntax
set disassembly-flavor intel
GDB Plugin Comparison
| Feature | Pwndbg | GEF | PEDA |
|---|---|---|---|
| Heap analysis | Excellent | Good | Basic |
| ROP search | Built-in | Built-in | Basic |
| Context display | Best | Good | Good |
| Heap visualization | vis_heap_chunks | heap bins | Limited |
| Active development | Very active | Active | Slow |
| Best for | Pwn/heap | General | Beginners |