Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracing a stack in x86 assembly code

I'm looking at a practice exam for one of my classes and I just don't understand a few aspects of the problem, so maybe you help me (probably really easy if you know x86).

So it's problem 8 here: http://www.coe.utah.edu/~cs4400/schedule/exam3.F10.pdf

And the solution to it is here: http://www.coe.utah.edu/~cs4400/schedule/exam3_solns.F10.pdf\

I just don't understand how the values are obtained in the solution. Let me run through how I intepret the stack:

08048510 <callfoo>:
08048510: 55       pushl %ebp               # old frame pointer is pushed to the stack  
08048511: 89 e5    movl %esp,%ebp           # frame pointer = stack pointer
08048513: 83 ec 08 subl $0x8,%esp           # allocates 8 bytes for stack
08048516: 83 c4 f4 addl $0xfffffff4,%esp    # this I believe allocates 4 bytes to the stack??
08048519: 68 9c 85 04 08 pushl $0x804859c   # push string address
0804851e: e8 d1 ff ff ff call 80484f4 <foo> # call foo, which takes the string address as param1
08048523: 89 ec    movl %ebp,%esp           # (after foo) does similar to return out of function
08048525: 5d       popl %ebp
08048526: c3       ret

080484f4 <foo>:
080484f4: 55       pushl %ebp                  # push old frame pointer
080484f5: 89 e5    movl %esp,%ebp              # frame pointer = stack pointer
080484f7: 83 ec 18 subl $0x18,%esp             # allocate 24 bytes 
080484fa: 8b 45 08 movl 0x8(%ebp),%eax         # moves the param1 (string pointer) into eax
080484fd: 83 c4 f8 addl $0xfffffff8,%esp       # allocates 8 more bytes (?)
08048500: 50       pushl %eax                  # push x # pushes param1 to stack
08048501: 8d 45 fc leal 0xfffffffc(%ebp),%eax  # adds 12 to the frame pointer, puts it in eax(?)  
08048504: 50       pushl %eax                  # push buf (which apparently is located in eax and 0xc(%ebp)
08048505: e8 ba fe ff ff call 80483c4 <strcpy> # copies the string from param1 into buf
0804850a: 89 ec    movl %ebp,%esp              # puts stack pointer into ebp
0804850c: 5d       popl %ebp                   # pops ebp (returns back to other function)
0804850d: c3       ret

(a) So after doing that, I guess I can see kinda how buf[0] = 0x64636261. A char is one byte, and being little endian, it could also be read like this: buf[0] = 0x61626364 (although I don't know if my prof would accept that answer). However, I don't understand how buf[2] is equal to 0x08040069 or 0x69000408. It has the last character, then a null character, but what are the 04 and 08?

(b) I'm not sure how to get (b) or (c). Where do I even obtain what the value of esp is to find out what is put into ebp at the beginning of foo? Overall I'm just confused on these last two... help? :(

like image 854
fvertk Avatar asked Jun 08 '26 05:06

fvertk


1 Answers

There seems to be a lot of unnecessary manipulation of the stack pointer going on in this code, but all that really matters is that the buf variable is at ebp-4. You can see that from the sequence:

leal 0xfffffffc(%ebp),%eax 
pushl %eax
call 80483c4 <strcpy>

0xfffffffc is -4, so leal 0xfffffffc(%ebp),%eax sets eax to the address of the memory location ebp-4. That value is then pushed onto the stack as the first argument to strcpy. Since the first argument passed to strcpy is buf, we know that the address of buf is at ebp-4.

Now consider how the stack builds up as foo is called.

First the string address is pushed by the instruction pushl $0x804859c.

0804859c   # string pointer

Then when the function foo is called, the address of the instruction following the call (08048523) is pushed onto the stack as the return address.

08048523   # return address

Then inside foo, ebp is saved on the stack. It could be anything at this point.

????????   # saved ebp

Then ebp is set to esp, so it's now pointing to the location where the previous ebp was saved.

Now because we know that buf is at ebp-4, that means the very next item on the stack will be buf. There is a lot more space allocated on the stack than is necessary by the subl and addl instructions, but all we care about is that buf is at ebp-4. So the part of the stack that we care about looks like this:

0804859c   # string pointer
08048523   # return address
????????   # saved ebp      <- ebp points here
????????   # buff[0]        <- ebp-4 points here

So now what happens when you copy "abcdefghi" into buff? Because the machine is little endian, those dwords are going to fill up from right to left. You have 9 characters plus a null terminator in that string, so you're going to overwrite all four bytes of buff[0], all four bytes of the saved ebp, and then two bytes of the return address.

So your stack now looks like this:

0804859c   # string pointer
08040069   # return address
68676665   # saved ebp      <- ebp points here
64636261   # buff[0]        <- ebp-4 points here

From that, it should be fairly obvious what the answers to the various questions are.

Since the stack builds downward in memory, buff[1] and buff[2] are located immediately above buff[0] in the stack representation as I've shown it. So you can see the various buff values are just:

buff[0] = 0x64636261
buff[1] = 0x68676665
buff[2] = 0x08040069

Then Immediately before the ret instruction, we have the following two instructions:

movl %ebp,%esp
popl ebp

The first sets esp to the current value of ebp, so it will be pointing to the position on the stack where the previous ebp was saved. However, looking at the stack representation, you can see that that value has now been overwritten with 68676665. So when you pop ebp, that's the value you're going to get.

%ebp = 0x68676665

Similarly, when the function returns, it's going to try and pop the return address off the stack, but again you can see from the stack representation that the original return address has been partially overwritten. So immediately after the ret instruction eip will have popped 08040069.

$eip = 0x08040069

And that, I think, answers all your questions.

I realise this question is now several years old, but it hasn't been closed and there isn't an accepted answer, so perhaps this explanation might still be of some use to someone.

like image 120
James Holderness Avatar answered Jun 10 '26 18:06

James Holderness



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!