ESP and EBP registers delimit the current location of the stack,
they point to the frame of activation
The call
intruction saves the current EIP on the stack,
The equivalent instructions to call 0x8048484 <foo>
are:
push %eip
jmp 0x8048484 ~foo()
The difference with the sole call of jmp
is that the call saves
the current state of EIP to return to it later.
After the jump the stack allocation is done:
Allocate space on the stack incrementing ESP
push %ebp
mov %esp, %ebp
sub %0x4, %esp
To view this result I should disable the optimization with -O0
and -preferred-stack-boundary=2
turning off some optimization
that store multiple (short) variables per stack word.
Before the function return, the return value is moved into EAX
The return from function is made with the leave
op
mov %ebp, %esp
pop %ebp
ret
That deallocates the current stack, and the ret
op pops the last value
on the stack to EIP to restore it.
Suggested reading: Smashing the stack for fun and profit
This works in C because it doesn't do memory management for you
like Python or Java
If we have a code like this
char buf[8];
gets(buf);
And we input during execution a sequence longer than 8
we get a segmentation fault
That is actually raised by the jmp
op trying to jump to
a meaningless position in memory, since we overwritten EIP
that was stored on the stack, by growing the heap.
Maybe it would have been enough to overwrite the return value
wothout overwriting EBP and EIP, and that is another
security vulnerability itself.
To jump to any function i would need to setup the parameters correctly on the stack. I can also jump into a function of a library loaded into memory This is called return to library or in particular return to libc. Also the environment variable loaded with a program are stored on top of the stack always in the same place, so i can put code in there and jump to it. Requirement for stack smashing:
We can use a debugger to stop the execution before the vulnerability
and get the address of memory where ESP is stored
On our own machine i can use a code to print to screen the position of ESP
(see slides)
The debugger method is not so reliable because some debuggers like gdb add
an offset to allocated memory.
We can reduce the need of precision filling the heap area with nop
forming a nop sled that make the processor go through to the right exploit code.
This is a measure to make the exploit work reliably on remote machines,
ans this is part of weaponizing an explloit