Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions ropper/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from ropper.common.enum import Enum
from ropper.common.error import NotSupportedError
from ropper.search import Searcher, Searcherx86, SearcherARM, SearcherMIPS
from re import compile
import re
from capstone import *
from . import gadget
try:
Expand Down Expand Up @@ -72,6 +72,7 @@ def __init__(self, arch, mode, addressLength, align, endianess=Endianess.LITTLE,
self._align = align

self._endings = {}
self._endings_re = None
self._badInstructions = []
self._categories = {}
self._maxInvalid = 1
Expand Down Expand Up @@ -137,7 +138,13 @@ def addressLength(self):
@property
def endings(self):
return self._endings


@property
def endings_re(self):
if not self._endings_re:
self._endings_re = {key: [(re.compile(x), y) for x, y in value] for key, value in self.endings.items()}
return self._endings_re

@property
def badInstructions(self):
return self._badInstructions
Expand Down Expand Up @@ -202,8 +209,8 @@ def pprs(self):

def _initGadgets(self):
super(ArchitectureX86, self)._initGadgets()
self._endings[gadget.GadgetType.ROP] = [(b'\xc3', 1), # ret
(b'\xc2[\x00-\xff]{2}', 3)] # ret xxx
self._endings[gadget.GadgetType.ROP] = [(b'[\xc3|\xcb]', 1), # ret
(b'[\xc2|\xca][\x00-\xff]{2}', 3)] # ret xxx

self._endings[gadget.GadgetType.SYS] = [(b'\xcd\x80', 2), # int 0x80
(b'\x0f\x05',2), # syscall
Expand Down Expand Up @@ -383,11 +390,16 @@ def __init__(self, endianess=Endianess.LITTLE):

def _initGadgets(self):
super(ArchitectureArm, self)._initGadgets()
self._endings[gadget.GadgetType.ROP] = [(b'[\x01-\xff]\x80\xbd\xe8', 4)] # pop {[reg]*,pc}
self._endings[gadget.GadgetType.JOP] = [(b'[\x10-\x1e]\xff\x2f\xe1', 4), # bx <reg>
(b'[\x30-\x3e]\xff\x2f\xe1', 4), # blx <reg>
self._endings[gadget.GadgetType.ROP] = [((b'[\x00-\xff][\x80-\xff]' + # pc + any reg
b'[\xbd\xfd]' + # u=1, s=0, w=1, l=1, Rn=1101 (sp)
b'[\xe8\xe9]'), 4)] # e=undconditional, 8/9=opcode+pre/post indexing bit set to anything
self._endings[gadget.GadgetType.JOP] = [(b'[\x10-\x19\x1e]{1}\xff\x2f\xe1', 4), # bx <reg>
(b'[\x30-\x39\x3e]{1}\xff\x2f\xe1', 4), # blx <reg>
(b'[\x00-\x0f]\xf0\xa0\xe1', 4), # mov pc, <reg>
(b'\x01\x80\xbd\xe8', 4)] # ldm sp! ,{pc}
# ldm anything not sp into pc
((b'[\x00-\xff][\x80-\xff]' + # pc + any reg
b'[\x10-\x1c\x1e\x30-\x3c\x3e\x50-\x5c\x5e\x70-\x7c\x7e\x90-\x9c\x9e\xb0-\xbc\xbe\xd0-\xdc\xde\xf0-\xfc\xfe]' + # u=0/1, s=0/1, w=0/1, l=1, Rn=anything but sp or pc
b'[\xe8\xe9]'), 4)] # e=undconditional, 8/9=opcode+pre/post indexing bit set to anything


class ArchitectureArmBE(ArchitectureArm):
Expand All @@ -401,11 +413,17 @@ def __init__(self):

def _initEndianess(self, endianess):
super(ArchitectureArmBE, self)._initEndianess(endianess)
self._endings[gadget.GadgetType.ROP] = [(b'\xe8\xbd\x80[\x01-\xff]', 4)] # pop {[reg]*,pc}
self._endings[gadget.GadgetType.JOP] = [(b'\xe1\x2f\xff[\x10-\x1e]', 4), # bx <reg>
(b'\xe1\x2f\xff[\x30-\x3e]', 4), # blx <reg>
self._endings[gadget.GadgetType.ROP] = [((b'[\xe8\xe9]' + # e=unconditional, 8/9=opcode+pre/post indexing bit set to anything
b'[\xbd\xfd]' + # u=1, s=0/1, w=1, l=1, Rn=1101 (sp)
b'[\x80-\xff][\x00-\xff]'), 4)] # pc + any reg
self._endings[gadget.GadgetType.JOP] = [(b'\xe1\x2f\xff[\x10-\x19\x1e]{1}', 4), # bx <reg>
(b'\xe1\x2f\xff[\x30-\x39\x3e]{1}', 4), # blx <reg>
(b'\xe1\xa0\xf0[\x00-\x0f]', 4), # mov pc, <reg>
(b'\xe8\xdb\x80\x01', 4)] # ldm sp! ,{pc}
# ldm anything not sp into pc
((b'[\xe8\xe9]' + # e=unconditional, 8/9=opcode+pre/post indexing bit set to anything
b'[\x10-\x1c\x1e\x30-\x3c\x3e\x50-\x5c\x5e\x70-\x7c\x7e\x90-\x9c\x9e\xb0-\xbc\xbe\xd0-\xdc\xde\xf0-\xfc\xfe]' + # u=0/1, s=0/1, w=0/1, l=1, Rn=anything but sp or pc
b'[\x80-\xff][\x00-\xff]'), 4)] # pc + any reg


class ArchitectureArmThumb(Architecture):

Expand All @@ -423,14 +441,12 @@ def __init__(self):

def _initGadgets(self):
super(ArchitectureArmThumb, self)._initGadgets()
self._endings[gadget.GadgetType.ROP] = [(b'[\x00-\xff]\xbd', 2)] # pop {[regs]*,pc}
self._endings[gadget.GadgetType.ROP] = [(b'[\x80-\xff]\xbd', 2)] # pop {[regs]*,pc}
self._endings[gadget.GadgetType.JOP] = [(b'[\x00-\x7f]\x47', 2), # bx <reg>
(b'[\x80\x88\x90\x98\xa0\xa8\xb0\xb8\xc0\xc8\xd0\xd8\xe0\xe8\xf0\xf8]\x47', 2) # blx <reg>
]




class ArchitectureArm64(Architecture):

def __init__(self):
Expand Down
33 changes: 22 additions & 11 deletions ropper/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,22 +454,33 @@ def __gatherGadgetsByEnding(self, code, arch, fileName, sectionName, offset, end
def __createGadget(self, arch, code_str, codeStartAddress, ending, binary=None, section=None):
gadget = Gadget(binary, section, arch)
hasret = False
if codeStartAddress == 0x0000000001b34d74:
print("found")
disassembler = self.__getCs(arch)
on_delay_slot = False
for inst in disassembler.disasm(code_str, codeStartAddress+gadget.imageBase):
if on_delay_slot:
gadget.append(inst.address-gadget.imageBase, inst.mnemonic,inst.op_str, bytes=inst.bytes)
break

for i in disassembler.disasm(code_str, codeStartAddress):
if re.match(ending[0], i.bytes):
if re.match(ending[0], inst.bytes):
hasret = True

if hasret or inst.mnemonic not in arch.badInstructions:
gadget.append(inst.address-gadget.imageBase, inst.mnemonic,inst.op_str, bytes=inst.bytes)

if hasret:
if arch.hasBranchDelaySlot:
on_delay_slot = True
continue
else:
break

if hasret or i.mnemonic not in arch.badInstructions:
gadget.append(
i.address, i.mnemonic,i.op_str, bytes=i.bytes)

if (hasret and not arch.hasBranchDelaySlot) or i.mnemonic in arch.badInstructions:
if i.mnemonic in arch.badInstructions:
break



for rop_endings in arch.endings_re[GadgetType.ROP]:
if rop_endings[0].match(inst.bytes):
# anything before this (including this instr) isn't part of this gadget, go back and try again
return None, -1

leng = len(gadget)
if hasret and leng > 0:
Expand Down