this time I am just commenting (and quoting) example made by the corelan team present on their forum. Personally I've never used Gadgets ending up with RETN + Offset, so I've never had the necessity to find out a way to pad the stack in this way. After all it seems pretty logic the way the stack needs to be padded, but lets see how they justified it.
Let’s say we have the following gadgets :
77C1E842 : PUSH EDI / POP EAX / POP EBP / RETN + 4
77C1D7F5: ADD EAX,20 / POP EBP / RETN + 8
71AA2526 : XOR EAX,EAX / INC ESI / RET
The first gadget ends with RETN+4. The second gadget ends with RETN+8. How does this impact the stack layout ?
ESP 77C1E842 <- first gadget. PUSH EDI/POP EAX is followed by POP EBP and RETN + 4
ESP+4 DAC0FF33 <- will be popped into EBP by gadget above. These 4 bytes need to be on the stack to make sure RET will land at next pointer (at ESP+8)
ESP+8 77C1D7F5 <- second gadget. POP EBP will pick up next 4 bytes. This gadget ends with RETN + 8
ESP+C 41414141 <- these are the 4 bytes needed to compensate for RET+4 in the first gadget. As you can see, the 4 bytes compensation need to be placed after the next RET instruction (so after the next gadget).
ESP+10 DAC0FF33 <- will be popped into EBP by gadget 77C1D7F5. RET will then land at next pointer (at ESP+10)
ESP+14 71AA2526 <- third gadget. No additional bytes are needed because nothing will be picked up from stack by this gadget.
ESP+18 41414141 4 bytes of padding – compensate for the first 4 bytes in RET+8 (gadget 2)
ESP+1C 41414141 4 bytes of padding – compensate for the second 4 bytes in RET + 8 (gadget 2)
ESP+20 <- 4th gadget must be placed here
Conclusion : the offset to RET must be accounted for on the stack after the next gadget pointer, and not after the current gadget pointer.
A great example of what written above is the exploit made by sickness : a Buffer Overflow in WM Downloader 18.104.22.168 available here. Following a piece of exploit (click on it to make it bigger) commented showing both padding procedures: POP padding (as explained here) and RETN + Offset as explained above.
In red you see the "common" stack compensation used to compensate POP instructions, Green the stack compensation due to RETN + Offset Gadgets. Following another piece of exploit commented and explained using the same notation.
Great ! That's all folks. For any comments and/or doubts feel free to send me email (or comment), as usually ! ;)