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.