ClearChain

gdb

This page documents some tips on how to use GDB for advanced debugging. It was created as all information I could find on the web lacked some useful information.

 

Assembly Debugging

 

Starting Out

When debugging assembly in gdb, it’s useful to learn about TUI mode. TUI mode gives gdb text based windows. This allows you to see both the disassembled coded as well as the ability to issue commands at the same time – a must have for debugging.

To enter into TUI mode use:

CTRL-X CTRL-1

This will create a single window. (To get rid of it use

CTRL-X a

Initially this window will not be in the right layout. (In gdb TUI mode, a layout is like a mode, ie assembler mode, etc).

You can tell gdb to change to assembly mode using:

layout asm

Now you should be able to see your program in a disassembled text window.

 

Common Tasks

In assembly debugging, theres a few common tasks that you need to these are listed below:

View registers

To view registers you can either use:

info all-registers     |   info reg     |  i r

to view the all/some of the registers. You can use:

 layout reg

to bring up a TUI window with all the registers. This window also shows what changes between instructions when your executing them.

To examine the current value of a register you can use:

 info reg es

You can examine the memory the register points to using the x instruction ie:

 x/x $esp    # View mem in hex
 x/b $esp    # View mem in bin
 x/i $esp    # View instruction at address

You can set a register using:

 set $eip = 0x90   # Set current eip to address 0x90

 

Memory Addresses

If you recall the early lessons in computing there’s two main memory regions in a program – the code segment and the data segment.

The code segment normally consists of executable instructions and static things like constants and strings. You can view the instructions at a memory address using:

disassemble 0x123123

where 0x123123 is an address in memory. This will show you a number of instructions at that address and onwards till the end of the function ends.

You can examine a memory address using

 x  0x123123

The x command takes a number of different parameters/options. It can output binary, hex, strings, instructions etc. For more help on how to use it try: help x in gdb.
You can also print out the value of an address using:

 p 0x123123

like x the p (or print) command the p command takes a number of options for displaying hex, binary etc.

 

Altering program execution

Say you’ve been debugging a program in assembly. You’ve setup break points, either to memory or functions. Now you’ve found the instruction you want to change. There’s a number of ways you can change it. Chances are the instruction is some type of compare, (cmp, cmpl, jge, jmp, etc). You could possible make the instruction a no instruction (nop) or modify the register the compare relies on to be something else.

In order to alter the line to be a nop you can do something like:

 set *0xbxxxx = 0x90

In this case the address is 0xbxxxx and the instruction (under x86 arch) is 0x90 (nop). However this could cause an issue if the previous instruction was 2 bytes wide. ie:

1> 0x126c :   incl   0xfffff3dc(%ebp)
2> 0x126d :   testb  %al,%al
3> 0x126f :   jne    0x125c

In the above the instruction at line 1 is a 1 byte instruction. The instruction at line 2 is a two byte instruction. How? Looks at the difference between the addresses:

 0x126d - 0x126c = 1 byte
 0x126f - 0x126d = 2 byte

In x86 arch, 0x90 (nop) is only a 1 byte instruction.

If you wanted to modify line 2, you’ld have to set the al register so the test would succeed.

Managing Signals

You can enable/disable signals using the ‘handle‘ command. ie:

handle SIGALARM stop

The options to handle are:

 

nostop
GDB should not stop your program when this signal happens. It may still print a message telling you that the signal has come in.
stop
GDB should stop your program when this signal happens. This implies the print keyword as well.
print
GDB should print a message when this signal happens.
noprint
GDB should not mention the occurrence of the signal at all. This implies the nostop keyword as well.
pass
GDB should allow your program to see this signal; your program can handle the signal, or else it may terminate if the signal is fatal and not handled.
nopass
GDB should not allow your program to see this signal. 

And to see what signals are currently set and their default setup use:

info signals 

 

Helpful External Links

http://insecure.org/stf/mudge_buffer_overflow_tutorial.html

Exit mobile version