Skip to content

Commit

Permalink
ROP: fix self.leave is None in some libc
Browse files Browse the repository at this point in the history
When `pop rbp; pop rsp; ret;` exists in libc, it is chosen instead of
`leave`. Add a specific `order` to filter out the former one.
  • Loading branch information
RocketMaDev committed Dec 13, 2024
1 parent fb2ee19 commit 834d581
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions pwnlib/rop/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@ def __getattr__(self, k):
if not set(['rsp', 'esp']) & set(regs):
self.pivots[sp_move] = addr

leave = self.search(regs=frame_regs, order='regs')
leave = self.search(regs=frame_regs, order='leav')
if leave and leave.regs != frame_regs:
leave = None
self.leave = leave
Expand Down Expand Up @@ -1451,15 +1451,17 @@ def search(self, move = 0, regs = None, order = 'size'):
pointer is adjusted.
regs(list): Minimum list of registers which are popped off the
stack.
order(str): Either the string 'size' or 'regs'. Decides how to
order(str): Either the string 'size', 'leav' or 'regs'. Decides how to
order multiple gadgets the fulfill the requirements.
The search will try to minimize the number of bytes popped more than
requested, the number of registers touched besides the requested and
the address.
If ``order == 'size'``, then gadgets are compared lexicographically
by ``(total_moves, total_regs, addr)``, otherwise by ``(total_regs, total_moves, addr)``.
by ``(total_moves, total_regs, addr)``, if ``order == 'regs'``,
then by ``(total_regs, total_moves, addr)``. ``order == 'leav'``
is specifically for ``leave`` insn.
Returns:
A :class:`.Gadget` object
Expand All @@ -1471,8 +1473,9 @@ def search(self, move = 0, regs = None, order = 'size'):
# Search for an exact match, save the closest match
key = {
'size': lambda g: (g.move, len(g.regs), g.address),
'regs': lambda g: (len(g.regs), g.move, g.address)
}[order]
'regs': lambda g: (len(g.regs), g.move, g.address),
'leav': lambda g: ('leave' not in g.insns, len(g.regs), g.address)
}[order] # False is prior than True

try:
result = min(matches, key=key)
Expand Down

0 comments on commit 834d581

Please sign in to comment.