GDB Demo
Tools used
GDB intro
- make sure you compile with debug symbols:
-g
gcc -g demo.c -o demo
-
gdb basics:
- run
- layout src - open TUI to view source code
- backtrace
- we can reach a function from multiple codepaths, but only one leads to our bug
- breakpoint
- watch
- next instr
- step into next instr
- continue
help
- the man of gdb
-
gdb basics++:
- disassemble
- info breakpoint
- delete breakpoint
- tbreak - temporary breakpoint
- start - equivalent to tbreak at main entrypoint
- finish - execute until selected stack frame returns
- set CLI arguments
set args <arg1> <arg2> ... <argN>
- set and use variables
set $i = 0 print $i++
- useful to print array elements
print v[$i++]
GDB power user
-
.gdbinit
- a config file for gdb
- read when gdb starts
- why it matters?
- gdb is scriptable
- we can place gdb commands in .gdbinit to save time
- demo
- a .gdbinit per project
- add
add-auto-load-safe-path .
to ~/.gdbinit
- add
- view library code
- enter Text User Interface (TUI) mode -
Ctrl+x+a
(toggle TUI mode)step into printf, toggle TUI, get missing source file error
- install libc6-dbg
show directories
- where gdb looks for source files. Instruct to look inside libc'sstdio
pathset directories
in .gdbinit
- enter Text User Interface (TUI) mode -
-
pwndbg
- a gdb plugin that enhances the user experience
- discuss displayed sections
- registers, disasm, code, stack, backtrace
- configure your display: as per docs, use
config
command - use
set <config-var> <config-value>
to modify config- ex.
set context-sections 'regs disasm stack'
- place it in your
.gdbinit
- ex.
-
gdbserver
- gdb remote debugging
- useful to debug remote programs
- on VMs
- on embedded systems with constrained resources: gdb won't fit on the embedded device -> gdbserver is a lot smaller
- on remote (target) machine
gdbserver localhost:4444 program
- on host machine, connect to target and start debugging
# start gdb in quiet mode $ gdb -q target remote <remote-addr>:4444
-
variables++
- access registers -
print $rip
- hijack control flow
set $rip = addr set $rax = value
- access registers -