def getcfg(self): # lsweep is the linear sweep based analysis # we can chosse other analysis methods, such as # fforward is the fast forward based analysis # see: https://github.com/bdcht/amoco/blob/release/amoco/main.py z = amoco.lsweep(self.prog) z.getcfg() str_sig = '' for func in z.functions(): #print cfg.signature(fun.cfg) str_sig = str_sig + cfg.signature(func.cfg) #print hashlib.sha512(str_sig).hexdigest() return str_sig, z.functions()
def sym_exec_gadget_and_get_mapper(code, address_code=0xdeadbeef): '''This function gives you a ``mapper`` object from assembled `code`. `code` will basically be our assembled gadgets. Note that `call`s will be neutralized in order to not mess-up the symbolic execution (otherwise the instruction just after the `call is considered as the instruction being jumped to). From this ``mapper`` object you can reconstruct the symbolic CPU state after the execution of your gadget. The CPU used is x86, but that may be changed really easily, so no biggie.''' p = amoco.system.raw.RawExec(amoco.system.core.DataIO(code), cpu) blocks = list(amoco.lsweep(p).iterblocks()) assert (len(blocks) > 0) mp = amoco.cas.mapper.mapper() for block in blocks: # If the last instruction is a call, we need to "neutralize" its effect # in the final mapper, otherwise the mapper thinks the block after that one # is actually 'the inside' of the call, which is not the case with ROP gadgets if block.instr[-1].mnemonic.lower() == 'call': p.cpu.i_RET(None, block.map) mp >>= block.map return mp
def run_amoco(executable): p = amoco.system.loader.load_program(executable) print p.mmap # linear sweep disassembly z = amoco.lsweep(p) # block iterator ib = z.iterblocks() b = next(ib) print b # instruction print '--------- symbolic execution -----------' print b.map # symbolic execution print '------ eflags -------' print "CF [0:1] ->", b.map[p.cpu.eflags][0:1] print "PF [2:3] ->", b.map[p.cpu.eflags][2:3] print "AF [4:5] ->", b.map[p.cpu.eflags][4:5] print "ZF [6:7] ->", b.map[p.cpu.eflags][6:7] print "SF [7:8] ->", b.map[p.cpu.eflags][7:8] print "OF [11:12] ->", b.map[p.cpu.eflags][11:12]
def sym_exec_gadget_and_get_mapper(code, address_code = 0xdeadbeef): '''This function gives you a ``mapper`` object from assembled `code`. `code` will basically be our assembled gadgets. Note that `call`s will be neutralized in order to not mess-up the symbolic execution (otherwise the instruction just after the `call is considered as the instruction being jumped to). From this ``mapper`` object you can reconstruct the symbolic CPU state after the execution of your gadget. The CPU used is x86, but that may be changed really easily, so no biggie.''' p = amoco.system.raw.RawExec( amoco.system.core.DataIO(code), cpu ) blocks = list(amoco.lsweep(p).iterblocks()) assert(len(blocks) > 0) mp = amoco.cas.mapper.mapper() for block in blocks: # If the last instruction is a call, we need to "neutralize" its effect # in the final mapper, otherwise the mapper thinks the block after that one # is actually 'the inside' of the call, which is not the case with ROP gadgets if block.instr[-1].mnemonic.lower() == 'call': p.cpu.i_RET(None, block.map) mp >>= block.map return mp
import amoco def generate(instrs): import subprocess f = open("target.asm","w") f.write("segment .text\n") f.write(" global _start\n") f.write("_start:\n") for line in instrs: f.write(line+"\n") f.write("ret\n") f.close() subprocess.check_output(["nasm","-f","elf","target.asm"]) subprocess.check_output(["ld","-m","elf_i386","-s","-o","target","target.o"]) generate(["mov eax, 0x0","inc eax","inc eax","inc eax"]) p = amoco.system.loader.load_program("target") z = amoco.lsweep(p) ib = z.iterblocks() b = next(ib) print b print b.map
import amoco def generate(instrs): import subprocess f = open("target.asm", "w") f.write("segment .text\n") f.write(" global _start\n") f.write("_start:\n") for line in instrs: f.write(line + "\n") f.write("ret\n") f.close() subprocess.check_output(["nasm", "-f", "elf", "target.asm"]) subprocess.check_output( ["ld", "-m", "elf_i386", "-s", "-o", "target", "target.o"]) generate(["xor eax, ebx"]) p = amoco.system.loader.load_program("target") z = amoco.lsweep(p) ib = z.iterblocks() b = next(ib) print b print b.map
def blocks(prog): z = amoco.lsweep(prog) ib = z.iterblocks() b0 = next(ib) b1 = next(ib) return (b0,b1)
def sym_exec_gadget_and_get_mapper(self, code, state=0): r'''This function gives you a ``mapper`` object from assembled `code`. `code` will basically be our assembled gadgets. Arguments: code(str): The raw bytes of gadget which you want to symbolic execution. Return: A mapper object. Example: >>> context.clear(arch="amd64") >>> se = GadgetMapper(CS_ARCH_X86, CS_MODE_64) >>> print se.sym_exec_gadget_and_get_mapper(asm("pop rdi; ret")) rdi <- { | [0:64]->M64(rsp) | } rsp <- { | [0:64]->(rsp+0x10) | } rip <- { | [0:64]->M64(rsp+8) | } Note that `call`s will be neutralized in order to not mess-up the symbolic execution (otherwise the instruction just after the `call` is considered as the instruction being jumped to). From this ``mapper`` object you can reconstruct the symbolic CPU state after the execution of your gadget. The CPU used is x86, but that may be changed really easily, so no biggie. Taken from https://github.com/0vercl0k/stuffz/blob/master/look_for_gadgets_with_equations.py''' if self.arch == CS_ARCH_ARM: from amoco.arch.arm.v7.env import internals internals["isetstate"] = state import amoco import amoco.system.raw import amoco.system.core p = amoco.system.raw.RawExec(amoco.system.core.DataIO(code), self.cpu) try: blocks = list(amoco.lsweep(p).iterblocks()) except: return None if len(blocks) == 0: return None mp = amoco.cas.mapper.mapper() for block in blocks: # If the last instruction is a call, we need to "neutralize" its effect # in the final mapper, otherwise the mapper thinks the block after that one # is actually 'the inside' of the call, which is not the case with ROP gadgets if block.instr[-1].mnemonic.lower() == 'call': p.cpu.i_RET(None, block.map) try: mp >>= block.map except Exception as e: pass return mp