exploit – How does a different depth of the call stack change the stack pointer in a buffer overflow?


(why can’t you) inject JMP ESP directly into the address of EIP, why do you need to
find an address that performs this call?

First of all, EIP is a register in x86. It itself does not have an address pointing to it. What you mean to say is more along the lines of “the value on the stack that will be popped into EIP at time of return”. This is important, because you can’t just “inject” or put instructions into EIP; it only holds a 4-byte address pointing to the memory address of the instruction to be executed. If you tried to put the opcodes directly in EIP, you’d get a segfault since invalid memory would be accessed.

You might need the jmp ESP or a similar gadget in this case in order to redirect execution to an address you cannot (easily) guess, assuming ASLR is enabled.

(why can’t you) add +4 to the return address as the shellcode comes right after the
return address

If PIE is disabled (which is a fair assumption for an old fashioned exploit like this), then you are able to know the addresses of all the program’s instructions. So you know where the program normally returns, but you don’t know the stack address where that value is stored. So no, you can’t add 4 to an address you don’t know unless you are able to leak it somehow.

Isn’t the shellcode always right after the overwritten EIP?

Not necessarily, it depends what is on the stack, or the shellcode could end up in the heap depending how the program is written. Technically, it would be before since it would be lower addresses.

And if ASLR is not enabled, do you then still have to find an address
with JMP ESP?

No, if there is no ASLR or you are able to leak/guess/bruteforce where the stack is, you can use that address directly such that it ends up in EIP.

As far as call stack depth goes, maybe I’m not understanding the question, but I can’t think of any impacts from that.