G-Free: defeating return-oriented programming through gadget-less binaries
This paper describes what seems like a really cool technique to prevent ROP attacks if the source is availible. They use an assembly preprocessor getween gcc and the assembler to remove or protect all possible free branches (returns and indirect jumps). They claim to have <3% (1% average) speed/performance impact.
They modify instructions or add no-ops to change alignment so that unintended/unaligned branch instructions are eliminated. To protect legitimate returns and jumps, they encrypt the return address with a random runtime key in the function prologue and decrypt it by XORing it just before the return. This is supposed to prevent the return satement from executing successfully unless the entry point was at the beginning of the function itself.
My question is how will return address encryption prevent ROP gadgets from being used? The key/cookie is stored on the stack just above the return address, so what is to prevent the attacker from modifying the gadget chain on the stack to also include a key 0x00000000 after each return address?
The paper seems to have got 73 citations and no one has mentioned anything like this as far as I can see so I must be missing something. Can someone throw some light on how the protection code for legitimate jumps and returns work?
(I know that this is a long question requiring the reading of a long paper, but I hope that at the very least whoever reads this finds the paper as cool as I did)
Update
This is apparently the same (or very similar) technique used in StackGuard and ProPolice. Can anybody tell me how they fare against memory disclosure vulnerabilities? I can't seem to figure out for sure. What I do find either mentions them in passing or just trumpets their virtues.