Skip to content

Commit

Permalink
Support adding lists in ROP.raw() (#2128)
Browse files Browse the repository at this point in the history
* Support adding lists in `ROP.raw()`

Allow to add multiple raw entries on a rop chain using an array instead of multiple calls to `raw()`.

```py
rop = ROP('/bin/ls')
# before
rop.raw(1)
rop.raw(2)
rop.raw(rop.ret)

# after
rop.raw([1, 2, rop.ret])
```

Fixes #2017

* Update CHANGELOG.md

* Update pwnlib/rop/rop.py

Co-authored-by: Arusekk <arek_koz@o2.pl>
  • Loading branch information
peace-maker and Arusekk committed Dec 29, 2022
1 parent 838e9ec commit 48d76ed
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions pwnlib/rop/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -1167,32 +1167,51 @@ def find_gadget(self, instructions):
if tuple(gadget.insns)[:n] == tuple(instructions):
return gadget

def _flatten(self, initial_list):
# Flatten out any nested lists.
flattened_list = []
for data in initial_list:
if isinstance(data, (list, tuple)):
flattened_list.extend(self._flatten(data))
else:
flattened_list.append(data)
return flattened_list

def raw(self, value):
"""Adds a raw integer or string to the ROP chain.
If your architecture requires aligned values, then make
sure that any given string is aligned!
When given a list or a tuple of values, the list is
flattened before adding every item to the chain.
Arguments:
data(int/bytes): The raw value to put onto the rop chain.
data(int/bytes/list): The raw value to put onto the rop chain.
>>> context.clear(arch='i386')
>>> rop = ROP([])
>>> rop.raw('AAAAAAAA')
>>> rop.raw('BBBBBBBB')
>>> rop.raw('CCCCCCCC')
>>> rop.raw(['DDDD', 'DDDD'])
>>> print(rop.dump())
0x0000: b'AAAA' 'AAAAAAAA'
0x0004: b'AAAA'
0x0008: b'BBBB' 'BBBBBBBB'
0x000c: b'BBBB'
0x0010: b'CCCC' 'CCCCCCCC'
0x0014: b'CCCC'
0x0018: b'DDDD' 'DDDD'
0x001c: b'DDDD' 'DDDD'
"""
if self.migrated:
log.error('Cannot append to a migrated chain')
self._chain.append(value)

if isinstance(value, (list, tuple)):
self._chain.extend(self._flatten(value))
else:
self._chain.append(value)

def migrate(self, next_base):
"""Explicitly set $sp, by using a ``leave; ret`` gadget"""
Expand Down

0 comments on commit 48d76ed

Please sign in to comment.