def load(fp, _isa, base=0, offset=0): """load a single executable extent from a file""" _isa = isa.correlate(copy.deepcopy(_isa)) # first, assemble fp.seek(offset, os.SEEK_CUR) assembled = bytes( keystone.Ks( _isa["keystone"]["arch"], _isa["keystone"]["endianness"] + _isa["keystone"]["mode"]).asm(fp.read())[0]) # disassemble return MachineCodeIO.load(io.BytesIO(assembled), _isa, base)
def dump(fp, extent): """load a single executable extent to a file""" _isa = isa.correlate(copy.deepcopy(extent["isa"])) # dump assembly b = io.BytesIO() AssemblyIO.dump(b, extent) # assemble fp.write( bytes( keystone.Ks( _isa["keystone"]["arch"], _isa["keystone"]["endianness"] + _isa["keystone"]["mode"]).asm(b.getvalue())[0]))
def loadall(fp, base=0, extents=None): """load all executable extents from a file""" # load the binary binary = analyze.Binary(fp.read()) # compute the complete _isa _isa = isa.correlate({ "capstone": { "arch": binary.arch, "endianness": binary.endianess, "mode": binary.mode } }) # load extents extents = dict(extents) if isinstance(extents, dict) \ else {".text": None} extents = {k: {"base": v} for k, v in extents.items()} for extent in binary.executable_sections: _base = extents[extent.name] \ if isinstance(extents.get(extent.name, None), int) \ else extent.addr code = io.BytesIO(extent.code) for offset in range( min(16, extent.size) ): # Intel-specific############################################################## print( "Loading extent from object (extent \"%s\", offset %u)..." % (extent.name, offset)) code.seek(0, os.SEEK_SET) extents[(extent.name, offset)] = MachineCodeIO.load(io.BytesIO(code.read()), _isa, base + _base, offset) # filter out unmatched extents return {k: v for k, v in extents.items() if len(v.keys()) > 1}
def load(fp, _isa, base=0, offset=0): """load a single executable extent from a file""" _isa = isa.correlate(copy.deepcopy(_isa)) # load fp.seek(offset, os.SEEK_CUR) return { "base": base, "instructions": capstone.Cs( _isa["capstone"]["arch"], _isa["capstone"]["endianness"] + _isa["capstone"]["mode"]).disasm(fp.read(), base + offset), "isa": _isa, "offset": offset }
def chain(which="mprotect", *objs, **kwargs): """establish a predefined ROP chain""" chains = {"mprotect": Transpiler.mprotect} if Transpiler._isa_mismatch(*objs): raise TypeError("ISA mismatch") _isa = None for o in objs: for e in o.values(): if "isa" in e: _isa = e["isa"] break if _isa is not None: break if _isa is None: raise ValueError("no ISA") _isa = isa.correlate(copy.deepcopy(_isa)) if which in chains: print("Generating the \"%s\" chain..." % which) chain = chains[which](*objs, **kwargs) if chain is None: print("Failed!") return print("Packing the chain...") packer = '>' if _isa["capstone"]["endianness"] \ == capstone.CS_MODE_BIG_ENDIAN else '<' packer += 'I' if _isa["capstone"]["mode"] == capstone.CS_MODE_32 \ else 'L' for i, e in enumerate(chain): if isinstance(e, bytes): continue else: # treat as a machine word chain[i] = struct.pack(packer, e) return b"".join(chain) raise ValueError("unsupported chain \"%s\"" % which)
def pload(path, _isa, base=0, offset=0): """load a single executable extent at a path""" _isa = isa.correlate(copy.deepcopy(_isa)) with open(path, "rb") as fp: return MachineCodeIO.load(fp, base, offset)
def pdump(path, extent): """load a single executable extent to a path""" _isa = isa.correlate(copy.deepcopy(extent["isa"])) with open(path, "wb") as fp: MachineCodeIO.dump(fp, extent)