3

I'm a beginner in reverse engineering, and as a beginner I started to read "Reverse Engineering for beginers".
Here is the hello world program from the book (taken from chapter 3, page 12) :

Now let’s try to compile the same C/C++ code in the GCC 4.4.1 compiler in Linux: gcc 1.c -o 1 Next, with the assistance of the IDA disassembler, let’s see how the main() function was created. IDA, like MSVC, uses Intel-syntax5.

main proc near

var_10 = dword ptr -10h

     push ebp
     mov ebp, esp
     and esp, 0FFFFFFF0h
     sub esp, 10h
     mov eax, offset aHelloWorld ; "hello, world\n"
     mov [esp+10h+var_10], eax
     call _printf
     mov eax, 0
     leave
     retn
main endp

There are two lines I don't understand at all :

  • and esp, 0FFFFFFF0h
  • sub esp, 10h

From what I understood from the book, we add 0FFFFFFF0h (equals -16) value to ESP in order to align the stack to a 16byte boundary for optimisation.
My question is : why do we add -16 and then substract 16 to the stack? It seems pointless to me, can't we substract directly 32? Second, if I'm understanding well:

  • the program starts with EBP = ESP, because nothing is on the stack.
  • Then EBP is pushed to the stack. Assuming the program is 64bit, ESP is now EBP - 8 (because of the 64bits). So now we have ESP != EBP.
  • Then we copy the content of ESP into EBP. So we have EBP = ESP, and EBP = fristEBP (EBP when the program started) - 8.

Why do we need to modify the value of EBP? PUSH instruction is supposed to change the value of ESP, not EBP, so why would there be any problem not modifying EBP value at the function prolog?



So now we have EBP = ESP, and both are fristEBP (EBP when the program started) - 8. So now we are adding -16 to the stack, so ESP becomes ESP - 16 (ESP - 24 if we consider that we've been adding -8 to the stack).
What is -24 have to do with a 16byte boundary? Why do we substract 16 again from the stack with sub esp, 10h?


Notes : I'm sorry for the english, and sorry if I'm asking dumb questions, the book isn't clear enought and I failed to find explainations on the net.

  • and not add aligns the stack to 16 byte boundary ie 123456a1 & fffffff0 will result in 123456a0 – blabb May 31 '18 at 10:14
  • Isn't there a risk of loosing data? – Nark May 31 '18 at 18:49
2

It's not add in the first opcode. It's and. So it will clear the lower nibble for the last byte in the address. This is how the alignment is done and not by adding anything. Only later you sub 16 to have room for the local variables.

Why do we need to modify the value of EBP?

We use EBP to store the initial ESP value. EBP is pointing to the current stack frame. This is the place for local variables created withing the function. Before we modify EBP it is stored on the stack so that we can restore it before we leave the function.

  • Okay I get it, but why add 0FFFFFFF0h and not 0FFFFFFF0F if we want to clear the lower nibble? – Nark May 31 '18 at 9:48
  • 1
    lower nibble are the bits 3-0 so why we would want to put 0 on bits 7-4 to do that? – Paweł Łukasik May 31 '18 at 9:53
  • I missread, sorry – Nark May 31 '18 at 10:01
  • ok, no worries! – Paweł Łukasik May 31 '18 at 10:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.