Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect invalid gadgets #140

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
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
44 changes: 30 additions & 14 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 @@ -429,8 +447,6 @@ def _initGadgets(self):
]




class ArchitectureArm64(Architecture):

def __init__(self):
Expand Down
27 changes: 18 additions & 9 deletions ropper/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,19 +454,28 @@ 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)

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

if re.match(ending[0], inst.bytes):
hasret = True

if hasret or i.mnemonic not in arch.badInstructions:
gadget.append(
i.address, i.mnemonic,i.op_str, bytes=i.bytes)
reset_gadget = False
if i != len(instrs)-1:
for ending2 in arch.endings_re[GadgetType.ROP]:
if ending2[0].match(inst.bytes):
# anything before this (including this instr) isn't part of this gadget
reset_gadget = True
break
if reset_gadget:
gadget = Gadget(binary, section, arch)
continue

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

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


Expand Down