Add new ROP feature: relative stack offset#2583
Conversation
|
Nice, can you please add a test to the ROP class itself or the module at the top which verifies this works as expected? You can look at the other tests which use |
|
I added the |
I am also thinking about this question. If I want to set an address precisely to the front or back of a gadget or data during ROP writing, due to the encapsulation of some ROP layouts, how should I do this? Since the length of the data after the gadget is uncertain, it seems difficult to achieve this requirement. |
|
The document is complete and can be reviewed. |
|
I though about it again. (Happy anniversary to the PR 🎉) Right now you'd even have to manually import the I think adding something like labels would be applicable to more use cases: Add a way to assign a label to the position in the rop chain and allow to reference that label anywhere. Labels would only work when the base address of the rop chain is known and passed to the from pwn import *
context.clear(arch='amd64')
assembly = 'special_gadget: pop rdx; leave; ret; pop rdi; ret; pop rsi; ret; pop rbp; ret'
binary = ELF.from_assembly(assembly)
binary.symbols['funcname'] = binary.entry + 0x1000
rop = ROP(binary, base=stack)
rop.call("funcname", [b"arg0", b"arg1"])
# set rbp to address of "step1" - 8
rop.rbp = rop.uselabel("step1", offset=-8)
rop.raw(binary.symbols['special_gadget'])
rop.raw(0xdeadbeef) # control rdx (and rbp after leave)
# store current offset while building the chain
rop.setlabel("step1")
rop.call("funcname", [b"hello", b"world"])
print(rop.dump())To set the value of rop = ROP(binary, base=stack)
rop.call("funcname", [b"arg0", b"arg1"])
# set rbp to address of "step1" -> `pop rbp; ret` based on that new `rsp`
rop.rbp = rop.uselabel("step1")
rop.raw(binary.symbols['special_gadget'])
rop.raw(0xdeadbeef) # control rdx
# store current offset while building the chain
rop.setlabel("step1")
rop.raw(0xbeef) # rbp after leave
rop.call("funcname", [b"hello", b"world"])Your use case of gadgets ending in Thoughts? Would this work for your usecase? |
|
Superceded by #2734. |
* ROP: Add labels to reference gadgets dynamically Allow to assign a name to a point in the ROP chain using `ROP.setlabel(name)` and reference it somewhere else using `ROP.uselabel(name, offset)`. You have to know the location of your chain in memory to resolve the right addresses. This allows to specify addresses relative to your ROP chain payload in your chain. Refs #2583 * Update ret2dlresolve test output * Update CHANGELOG * Rename functions to `label` and `ref` This is less verbose than `setlabel` and `uselabel` but still descriptive enough to be able to guess what they do.
Add new
ROPfeature: relative stack offsetSometimes, the ROP needs to be set using the relative offset position on the stack.
This is a temporary solution.
But sometimes errors occur.
Because of the existence of
AppendedArgument, arguments will be placed at the end of the stack.len(rop.chain())will not be the correct offset from base to the current slot.Therefore, I added a class
StackRelativeand added the processing logic forStackRelativein theROP.buildfunction... elif isinstance(slot, StackRelative): address = slot.resolve(slot_address) stack[i] = address stack.describe(self.describe(address), slot_address) ...At this point we can use this to solve the above example.