Quick Notes: GDB Cheatsheet

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! I recommend that students use the pwndbg plug-in as it makes GDB a little nicer to work with. Pwndbg comes preconfigured on the EpicTreasure docker image.

Arguments:

  • Use gdb -ex COMMAND to start GDB and execute the given COMMAND. For example, gdb -ex r will 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=0xdeadbeef to write the value 0xdeadbeef to address 0x8049700.
  • Remember you can use int3 in your shellcode (op code 0xcc) to cause a breakpoint.
  • Execute shell commands, e.g., shell clear will clear the screen.
  • Use the dir command to specify the local directory containing the source files.

Running the binary:

  • run and r will run the current program.
  • kill will kill the current program.
  • Reload the binary: file foo, useful if you pop a shell with execv from 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 *main or b *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 number
  • clear delete all breakpoints
  • enable <num> enables a breakpoint by number
  • disable <num> disables a breakpoint by number

Stepping:

  • si will step instruction by instruction going into function calls whereas
  • ni will step over function calls.
  • step will execute until the next source line, going into function calls.
  • next will execute until the next source line, not going into functions.
  • finish will execute until the current funciton returns
  • continue will continue normal execution.
  • Be careful though, si and ni seem to skip over int3 instructions.
  • f 4 will 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 registers or i r
  • Setting values: set $eax=0

Getting information:

  • info functions
  • disassemble main or disass main to disassemble a function.
  • This command will disassemble the function that contains the instruction at address 0x08… disassemble 0x08...
  • (gef only) aslr will tell you if aslr is enabled. Note that the output may be different before running the binary. You can disable ASLR with aslr off.
  • (gef only) Use vmmap to 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 foo will give you the location of function foo.
  • p system will give you the address of the libc function system.
  • Use backtrace to 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 full to 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 pattern aaaa—assuming the stack range given by vmmap is 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 on
  • set pagination off
  • show 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