The stack, and why overflowing it matters
6 min read
When a function is called, the CPU pushes the return address — where to resume when the function finishes — onto the stack. Local variables, including buffers, live just below it. The stack grows downward but arrays fill upward, so a buffer and the saved return address are neighbours pointing at each other.
Now write past the end of that buffer. A gets() or an unbounded strcpy()
keeps copying, straight over the saved return address. When the function returns, the CPU jumps to
whatever you wrote there. You have turned "too much input" into "choose the next instruction" — the
essence of a stack buffer overflow.
higher addresses +---------------------+ | saved return addr | <- overwrite THIS to redirect execution +---------------------+ | saved frame ptr | +---------------------+ | char buf[64] | <- your input starts here and grows up +---------------------+ lower addresses
The distance from the start of the buffer to the return address is the offset, and finding it exactly is the first step of every stack exploit.