Assuming an x86 system with no aslr I'd like to ask the following;
1) Theory says that when we execute a stack overflow attack, the value pointed to by the ebp register is overwritten with the new return address too.
Now, since we never go back to the caller function we don't really need ebp's original value to restore the previous stack frame but nevertheless, ebp register must point somewhere at all times. How ebp is set after the eip register starts pointing to our new shellcode? More specifically, which of the two assembly instructions (leave-ret) induces a further microinstruction which restores ebp to a value?
2) Last but not least, I would also like to ask how do we make sure that in occasions where our shellcode needs to push a couple of values on the stack, these values won't overwrite any part of the shellcode? In other words, how can we be certain that any shellcode generated variables will only be placed before the start of the shellcode and for instance not somewhere in between?
Thank you all in advance.
In answer to part 2 of your question: Depending on the syscall you are making, you may have to put a value into esp
(as an arg array). If that's the end of the shellcode then you are fine. However, if there is more to the shell code and you happen to do a push
and the esp
happens to point somewhere in the rest of your shellcode you might be in trouble (because at that point you will be writing over your own instructions). A simple fix is to do something like sub $0x99, %esp
at the very beginning of the shellcode.
EDIT (in response to the comments)
Perhaps I misunderstood you question. When you said 'stack overflow' I assumed that you meant a buffer overflow. If I assumed correctly then read on. Assuming you really are talking about a classic smashing-the-stack sort of exploit (which seems to be the case based on the picture you linked to), then you are filling a buffer with a nop
sled, shellcode
and finally overwriting the return pointer. The shell code is "position independent code". That means that it is a series of instructions that can be executed regardless of the current state of the registers, flags etc.
Normally, (this is also the way the link that you posted depicts it) you fill the buffer with nops, followed by the shellcode, and finally a return address that points somewhere in tho nop sled. When the ret
instruction is executed, the address in %esp
is poped into %eip
and %esp
is incremented by 4 (in x86). The problem is that if your shellcode has several push
instructions, this has a side effect of decrementing %esp
. If you have enough of them and your shellcode is all the way at the end (i.e. adjacent to the return address) then you may end up overwriting your shellcode with the push
instructions.
So, to actually answer your question. No, there is no 'mechanism' to separate your shellcode from 'its stack'. This is because there is no stack per-se for your shellcode. Remember, it is position independent code. It must be able to run regardless of machine state. Any stack management that needs to happen must be performed by the shellcode itself. That is why I suggested a sub $0x99, %esp
at the begning of the shellcode if you have many push
statements in the code. Another option is to make sure there sufficient space between the return address (which %esp-4
will be pointing at) and your shellcode.