Appendix G: GDB Command Reference
This appendix covers GDB commands used throughout this book, organized by task. All commands work with standard GDB; commands specific to the pwndbg plugin are marked (pwndbg).
GDB can be launched with: gdb ./binary or gdb -q ./binary (quiet mode, suppresses banner).
Starting and Controlling Execution
| Command |
Short |
Description |
run [args] |
r |
Start or restart the program |
run < input_file |
|
Run with stdin redirected from file |
start |
|
Run and break at main |
continue |
c |
Resume execution until next breakpoint |
next |
n |
Step over (execute one source line; don't enter calls) |
nexti |
ni |
Step over one machine instruction |
step |
s |
Step into (execute one source line; enter calls) |
stepi |
si |
Step into one machine instruction |
finish |
fin |
Run until current function returns |
until [addr] |
u |
Run until given address or end of loop |
jump addr |
j |
Jump to address (no frame setup) |
call func(args) |
|
Call a function in the inferior |
kill |
k |
Kill the running program |
quit |
q |
Exit GDB |
Breakpoints and Watchpoints
| Command |
Short |
Description |
break main |
b main |
Set breakpoint at function main |
break *0x401234 |
b *0x401234 |
Set breakpoint at address |
break file.c:42 |
|
Set breakpoint at source file/line |
break +5 |
|
Set breakpoint 5 instructions ahead |
tbreak location |
tb |
Temporary breakpoint (deleted after first hit) |
info breakpoints |
i b |
List all breakpoints |
delete 2 |
d 2 |
Delete breakpoint #2 |
delete |
d |
Delete all breakpoints (prompts) |
disable 2 |
|
Disable breakpoint #2 |
enable 2 |
|
Enable breakpoint #2 |
condition 2 rax==0 |
cond 2 rax==0 |
Add condition to breakpoint |
ignore 2 5 |
|
Ignore breakpoint #2 for next 5 hits |
watch *0xaddress |
|
Set watchpoint (break on memory write) |
rwatch *0xaddress |
|
Read watchpoint (break on read) |
awatch *0xaddress |
|
Access watchpoint (break on read or write) |
catch syscall write |
|
Break on write system call |
catch throw |
|
Break on C++ exception throw |
Examining Registers
| Command |
Short |
Description |
info registers |
i r |
Show all general-purpose registers |
info registers rax rbx |
i r rax rbx |
Show specific registers |
info all-registers |
i all-r |
Show all registers including SIMD |
print $rax` | `p $rax |
Print register value (decimal) |
|
print/x $rax` | `p/x $rax |
Print register value (hexadecimal) |
|
print/t $rflags` | `p/t $rflags |
Print in binary |
|
print/d $rax` | `p/d $rax |
Print as signed decimal |
|
set $rax = 0 |
|
Modify register value |
print $pc` | `p $pc |
Print instruction pointer |
|
print $sp` | `p $sp |
Print stack pointer |
|
pwndbg display: The pwndbg plugin automatically displays registers at each prompt with color-coding (changed registers highlighted in red).
Examining Memory
| Command |
Description |
x/10gx $rsp |
Examine 10 8-byte (giant) values from RSP, hex |
x/20wx 0x601000 |
Examine 20 4-byte words at address, hex |
x/s 0x402000 |
Examine string at address |
x/i $rip |
Disassemble one instruction at RIP |
x/10i $rip |
Disassemble 10 instructions from RIP |
x/10i main |
Disassemble 10 instructions from main |
x/b addr |
Examine one byte |
x/2gx $rbp |
Show saved RBP and return address |
print *(int*)0xaddress |
Dereference pointer as int |
print (char*)0xaddress |
Dereference as string |
| Letter |
Size |
Letter |
Format |
b |
byte (1) |
x |
hexadecimal |
h |
halfword (2) |
d |
decimal |
w |
word (4) |
u |
unsigned decimal |
g |
giant (8) |
o |
octal |
|
|
t |
binary |
|
|
f |
float |
|
|
s |
string |
|
|
i |
instruction |
|
|
c |
character |
Disassembly
| Command |
Description |
disassemble |
Disassemble current function |
disassemble main |
Disassemble function main |
disassemble *0x401000,+64 |
Disassemble 64 bytes from address |
disassemble /m main |
Disassemble with source lines interleaved |
disassemble /r main |
Disassemble with raw bytes shown |
set disassembly-flavor intel |
Switch to Intel syntax (recommended) |
set disassembly-flavor att |
Switch to AT&T syntax (default) |
layout asm |
Open TUI assembly view |
layout regs |
Open TUI register + assembly view |
layout src |
Open TUI source view |
Ctrl-X A |
Toggle TUI mode |
Stack Inspection
| Command |
Description |
backtrace |
bt — show call stack |
backtrace full |
Show call stack with local variables |
frame 2 |
f 2 — switch to frame #2 |
info frame |
Show details of current frame |
info locals |
Show local variables in current frame |
info args |
Show arguments in current frame |
x/20gx $rsp |
Show 20 stack entries (8 bytes each) |
x/2gx $rbp |
Show saved RBP and return address |
| Command |
Description |
info proc mappings |
Show memory map (like /proc/PID/maps) |
info files |
Show loaded files and sections |
info sharedlibrary |
Show loaded shared libraries |
info threads |
List all threads |
thread 2 |
Switch to thread #2 |
info address printf |
Show address of symbol |
info symbol 0x401234 |
Show symbol at address |
print &printf |
Print address of function |
maintenance info sections |
Show all ELF sections |
vmmap |
(pwndbg) Show memory map with permissions |
Symbols and Source
| Command |
Description |
list main |
Show source around main |
list 42 |
Show source around line 42 |
list file.c:42 |
Show specific file/line |
info functions |
List all functions |
info functions pattern |
List functions matching pattern |
info variables |
List all global variables |
demangle _Z3fooi |
Demangle a C++ symbol name |
whatis variable |
Show type of variable |
ptype struct_name |
Show structure layout |
set print pretty on |
Pretty-print structures |
Scripting and Automation
GDB supports Python scripting and a built-in scripting language.
Init File
Create ~/.gdbinit for persistent settings:
set disassembly-flavor intel
set pagination off
set print pretty on
set print array on
Simple Script
# In GDB or a .gdb file:
define hook-stop
x/5i $pc
x/8gx $rsp
end
Python Scripting
# Access from GDB: (gdb) python print(gdb.selected_frame().pc())
import gdb
class PrintStack(gdb.Command):
def __init__(self):
super().__init__("print-stack", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
sp = gdb.parse_and_eval("$rsp")
for i in range(8):
addr = int(sp) + i * 8
val = gdb.inferiors()[0].read_memory(addr, 8)
print(f"[RSP+{i*8:3d}] = {int.from_bytes(val, 'little'):#018x}")
PrintStack()
pwndbg-Specific Commands
| Command |
Description |
cyclic 100 |
Generate a 100-byte De Bruijn cyclic pattern |
cyclic -l 0x6161616b |
Find the offset of a pattern value |
checksec |
Show binary security mitigations |
vmmap |
Show memory map with rwx permissions |
heap |
Show heap state (glibc tcache, fastbins) |
bins |
Show free list bins |
got |
Show GOT entries and their current values |
plt |
Show PLT entries |
rop |
Find ROP gadgets in loaded binary |
search -s "string" |
Search memory for byte string |
search -x 0x90909090 |
Search memory for byte pattern |
telescope $rsp |
Show annotated stack (dereferences pointers) |
context |
Redisplay the context (registers, stack, disasm) |
canary |
Show the stack canary value |
aslr |
Show ASLR status |
procinfo |
Show process information |
Remote Debugging
Debug with GDB Server (typical for embedded or QEMU)
# On the target (or in QEMU):
gdbserver :1234 ./binary
# In GDB on the host:
(gdb) target remote localhost:1234
(gdb) continue
Debug Linux Kernel with QEMU
# QEMU with GDB stub:
qemu-system-x86_64 -kernel bzImage -append "nokaslr" -s -S
# In GDB:
(gdb) file vmlinux
(gdb) target remote :1234
(gdb) break start_kernel
(gdb) continue
Common Exploit Development Workflows
Find return address on stack
(gdb) break *main+offset # break at get_name or vulnerable function
(gdb) run
(gdb) x/20gx $rsp # examine stack: look for return address
(gdb) x/2gx $rbp # [rbp] = saved rbp, [rbp+8] = return address
Confirm overflow offset with cyclic pattern (pwndbg)
(gdb) cyclic 100
aaaaaaaabaaaaaaacaaaaa...
(gdb) run < <(cyclic 100) # pipe cyclic input to program
Program received signal SIGSEGV
RIP = 0x6161616162616161
(gdb) cyclic -l 0x6161616162616161
72
Find function address for ret2win
(gdb) info functions win
0x0000000000401160 win
(gdb) disassemble win
# verify it reads flag.txt
Examine canary value
(gdb) break *vulnerable_function+3 # just after canary read in prologue
(gdb) run
(gdb) x/gx $rbp-8 # show canary on stack
0x7fffffffe408: 0x4cd8b2e5f70a2300 # low byte is 0x00 (null byte)
(gdb) x/gx fs:0x28 # show TLS canary (should match)
Trace execution with SIGSEGV analysis
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a12345 in ?? ()
(gdb) x/i $rip # what instruction caused the fault?
(gdb) info registers # what register values?
(gdb) backtrace # what is the call chain?
(gdb) x/20gx $rsp # what is on the stack?
.gdbinit Template for Exploit Development
set disassembly-flavor intel
set pagination off
set follow-fork-mode child
define hook-stop
echo \n[Registers]\n
info registers rax rbx rcx rdx rsi rdi rsp rbp rip
echo \n[Stack]\n
x/10gx $rsp
echo \n[Instructions]\n
x/5i $rip
end