Tools · CTF categories for beginners · 12 / 18
GDB basics for CTF reversing: breakpoints, registers, memory, and stepping
Run a practice binary under gdb, set breakpoints on functions and addresses, inspect registers and memory, and step through a comparison to watch values change.
Core commands
break sets breakpoints by function or address, run starts the program, continue resumes, stepi and nexti step one instruction, info registers shows registers, and x examines memory, as in x/s for a string or x/8gx for eight 64-bit values. disassemble shows the current function. Extensions such as GEF or pwndbg show registers, stack, and code together after each step.
gdb -q ./crackme (gdb) break main (gdb) run (gdb) disassemble (gdb) break strcmp (gdb) continue (gdb) info registers rdi rsi (gdb) x/s $rdi (gdb) x/s $rsi (gdb) finish (gdb) print $rax
Calling convention reminder
On x86-64 Linux, the first function arguments go in rdi, rsi, rdx, rcx, r8, and r9, and the return value comes back in rax. So at a breakpoint on strcmp, the two strings being compared are at the addresses in rdi and rsi.
Lab: watch the key appear
Use the crackme from the first reversing lesson. Break on strcmp, run, type any input, and examine both arguments with x/s: one is your input, the other is the expected key. Then try the XOR version: set a breakpoint inside the loop at the compare instruction you found in Ghidra, and print the register holding the expected byte on each iteration with a breakpoint command list.
(gdb) break *main+142 (gdb) commands > silent > printf "%c", $al > continue > end (gdb) run <<< 'AAAAAAAAAAAA'
Tips
Use starti to stop at the very first instruction when main is hard to find. Set disable-randomization on (the default in gdb) to keep addresses stable while learning. Save useful commands in a .gdbinit file in the challenge folder, and only load .gdbinit files you wrote yourself.
Diagram
Debugging a comparison
- Break
Set a breakpoint on the compare function or instruction.
- Run
Supply test input.
- Inspect
Read arguments in rdi and rsi, or the compared register.
- Step and confirm
finish or stepi; check rax for the result.
Check yourself
1. On x86-64 Linux, which registers hold the first two function arguments?
2. Which gdb command prints memory at an address as a string?
3. Where is a function’s return value after it finishes?