A source level debugger based on `ptrace` for *NIX systems and developed by the GNU project.
GDB is primarily designed for debugging software during development with source available. However, it can also be used to debug without source code and debug symbols available.
It is available on most platforms and included by default in the tool chains of most Unix like operating systems. There are text interfaces as well as graphical ones such as Eclipse integration, the venerable DDD or KDBG.
You can find the comprehensive documentation here.
Default interfaces
The default interfaces are terminal based.
But you can also use the following GDB commands on the (gdb)
prompt to switch the layouts on the fly (use help layout
to get more information):
layout src
(only useful with source and symbols)layout asm
layout regs
TUI
There is the default layout src
which can be invoked using the -tui
command line switch.
Simple prompt
Default when not using any kind of command line switches.
layout asm
together with layout regs
This is by far the most useful layout
for reverse engineering, during which debug symbols are usually unavailable. Behold:
Beautiful isn't it? You can see the current values of registers, see the assembly at your current program counter, see where the break point was set and so on. And if you prefer the Intel assembly syntax like I do you issue a:
set disassembly-flavor intel
and it looks like this:
Debugging without debug symbols
Normally GDB will attempt to load the debug symbols from the executable itself or in the search paths it was told about. If it doesn't find any symbols or you are reversing/analyzing a target executable without symbols, you can use the following line:
disp/i $pc
to enable an automatic display
for the program counter ($pc
). So you see what you are going to execute. Starting with GDB 7 you can also use the following setting to achieve virtually the same:
set disassemble-next-line on
If you merely want to see the current instruction use:
x/i $pc
which is short for examine
.
If you wanted to make sure you don't get surprised by something running before you get control in GDB, you should use:
info file
which will give you an output similar to (shortened for brevity):
(gdb) info file
Symbols from "/home/username/source/hello".
Local exec file:
`/home/username/source/hello', file type elf64-x86-64.
Entry point: 0x400410
0x0000000000400238 - 0x0000000000400254 is .interp
0x0000000000400254 - 0x0000000000400274 is .note.ABI-tag
0x0000000000400274 - 0x0000000000400298 is .note.gnu.build-id
0x0000000000400298 - 0x00000000004002b4 is .gnu.hash
0x00000000004002b8 - 0x0000000000400318 is .dynsym
0x0000000000400318 - 0x0000000000400355 is .dynstr
0x0000000000400356 - 0x000000000040035e is .gnu.version
0x0000000000400360 - 0x0000000000400380 is .gnu.version_r
0x0000000000400380 - 0x0000000000400398 is .rela.dyn
0x0000000000400398 - 0x00000000004003c8 is .rela.plt
0x00000000004003c8 - 0x00000000004003e0 is .init
...
and you are interested to set breakpoint
s at the lines for the Entry point:
and the one with .init
(a runtime function running before the entry point):
(gdb) b *0x400410
Breakpoint 1 at 0x400410
(gdb) b *0x00000000004003c8
Breakpoint 2 at 0x4003c8
Notice how we use the asterisk (*
) to specify an address for the break
point command.
Refining what assembly we see
(gdb) x/5i $pc
=> 0x400410 <_start>: xor %ebp,%ebp
0x400412 <_start+2>: mov %rdx,%r9
0x400415 <_start+5>: pop %rsi
0x400416 <_start+6>: mov %rsp,%rdx
0x400419 <_start+9>: and $0xfffffffffffffff0,%rsp
Both examine
and display
allow us to specify the number of instructions we want to see like this to show 5 instructions:
x/5i $pc
we can also tell it to show starting from before the current program counter:
x/10i $pc-3
last but not least we can change from AT&T syntax to Intel syntax:
set disassembly-flavor intel
Example:
(gdb) x/10i $pc-3
0x40041a <_start+10>: and esp,0xfffffff0
=> 0x40041d <_start+13>: push rax
0x40041e <_start+14>: push rsp
0x40041f <_start+15>: mov r8,0x4005a0
0x400426 <_start+22>: mov rcx,0x400510
0x40042d <_start+29>: mov rdi,0x4004f4
0x400434 <_start+36>: call 0x400400 <__libc_start_main@plt>
0x400439 <_start+41>: hlt
0x40043a <_start+42>: nop
0x40043b <_start+43>: nop