today I want to write another quick ‘n dirty post on how to compensate the stack during Return Oriented Programming. Gadgets come with some PUSH/POP operations that shift %ESP blocking the ROP chain.
Lets make this (fake) example:
Gadget 1: 77C5E842 : PUSH EDI / POP EAX / POP EBP / RET
Gadget 2: 77C5D7F5: ADD EAX,20 / POP EBP / RET
Gadget 3: 71AC2528 : XOR EAX,EAX / INC ESI / RET
Gadget 1, makes PUSH %EDI which decrements %ESP, POP %EAX which increments %ESP (so far %ESP is not modified from the original value) but then it makes another POP %EBP which increments %ESP. Finally it RETurns. Gadget 1 does not RET at %ESP + 4 but at %ESP +8 (%ESP + 4 need to be filled up since it is moved to %EBP). At this point the attacker needs to fill in 4 bytes between addresses 77C1E842 and 77C1D7F5.
Gadget 2, makes an arithmetic operation (ADD) which does not modify %ESP but then it POPs %EBP. This increments %ESP. %ESP + C is popped into %EBP. The attacker needs to fill up 4 bytes between addresses 77C1D7F5 and 71AA2526
Gadget 3, maxes only arithmetic operations, it does not need padding.
Finally we come up with the following Stack:
%ESP+14 Eventually another Gadget
This post covered how to pad the stack when Gadgets uses an odd number of sequences PUSH/POP.