Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GDB: Assembly instruction calculation

Tags:

c

assembly

gdb

I'm new to assembly. Is there a way to execute a calculation in GDB apart from the actual code being debugged? For example, I'm stepping through the following using Linux IA-32 assembly (AT&T syntax):

   ;$esi is 0xbffff0a8 which refers to 1 after this command. $eax is 2
   0x08048cd5 <+42>:    lea    -0x20(%ebp),%esi

   ;$eax=ebx=2 after this instruction
   0x08048cd8 <+45>:    mov    %ebx,%eax 

   ;$eax equals 2 after this instruction               
   0x08048cda <+47>:    add    -0x4(%esi,%ebx,4),%eax

I'm just not seeing how $eax ends up at 2. Can I assue an instruction like: -0x4(%esi,%ebx,4) in gdb and analyze the result?

As I understand it, $ebx is multiplied by 4 to yield 8. That is added to $esi to give 9. Then -4 is subtracted to give 5. Then five is added to $eax which was 2 to yield 7. Instead $eax is 2.

like image 649
user994165 Avatar asked Oct 07 '12 21:10

user994165


1 Answers

You can evaluate expressions using registers, if that's what you're asking.

gdb's print command is your friend.

Basically you can query the registers by prepending a dollar sign, e.g.

print $ecx

or use them in expressions:

print $esi + $ebx + 4

You can dereference the memory using the * operator (like in C):

print *$ecx

will print the contents of the memory location pointed to by ecx.

While you can't directly type in assembly code, you can translate the expression into something more high-level, like this:

print $eax - ($esi * $ebx)

Also, you can convert to various types using casts to C data-types, e.g.

print (char)$ecx

would print the contents of ecx as a character.

print *(char**)$ecx

which would interpret ecx as a pointer to char*, which you then dereference. So you'd see the contents of the string at the address contained in ecx.

This is just the tip of the iceberg though. gdb is very powerful tool. You might also find the display command useful. It's basically the same as print, except it will repeat the print command whenever the code is stopped (useful with breakpoints). You can examine most registers using info registers, or info all-registers if you're masochistic.

You can also change the contents of registers, using set:

set $eax = 20

and stepi through instructions, or continue running the program.

P.S. You'll probably want to learn how to set breakpoints, etc., if you don't know that.

like image 106
Daniel Hanrahan Avatar answered Sep 19 '22 16:09

Daniel Hanrahan