Skip to main content

GDB (GNU Debugger)

Getting started​

👉 Gotchas​

  • If you have a multi-line command to run in gdb, you'll need to paste the first line separately and press Enter before pasting the rest

Basic usage​

  1. Start a binary with gdb

    gdb /path/to/binary
  2. Set a breakpoint

    break function_name

    Or to break on a memory address:

    break *0x09319b91
  3. Run the binary

    run

Step through the code​

⚠️ next and step may perform erratically when debugging a stripped binary; use nexti and stepi instead

  • Use next/n to run the next line of code and stop at the next line in the current function
  • Use nexti/ni to run the current instruction and stop at the next instruction in the current function
  • Use step/s to run the next line of code, entering into any functions
  • Use stepi/si to run the current instruction, entering into any functions
  • Use finish/fin to run through the end of the current function

💡 Pressing Enter runs the last command again

Troubleshoot a crash​

  1. Start a binary with gdb (see above)

  2. Wait for the crash

  3. Do a backtrace

    bt

Restart a running program from the beginning​

Just type run again

Variables​

Built-in variables​

  • Stack: $sp or $esp
  • Program counter: $pc
    • This points to the memory address of the current instruction

Registers​

Show all the registers​

info registers

Functions​

Show the parameters of a function​

If you don't have debugging symbols

  1. Open the binary with Ghidra

  2. Go to the top of the function

  3. In the Listing look at the parameters, e.g.

    wchar_t *    Stack[0x8]:4    param_2
    • Parameter is 4 bytes long, on the stack at position 0x8
  4. In Ghidra, copy the memory address

  5. In gdb, set a breakpoint for the address

  6. Examine the stack, e.g.

    x/wx $sp+0x8
  7. Print the value at that address

    In our example above, to print a wchar_t, use this function: https://stackoverflow.com/a/1406427/399105

Breakpoints​

ⓘ If you use start instead of run, gdb may automatically break if it finds a main function, even if no break point was created

Create a breakpoint​

break function_name

Or to break on a memory address:

break *0x09319b91

List breakpoints​

info break

Delete breakpoint​

Use the breakpoint number (see List breakpoints) to delete a specific breakpoint, e.g.

delete 2

Delete all breakpoints​

delete

Printing​

Integer​

Print the value of an unsigned integer:

p (unsigned int)0x00003266

Or to print a memory address:

print *(int*)($sp+0xc)

Byte​

Print a byte

x/xw $sp+0x10

Print 5 bytes

x/5xw $sp

String​

Print a string:

x/s 0xde7f322c