Skip to content

Commit

Permalink
rop: Improve density (Gallopsled#2048)
Browse files Browse the repository at this point in the history
When the last gadget has no arguments and the gadget before has stack
arguments, put the last gadget directly in its return address slot
(instead of a stack adjustment gadget).
  • Loading branch information
Arusekk authored and vboxuser committed Sep 10, 2023
1 parent b5fd3c9 commit 11e9b9b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
7 changes: 7 additions & 0 deletions pwnlib/rop/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,13 @@ def __repr__(self):
fmt % self.target,
self.args)

def is_flat(self):
if isinstance(self, six.integer_types + (Unresolved,)):
return True
if not isinstance(self, Call):
return False
return bool(self.args or self.stack_arguments_before)

@property
def register_arguments(self):
return dict(zip(self.abi.register_arguments, self.args))
Expand Down
21 changes: 12 additions & 9 deletions pwnlib/rop/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,10 @@
0x001c: 0x6 arg2
0x0020: b'iaaa' <pad>
0x0024: 0xdecafbad write(7, 8, 9)
0x0028: 0x10000000 <adjust @0x3c> add esp, 0x10; ret
0x0028: 0xfeedface exit()
0x002c: 0x7 arg0
0x0030: 0x8 arg1
0x0034: 0x9 arg2
0x0038: b'oaaa' <pad>
0x003c: 0xfeedface exit()
You can also append complex arguments onto stack when the stack pointer is known.
Expand Down Expand Up @@ -188,18 +186,16 @@
>>> rop.exit()
>>> print(rop.dump())
0x0000: 0x10000012 write(STDOUT_FILENO, 0x10000026, 8)
0x0004: 0x1000000e <adjust @0x18> add esp, 0x10; ret
0x0004: 0x1000002f exit()
0x0008: 0x1 STDOUT_FILENO
0x000c: 0x10000026 flag
0x0010: 0x8 arg2
0x0014: b'faaa' <pad>
0x0018: 0x1000002f exit()
The raw data from the ROP stack is available via `str`.
The raw data from the ROP stack is available via `r.chain()` (or `bytes(r)`).
>>> raw_rop = rop.chain()
>>> print(enhex(raw_rop))
120000100e000010010000002600001008000000666161612f000010
120000102f000010010000002600001008000000
Let's try it out!
Expand Down Expand Up @@ -927,7 +923,7 @@ def build(self, base = None, description = None):
# If there were arguments on the stack, we need to stick something
# in the slot where the return address goes.
if len(stackArguments) > 0:
if remaining:
if remaining and (remaining > 1 or Call.is_flat(chain[-1])):
fix_size = (1 + len(stackArguments))
fix_bytes = fix_size * context.bytes
adjust = self.search(move = fix_bytes)
Expand All @@ -944,6 +940,13 @@ def build(self, base = None, description = None):
stackArguments.append(Padding())

# We could not find a proper "adjust" gadget, but also didn't need one.
elif remaining:
_, nxslot = next(iterable)
stack.describe(self.describe(nxslot))
if isinstance(nxslot, Call):
stack.append(nxslot.target)
else:
stack.append(nxslot)
else:
stack.append(Padding("<return address>"))

Expand Down

0 comments on commit 11e9b9b

Please sign in to comment.