0

DISCLAIMER: This is a homework problem so I do not want you to just tell me the answer. Rather I need help understanding how this code works. If this is not allowed then that is fine I can take this down or whatever is required by me. What I am trying to do is understand x86(Intel). I am just learning it and there is so much going on that I often find myself staring at the screen making no progress. What will help me is asking ME questions that lead to the answer rather than giving me the answer. I know this is not a discussion forum so maybe someone can point me to place that would be glad to help me with a problem such as this.

What I understand so far is that space is allocated on the stack by the sub instruction. then whatever is in eax is moved to the stack. then the combinations of mov and lea confuses me. My intuition tells me that pointers are being stored on the stack to be used later. Or that it might be some kind of mathematical function being performed on the number I provided. In the beginning of the function I found that eax had the number I inputted. Another thing I found is that doing x/s 0x804a819 gave me "%d %d %d %d %d %d". Is this moving six numbers to 0x4(%esp)? I found the address 0x804a819 from the movl instruction. Just before the call to sscanf there is mov %eax,(%esp) I assume the program is saving the position of the stack pointer for later use? One thing I have tried is after the call 0x80488d0 <__isoc99_sscanf@plt> is executed I did p $eax = 0x7 so that the instruction cmp $0x5,%eax would set the right flags so that the instruction jg 0x80495b5 would skip over calling explode_bomb. But no matter what explode_bomb gets called. So I'm sure there is something I am missing and its probably not even in this function.

Some other questions. A functions local variables are stored on the stack correct?

sub    $0x2c,%esp
mov    0x34(%esp),%eax
lea    0x14(%eax),%edx
mov    %edx,0x1c(%esp)
lea    0x10(%eax),%edx
mov    %edx,0x18(%esp)
lea    0xc(%eax),%edx
mov    %edx,0x14(%esp)
lea    0x8(%eax),%edx
mov    %edx,0x10(%esp)
lea    0x4(%eax),%edx
mov    %edx,0xc(%esp)
mov    %eax,0x8(%esp)
movl   $0x804a819,0x4(%esp)
mov    0x30(%esp),%eax
mov    %eax,(%esp)
call   0x80488d0 <__isoc99_sscanf@plt>
cmp    $0x5,%eax
jg     0x80495b5 <read_six_numbers+76>
call   0x804941c <explode_bomb>
add    $0x2c,%esp
ret 
Javier Pena
  • 115
  • 1
  • 2
  • 6
  • Remember AT&T syntax is stupid and backwards - `eax` is _loaded_ off the stack initially. – Notlikethat Feb 15 '14 at 17:52
  • So you want a hint: the stack is used for two things, one being (as you say) storing automatics (local variables within a function), and the other the 'call' line can help you with. – abligh Feb 15 '14 at 18:04
  • I'm pretty sure this is intel syntax though – Javier Pena Feb 15 '14 at 18:04
  • The compiler will choose `lea` instructions if it needs to do addition and store the result in a different register in one step. For example `0x14(%eax),%edx` adds 20 to `eax` and places the result in `edx`. Different versions of `lea` can add _two_ registers, optionally multiplying one of these by 2,4, or 8, plus a constant and place the result in a different register. – Gene Feb 15 '14 at 18:31
  • Just to clarify your last question, only _automatic_ local variables go on the stack. Static local variables will go on the heap. –  Feb 15 '14 at 19:59
  • This isn't Intel syntax, this is AT&T syntax. x86 assembly can be printed in two different ways. On Windows systems (and Intel documentation), Intel format is used. Traditionally on Unix systems, AT&T format is used. gdb by default will print using AT&T syntax. – Jason Molenda Feb 20 '14 at 00:58
  • type into gdb `set disassembly-flavor intel`. – James Feb 20 '14 at 01:11

1 Answers1

0

It will probably be helpful to remember that on i386, function arguments are passed on the stack. On function entry, if you read the word of memory at the stack pointer's address, you'll find the caller's return address.

It looks like your mystery function here takes two arguments. So when it says

sub    $0x2c,%esp
mov    0x34(%esp),%eax

Once 0x2c has been subtracted from the stack pointer, we can find the caller's saved eip at *(esp + 0x2c), we can find the first argument at *(esp + 0x30) and we can find the second argument at *(esp + 0x34). You can see a reference to that second argument here,

movl   $0x804a819,0x4(%esp)
mov    0x30(%esp),%eax
mov    %eax,(%esp)
call   0x80488d0 <__isoc99_sscanf@plt>

This stores the address of your format string at address (0x804a819) at *(esp+4) - so that is going to be the 2nd argument to sscanf(). Then it loads the first argument to your mystery function (at *(esp + 0x30)) and stores it at *(esp) - so it will be the 1st argument to sscanf().

Hopefully that's enough help to understand the function without being too helpful. :)

Jason Molenda
  • 14,835
  • 1
  • 59
  • 61