I know that upon a overflow, the stack gets partially overwritten, but I do not understand why registers such as EIP or RIP get changed in this process.
How come some registers are modified by such an attack?
Buffer overflows do not directly modify registers; rather, they are used to overwrite the function return address (the first element in the function's stack frame,
4(%ebp) in x86) and place custom code on the stack which will be executed when the overwritten return address is loaded into EIP/RIP.
In x86 machines, the operations performed by
ret are of particular interest:
When executing a near call, the processor pushes the value of the EIP register (which contains the offset of the instruction following the CALL instruction) onto the stack (for use later as a return-instruction pointer). The processor then branches to the address in the current code segment specified with the target operand.
Transfers program control to a return address located on the top of the stack. The address is usually placed on the stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.
Taking control of EIP/RIP is accomplished by overwriting the return address
call pushed onto the runtime stack with an address that points to the location in memory of code crafted by the attacker. When the
ret instruction writes this memory address to EIP/RIP, execution jumps to that address.
You can see this for yourself by stepping through program instructions using a debugger.