Looking at a few basic stack-based buffer overflows, I'm confused as to the difference the caller's ebp plays in a basic return address overwrite vs an off-by-one ebp overwrite.
In the return address overwrite, the goal is to smash the stack enough to overwrite the return address and therefore control eip.
In the off-by-one attack, the LSB of the caller's ebp is overwritten. This forces ebp to pop, and the esp is moved to a location within the attacker-controlled buffer, which elicits control of the return address and, therefore `eip.
My confusion stems from the behaviour of ebp. In the basic return address overwrite, it doesn't matter that we overwrite the caller's ebp with junk bytes, but ebp's value needs to be coherent in the off-by-one attack. How does the function epilogue work in the basic buffer overflow case?
mov esp, ebp
pop ebp
retn