Debugging at the assembly level¶
You can debug or reverse engineer a program in gdb even if
there is no source-level or debugging information for it, by working
directly at the machine code level. Let’s say you want to figure out
a program named progX
; you can load it in the debugger with
gdb progX
and get the (gdb)
command prompt.
A good way to begin is to start the program, paused, with the
start
command, and then step instruction by instruction with the
stepi
command (which can be abbreviated si
, and repeated
by simply hitting enter). However, all you will see is the address of the
current instruction. You can disassemble the entire current function with
disassemble
(abbreviated disas
), and it will even show
an arrow indicating the current line; you can also set gdb
to automatically disassemble and show you the instruction about to
execute with disp/i $pc
.
While you are stepping through the program, you will typically want to
see the values of various variables. If there is a variable with a symbol
in the symbol table, for example a global variable named array
,
you can use that name in gdb and e.g. print array
, but without
debugging information it won’t know what type to use when interpreting
that memory. You can try e.g. print/d (char[100])array
if you hypothesize that the array is 100 bytes, or print/d
(long[100])array
if you hypothesize that the array is 100 long integers.
Another useful technique is to use breakpoints to avoid all that stepping. When you disassemble the function, you can read down to where you would like to pick up debugging, and set a breakpoint at that address. For example, if you see the following line, you know that’s the end of the function.
0x000000000000118a <+97>: ret
The <+97>
part is the offset of the address from the
top of the function, so you can either call this instruction
*0x000000000000118a
or *main+97
in this case. To set
a breakpoint there, use the break
command, e.g. break
*main+97
. Then you can run
your program or, if it is already
running but paused, continue
it and let it run at its own pace
until it hits the breakpoint. Then have a look around!