While I was studying ret2libc, I saw that tutorials use:

call_to_function + ret addr + arguments

For example I understand that if I want to execute system function from libc I can use the following scheme:

system_address(that overwrite eip) + addrsssOf_exit_function + arguments 

What I didn't understand is why we use this order if before calling a function the arguments need to be already on the stack.

If I overwrite the eip the next instruction called is system but we don't have already the arguments, right? What's I'm missing?

1 Answer 1


It can be confusing indeed. What you have to consider is that you are not interacting with the stack in the same way you would if you were writing code. The stack grows down, but your data in the buffer goes from bottom to top. Also, items are popped off the stack from the bottom.

Your buffer overflow allows you to populate the stack in one shot. You will overwrite the stack starting at the bottom. So, when a ret is reached, the program pops the next thing on the stack, which is the address of system() in your case. It then pops the next thing, which is the return address for that function. Finally, the last thing to be popped off the stack is the argument to system().

In summary, it just has to do with the ordering of the stack. It may help to watch the stack while stepping through the program after overflowing the buffer (using GDB or debugger of choice).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .