Skip to content

Commit

Permalink
rop: Improve density
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 committed Apr 19, 2022
1 parent 79986d8 commit ad901ca
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 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
17 changes: 10 additions & 7 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,12 +186,10 @@
>>> 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`.
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 ad901ca

Please sign in to comment.