Anyways, the stack overflow exploits work like this. If a program has a buffer for a string of text like the body of an email or the header of a ping packet or whatever it can store it in one of a few places. The more modern way (with some fixed overhead) is to dynamically allocate a chunk of memory. The old school way that is very fast is to have a fixed size array (chunk of memory) that is on the stack, just another local variable. So if the coder is sloppy and doesn't check the size of incoming data and blindly writes into a fixed size array, then the array will "overflow," as the program continues to blindly write past the end of the array.
So, for x86 computers the stack "grows down" (lower addresses are higher on the stack) and arrays are typically written in an increasing direction. Thus, when the stack is overwritten, it's the previous stack values that get blasted. These values include a return pointer to tell a function where to return to.
So now, Mr. Malicious 15yr old sends a malformed packet to some buggy server (definately not IIS 4 or Windows RPC Service). The server's processThingy() function blindly overwrites the stack, including the return address, causing it to return to the array it just wrote, which contains malicious code. Now Mr M is in business and can execute whatever code he sent with the same permissions that the server had. Note that to do this, he had to exploit the absolute jump instruction used to return from processThingy(). He was able to do this because he could predict where on the stack, and thus where in memory his code was located.