Below is a smattering of gdb hints, tips, and tricks. Some might even be useful during this course. If you’d like to contribute to this cheatsheet, let me know! The course shell server loads GEF by default, which makes GDB friendlier for exploit development and binary analysis. If you build your own local environment later, install GEF if you want the same commands and output shown in class.
Arguments:
- Use
gdb -ex COMMANDto start GDB and execute the givenCOMMAND.For example,gdb -ex rwill load the binary in gdb and then execute the run command. - Use
gdb --pid <pid>to attach to a running process
Basics:
- Use “-g” when compiling with GCC to enable debug symbols, providing more information to GDB.
- To switch to Intel syntax:
set disassembly-flavor intel - Use
set {int}0x8049700=0xdeadbeefto write the value 0xdeadbeef to address 0x8049700. - Remember you can use
int3in your shellcode (op code0xcc) to cause a breakpoint. - Execute shell commands, e.g.,
shell clearwill clear the screen. - Use the
dircommand to specify the local directory containing the source files.
GEF quick reference:
contextredraws the GEF register, stack, code, and backtrace panes.checksecshows binary protections such as NX, PIE, RELRO, and stack canaries. You can also runchecksec ./binarybefore starting the program.vmmapshows the process memory map and page permissions.xinfo <address>explains where an address lives and what permissions that page has. Registers work here too, e.g.,xinfo $rsp.pattern create <length>creates a cyclic pattern for finding overwrite offsets, andpattern search <value>finds the matching offset.search-pattern <value>searches process memory for a value or address.
Running the binary:
runandrwill run the current program.killwill kill the current program.- Reload the binary:
file foo, useful if you pop a shell withexecvfrom inside of gdb. - Run the current program with input from a file:
r < input.in - Run the current program with command line args:
r foo bar - Or run with arbitrary arguments:
r < <(python exploit.py)
Working with breakpoints:
- Setting by function symbol:
break *mainorb *main. - Setting by source code function:
break main - By offset in function:
b *main+10 - By address:
break *0x400D02 - By line number in file:
break foo.c:12 - List current break points:
info break delete <num>deletes a breakpoint by numbercleardelete all breakpointsenable <num>enables a breakpoint by numberdisable <num>disables a breakpoint by number
Stepping:
siwill step instruction by instruction going into function calls whereasniwill step over function calls.stepwill execute until the next source line, going into function calls.nextwill execute until the next source line, not going into functions.finishwill execute until the current function returnscontinuewill continue normal execution.- Be careful though,
siandniseem to skip overint3instructions. f 4will jump to the fourth stack frame. This is useful when an error occurs within a library function and you’d like to see what arguments were passed from the calling function(s).
Working with the heap:
heap chunks(gef only) will give a list of the current heap chunks.heap bins(gef only) will summarize the current state of all heap bins.
Working with registers:
- Getting values:
info registersori r - Setting values:
set $eax=0
Getting information:
info functionsdisassemble mainordisass mainto disassemble a function.- This command will disassemble the function that contains the instruction at
address 0x08…
disassemble 0x08... aslrwill tell you if ASLR is enabled from GDB’s perspective. Note that the output may be different before running the binary. You can disable ASLR withaslr off.- Use
vmmapto view memory regions and permissions. - View the mapped address space:
info proc mappings - Print out the string representation of the bytes at a given address:
x/s 0x4005d0 - Print out a word of memory relative to the stack pointer:
x/wx $esp+0x5c x foowill give you the location of functionfoo.p systemwill give you the address of the libc functionsystem.- Use
backtraceto find out where you where in a program when it crashed, e.g., after a segmentation fault. Caveat, if your bug smashes the stack then the backtrace won’t be able to make much sense of where you are. - Use
backtrace fullto show the call stack and print the value of local variables. - To find what address caused a segmentation fault:
p $_siginfo._sifields._sigfault.si_addr. If it shows(void *) 0x0(or a small number), then you have a NULL pointer dereference. - Use
find 0x7ffffffde000, 0x7ffffffff000-1, 'a', 'a', 'a', 'a'to search for the string that starts with the patternaaaa—assuming the stack range given byvmmapis 0x7ffffffde000 to 0x7ffffffff000. Note that the subtraction of 1 from the end address is necessary to avoid the error “Unable to access 7169 bytes of target memory at 0x7fffffffd400, halting search.”
Pagination:
set pagination onset pagination offshow pagination
Creating Hooks
Create a hook to print some information on every break point:
define hook-stop
info registers
x/24wx $esp
x/2i $eip
end
This hook will print all of the register values, the stack, and the next two instructions.
Viewing struct values nicely:
set $foo = (struct bar *) 0x804a008
#get the address
print $foo
#get a value of the struct's members
print *$foo
#get the value of an attribute
print $foo->name
#examine the memory at the address stored in the attribute
x $foo->name