Triple post.

>> Anyhow...Attacks using techniques like your talking about, work on the principle that it is possible under the right circumstances to alter the return address of a function to allow execution of an attackers code. When the code must branch and follow another execution path, it must have a way to remember where the split occured, so that it can continue execution there when it's done. Basically the value of EIP is pushed unto the stack; a branch of code is ran; and then EIP is pop'ed back of the stack and execution continue's there. So now you should be getting a clearer picture of how it's possible to alter the return address of a function, by writing data to the stack.

Yep, at any function call, when it is call'ed with the CALL instruction, it pushes the address of the next instruction to be executed in the function it's called from onto the stack, then branches flow to the other function, and then when it returns from that function, it pop's the next address off the stack and continues execution in the function that called it. When something like

00401049 CALL vuln.strcpy ; Calls strcpy

Happens, this is push'ed onto the stack

0012FCA0 0040104E ; Data at top of the stack is the next instruction after the call to strcpy

And if I overwrite that return address on the stack, I can go wherever I want. And that's a buffer overflow. I can't see the use of the NOP sled in the case of a JMP ESP thing, because I would have to know exactly where the RET address was, and then just put my shellcode right next to it, but I can see if it was a different register besides ESP for whatever reason, that I could only guarantee within a certain distance, then it could be good.