def jit_instructions(mn_str): """JIT instructions and return the jitter object.""" # Get the miasm Machine machine = Machine("mepb") mn_mep = machine.mn() loc_db = LocationDB() # Assemble the instructions asm = b"" for instr_str in mn_str.split("\n"): instr = mn_mep.fromstring(instr_str, "b") instr.mode = "b" asm += mn_mep.asm(instr)[0] # Init the jitter and add the assembled instructions to memory jitter = machine.jitter(loc_db, jit_type="gcc") jitter.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, asm) # Set the breakpoint jitter.add_breakpoint(len(asm), lambda x: False) # Jit the instructions #jitter.init_stack() jitter.init_run(0) jitter.continue_run() return jitter
def miasm_load_vmlinux(kallsyms, vmlinux): global g_machine global g_code_size global g_jitter global g_cpu if kallsyms['arch'] == 'arm': g_cpu = "arml" elif kallsyms['arch'] == 'arm64': g_cpu = "aarch64l" else: raise Exception('Invalid arch') g_machine = Machine(g_cpu) g_jitter = g_machine.jitter('gcc') start_addr = kallsyms['_start'] g_code_size = ((len(vmlinux) + 0x1000) >> 12 << 12) g_code_size += 0x8000000 # bss end_addr = start_addr + g_code_size print_log("[+]mapping %s - %s" % (hex(start_addr), hex(end_addr))) g_jitter.vm.add_memory_page(start_addr, PAGE_READ|PAGE_WRITE, b"\x00"*g_code_size, "code page") g_jitter.vm.set_mem(kallsyms['_start'], vmlinux) # stack g_jitter.vm.add_memory_page(0xdead1000, PAGE_READ|PAGE_WRITE, b"\x00"*0x2000, "stack")
def __init__(self): self.machine = Machine('x86_64') self.dis_engine, self.ira = self.machine.dis_engine, self.machine.ira self.bs = bin_stream_ida() self.mdis = self.dis_engine(self.bs) self.ssa_cache = {} self.ssa_with_state_cache = {} return
def init_jitter(loc_db): global data, run_addr # Create jitter myjit = Machine("x86_32").jitter(loc_db, sys.argv[1]) myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) # Init jitter myjit.init_stack() myjit.set_trace_log() myjit.push_uint32_t(0x1337beef) myjit.add_breakpoint(0x1337beef, code_sentinelle) return myjit
def __init__(self, file_name, conn=None, cont=None, exectbl=None, *args, **kwargs): super(ExtendedAsmCFG, self).__init__(loc_db=LocationDB(), *args, **kwargs) self.file_name = file_name if not cont: if conn: stream = conn.builtins.open(file_name, 'rb') else: stream = open(file_name, 'rb') cont = Container.from_stream(stream) self.cont = cont self.mode = int(cont.arch[-2:]) self.address_size = self.mode // 8 self.pck = pck32 self.upck = upck32 self.machine = Machine(cont.arch) self.disassembler = self.machine.dis_engine if self.mode == 64: self.pck = pck64 self.upck = upck64 self._exectbl = exectbl if not exectbl: self._exectbl = pe_init.PE(cont.executable) self._dis_engine = None self.func_addr = None self.jmp_table_loc_keys = set()
def init_jitter(): global data, run_addr # Create jitter myjit = Machine("x86_32").jitter(sys.argv[1]) myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) # Init jitter myjit.init_stack() myjit.set_trace_log() myjit.push_uint32_t(0x1337beef) myjit.add_breakpoint(0x1337beef, code_sentinelle) return myjit
def __init__(self, raw, address): self.cont = Container.fallback_container(raw + b'\xC3', vm=None, addr=address) self.address = address self.machine = Machine('x86_64') self.mdis = self.machine.dis_engine(self.cont.bin_stream, loc_db=self.cont.loc_db) self.asmcfg = self.mdis.dis_multiblock(self.address) self.head = self.asmcfg.getby_offset(self.address).loc_key self.orignal_ira = self.machine.ira(self.mdis.loc_db) self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg( self.asmcfg) self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira) self.common_simplifier.simplify(self.orginal_ircfg, self.head) self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db) self.custom_ira2 = IRAOutRegs(self.mdis.loc_db) self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg) self.simplify()
def __init__(self, arch): """ :param arch: Either 32 or 64 bit architecture """ self._pending = {} self._reached_funcs = set() if arch not in [32, 64]: raise ValueError self._machine = Machine("x86_" + str(arch))
def miasm_machine(): """Retrieve a miasm machine using the R2M2_ARCH environment variable.""" r2m2_arch = os.getenv("R2M2_ARCH") available_archs = Machine.available_machine() if not r2m2_arch or r2m2_arch not in available_archs: message = "Please specify a valid miasm arch in the R2M2_ARCH " message += "environment variable !\nThe following are available: " message += ", ".join(available_archs) print >> sys.stderr, message + "\n" return None else: global MIASM_MACHINE if MIASM_MACHINE is None: MIASM_MACHINE = Machine(r2m2_arch) return MIASM_MACHINE
def __init__(self, jitter_engine): self.machine = Machine(self.arch_name) jitter = self.machine.jitter self.myjit = jitter(jitter_engine) self.myjit.init_stack() self.myjit.set_trace_log() self.dse = None self.assembly = None
def patch_xrefs(find_addr, patch_addr, args, ip='localhost', port=4455, conn=None): """ Patches xrefs with certain arguments :param find_addr: address of function whose xrefs are to be replaced :param patch_addr: the new target of the xref call :param args: dictionary mapping number of argument to its required value :param ip: optional, IP of the computer running rpyc server in IDA :param port: optional, port of the computer running rpyc server in IDA :param conn: optional, already estabilished connection to running rpyc server in IDA :return: None """ close_conn = False if not conn: close_conn = True conn = rpyc.classic.connect(ip, port) file_name = conn.modules.idaapi.get_input_file_path() idautils = conn.root.getmodule("idautils") with mock.patch("builtins.open", conn.builtins.open): cont = Container.from_stream(open(file_name, 'rb')) machine = Machine(cont.arch) mdis = machine.dis_engine(cont.bin_stream) exectbl = cont.executable for r in idautils.XrefsTo(find_addr): scn_args = conn.modules.idaapi.get_arg_addrs(r.frm) if scn_args is None: print("Couldn't find args of %x" % r.frm) continue if compare_args(args, scn_args, conn): patch_xref(r.frm, patch_addr, mdis, machine.mn, exectbl) with open(file_name, 'wb') as fl: fl.write(bytes(exectbl)) if close_conn: conn.close()
def main(file_path: Path, start_addr: int, oracle_path: Path) -> None: # symbol table loc_db = LocationDB() # open the binary for analysis container = Container.from_stream(open(file_path, 'rb'), loc_db) # cpu abstraction machine = Machine(container.arch) # init disassemble engine mdis = machine.dis_engine(container.bin_stream, loc_db=loc_db) # initialize intermediate representation lifter = machine.lifter_model_call(mdis.loc_db) # disassemble the function at address asm_block = mdis.dis_block(start_addr) # lift to Miasm IR ira_cfg = lifter.new_ircfg() lifter.add_asmblock_to_ircfg(asm_block, ira_cfg) # init symbolic execution engine sb = SymbolicExecutionEngine(lifter) # symbolically execute basic block sb.run_block_at(ira_cfg, start_addr) # initialize simplifier simplifier = Simplifier(oracle_path) for k, v in sb.modified(): if v.is_int() or v.is_id() or v.is_loc(): continue print(f"before: {v}") simplified = simplifier.simplify(v) print(f"simplified: {simplified}") print("\n\n")
def emotet_control_flow_unflatten(func_addr, filename): with open(filename, 'rb') as fstream: cont = Container.from_stream(fstream) machine = Machine(cont.arch) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) asmcfg = mdis.dis_multiblock(func_addr) ir_arch = machine.ira(mdis.loc_db) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) state_register = get_state_register(asmcfg, get_loc_key_at(cont.loc_db, func_addr)) if not state_register: print("[-] Function was not obfuscated") return to_patch_offsets = resolve_offsets(state_register, asmcfg, ircfg, ir_arch) to_patch_offsets.sort(key=lambda tup: tup[0]) fix_func_cfg(filename, to_patch_offsets) print("[+] Function was deobfuscated!")
def init(binary): BinaryAnalysis.clear() BinaryAnalysis.path = binary BinaryAnalysis.rawData = list(open(binary, 'rb').read()) BinaryAnalysis.container = Container.from_stream(open(binary, 'rb')) BinaryAnalysis.locDB = BinaryAnalysis.container.loc_db BinaryAnalysis.machine = Machine(BinaryAnalysis.container.arch) BinaryAnalysis.iraType = BinaryAnalysis.machine.ira if isinstance(BinaryAnalysis.container, ContainerPE): BinaryAnalysis.binaryInfo = PEInfo(binary) elif isinstance(BinaryAnalysis.container, ContainerELF): BinaryAnalysis.binaryInfo = ELFInfo(binary) if BinaryAnalysis.binaryInfo.type == 'PE': if BinaryAnalysis.container.arch == 'x86_32': parser = Sandbox_Win_x86_32.parser(description="PE sandboxer") options = parser.parse_args() BinaryAnalysis.sb = Sandbox_Win_x86_32(BinaryAnalysis.path, options, globals()) elif BinaryAnalysis.container.arch == 'x86_64': parser = Sandbox_Win_x86_64.parser(description="PE sandboxer") options = parser.parse_args() BinaryAnalysis.sb = Sandbox_Win_x86_64(BinaryAnalysis.path, options, globals()) elif BinaryAnalysis.binaryInfo.type == 'ELF': if BinaryAnalysis.container.arch == 'x86_32': parser = Sandbox_Linux_x86_32.parser( description="PE sandboxer") options = parser.parse_args() BinaryAnalysis.sb = Sandbox_Linux_x86_32( BinaryAnalysis.path, options, globals()) elif BinaryAnalysis.container.arch == 'x86_64': parser = Sandbox_Linux_x86_64.parser( description="PE sandboxer") options = parser.parse_args() BinaryAnalysis.sb = Sandbox_Linux_x86_64( BinaryAnalysis.path, options, globals()) BinaryAnalysis.disasmEngine = BinaryAnalysis.machine.dis_engine( BinaryAnalysis.container.bin_stream, loc_db=BinaryAnalysis.container.loc_db) BinaryAnalysis.disasmEngine.dis_block_callback = detect_func_name BinaryAnalysis.maxSizeData = BinaryAnalysis.disasmEngine.attrib // 8 BinaryAnalysis.strings = BinaryAnalysis.binaryInfo.findStrings() BinaryAnalysis.radare = r2pipe.open(binary) BinaryAnalysis.radare.cmd('aaa;') BinaryAnalysis.detectFunctions() BinaryAnalysis.disassembly() for start, end in (BinaryAnalysis.binaryInfo.codeRange - BinaryAnalysis.doneInterval): BinaryAnalysis.data.append((start - 1, end)) for start, end in BinaryAnalysis.binaryInfo.dataRange: BinaryAnalysis.data.append((start, end - 1))
class Block: def __init__(self, raw, address): self.cont = Container.fallback_container(raw + b'\xC3', vm=None, addr=address) self.address = address self.machine = Machine('x86_64') self.mdis = self.machine.dis_engine(self.cont.bin_stream, loc_db=self.cont.loc_db) self.asmcfg = self.mdis.dis_multiblock(self.address) self.head = self.asmcfg.getby_offset(self.address).loc_key self.orignal_ira = self.machine.ira(self.mdis.loc_db) self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg( self.asmcfg) self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira) self.common_simplifier.simplify(self.orginal_ircfg, self.head) self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db) self.custom_ira2 = IRAOutRegs(self.mdis.loc_db) self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg) self.simplify() def simplify(self): simplifier = IRCFGSimplifierCommon(self.custom_ira1) simplifier.simplify(self.ircfg, self.head) for loc in self.ircfg.leaves(): irblock = self.ircfg.blocks.get(loc) if irblock is None: continue regs = {} for reg in self.custom_ira1.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) newAssignBlk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(newAssignBlk) newIrBlock = IRBlock(irblock.loc_key, assignblks) self.ircfg.blocks[loc] = newIrBlock simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2) simplifier.simplify(self.ircfg, self.head)
class Arch(object): """ Parent class for Arch abstraction """ # Architecture name _ARCH_ = None def __init__(self, **kwargs): self.machine = Machine(self._ARCH_) self.jitter = self.machine.jitter(self.options.jitter) @classmethod def update_parser(cls, parser): pass
class Asm_Test(object): def __init__(self, jitter): self.myjit = Machine("mips32l").jitter(jitter) self.myjit.init_stack() def __call__(self): self.asm() self.run() self.check() def asm(self): blocks, loc_db = parse_asm.parse_txt(mn_mips32, 'l', self.TXT, loc_db=self.myjit.ir_arch.loc_db) # fix shellcode addr loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_mips32, blocks, loc_db) for offset, raw in viewitems(patches): s[offset] = raw s = bytes(s) self.assembly = s def run(self): run_addr = 0 self.myjit.vm.add_memory_page( run_addr, PAGE_READ | PAGE_WRITE, self.assembly) self.myjit.cpu.RA = 0x1337beef self.myjit.add_breakpoint(0x1337beef, lambda x: False) self.myjit.init_run(run_addr) self.myjit.continue_run() assert(self.myjit.pc == 0x1337beef) def check(self): raise NotImplementedError('abstract method')
class Asm_Test_16(Asm_Test): arch_name = "x86_16" arch_attrib = 16 ret_addr = 0x1337 def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.stack_base = 0x1000 self.myjit.stack_size = 0x1000 self.myjit.init_stack() def init_machine(self): self.myjit.vm.add_memory_page(self.run_addr, PAGE_READ | PAGE_WRITE, self.assembly) self.myjit.push_uint16_t(self.ret_addr) self.myjit.add_breakpoint(self.ret_addr, lambda x:False)
class Asm_Test_16(Asm_Test): arch_name = "x86_16" arch_attrib = 16 ret_addr = 0x1337 def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.stack_base = 0x1000 self.myjit.stack_size = 0x1000 self.myjit.init_stack() def init_machine(self): self.myjit.vm.add_memory_page(self.run_addr, PAGE_READ | PAGE_WRITE, self.assembly) self.myjit.push_uint16_t(self.ret_addr) self.myjit.add_breakpoint(self.ret_addr, lambda x: False)
class Asm_Test(object): run_addr = 0x0 def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.init_stack() def test_init(self): pass def prepare(self): pass def __call__(self): self.prepare() self.asm() self.init_machine() self.test_init() self.run() self.check() def run(self): self.myjit.init_run(self.run_addr) self.myjit.continue_run() assert (self.myjit.pc == self.ret_addr) def asm(self): blocks, loc_db = parse_asm.parse_txt(mn_x86, self.arch_attrib, self.TXT, loc_db=self.myjit.ir_arch.loc_db) # fix shellcode addr loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_x86, blocks, loc_db) for offset, raw in viewitems(patches): s[offset] = raw s = bytes(s) self.assembly = s def check(self): raise NotImplementedError('abstract method')
class Asm_Test(object): run_addr = 0x0 def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.init_stack() def test_init(self): pass def prepare(self): pass def __call__(self): self.prepare() self.asm() self.init_machine() self.test_init() self.run() self.check() def run(self): self.myjit.init_run(self.run_addr) self.myjit.continue_run() assert(self.myjit.pc == self.ret_addr) def asm(self): blocks, loc_db = parse_asm.parse_txt(mn_x86, self.arch_attrib, self.TXT, loc_db = self.myjit.ir_arch.loc_db) # fix shellcode addr loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_x86, blocks, loc_db) for offset, raw in viewitems(patches): s[offset] = raw s = bytes(s) self.assembly = s def check(self): raise NotImplementedError('abstract method')
# Container is superclass of ContainerELF, ContainerPE, etc. # Is container the analog of Binja's BinaryView? # # container.arch = 'x86_64' container = Container.from_string(data) # list all symbols / addresses available from the container ldb = container.loc_db for k in ldb.loc_keys: offset = ldb.get_location_offset(k) names = [x.decode() for x in ldb.get_location_names(k)] #print('%08X:' % offset) #for name in names: # print('\t"%s"' % name) # disassemble the given symbol machine = Machine(container.arch) disassembler = machine.dis_engine(container.bin_stream, loc_db=container.loc_db) sym_offs = resolve_symbol(container, sym_name) #print('%s is located at: 0x%X' % (sym_name, sym_offs)) # miasm.core.asmblock.AsmCFG cfg = disassembler.dis_multiblock(offset=sym_offs) print('```mermaid') print(cfg_to_mermaid(cfg)) print('```')
parser.add_argument("strategy", choices=["code-cov", "branch-cov", "path-cov"], help="Strategy to use for solution creation") args = parser.parse_args() # Convert strategy to the correct value strategy = { "code-cov": DSEPathConstraint.PRODUCE_SOLUTION_CODE_COV, "branch-cov": DSEPathConstraint.PRODUCE_SOLUTION_BRANCH_COV, "path-cov": DSEPathConstraint.PRODUCE_SOLUTION_PATH_COV, }[args.strategy] loc_db = LocationDB() # Map the shellcode run_addr = 0x40000 machine = Machine("x86_32") jitter = machine.jitter(loc_db, "python") with open(args.filename, "rb") as fdesc: jitter.vm.add_memory_page( run_addr, PAGE_READ | PAGE_WRITE, fdesc.read(), "Binary" ) # Expect a binary with one argument on the stack jitter.init_stack() # Argument jitter.push_uint32_t(0)
import sys from miasm.core.utils import decode_hex from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_ACCESS_VIOL from miasm.analysis.machine import Machine def code_sentinelle(jitter): jitter.run = False jitter.pc = 0 return True machine = Machine("x86_32") jitter = machine.jitter(sys.argv[1]) jitter.init_stack() # nop # mov eax, 0x42 # jmp 0x20 data = decode_hex("90b842000000eb20") # Will raise memory error at 0x40000028 error_raised = False def raise_me(jitter): global error_raised error_raised = True assert jitter.pc == 0x40000028 return False
parser.add_argument("-mems", type=str, default='', help="print [imm1],[reg1],[immN]") parser.add_argument("-function", dest="just_function", type=bool, default=False, help="disas only current function") parser.add_argument("-from_deep", type=int, default=-1, help="disas only deeper then N") parser.add_argument("-to_deep", type=int, default=-1, help="disas only not deeper then N") parser.add_argument("-ir", dest="ir", type=bool, default=False, help="print IR instead of disas") parser.add_argument("-anal", dest="anal", type=bool, default=False, help="print REGs access, MEMs access") parser.add_argument("-diff", type=str, default='', help="print difference between two traces") args = parser.parse_args() if args.ir: from miasm.core.locationdb import LocationDB from miasm.analysis.machine import Machine machine = Machine('x86_32') if args.diff: import difflib eips_a = [] eips_b = [] new_eips = [] lost_eips = [] with open(args.diff) as f: for line in f: if line.find('{') != -1: eips_a.append( line.split(':')[1] ) with open(args.tracefile) as f: for line in f: if line.find('{') != -1:
import json from future.utils import viewitems from miasm.analysis.machine import Machine from miasm.analysis.binary import Container from miasm.analysis.depgraph import DependencyGraph from miasm.expression.expression import ExprMem, ExprId, ExprInt parser = ArgumentParser("Dependency grapher") parser.add_argument("filename", help="Binary to analyse") parser.add_argument("func_addr", help="Function address") parser.add_argument("target_addr", help="Address to start") parser.add_argument("element", nargs="+", help="Elements to track") parser.add_argument("-m", "--architecture", help="Architecture (%s)" % Machine.available_machine()) parser.add_argument("-i", "--implicit", help="Use implicit tracking", action="store_true") parser.add_argument("--unfollow-mem", help="Stop on memory statements", action="store_true") parser.add_argument("--unfollow-call", help="Stop on call statements", action="store_true") parser.add_argument("--do-not-simplify", help="Do not simplify expressions", action="store_true") parser.add_argument("--rename-args", help="Rename common arguments (@32[ESP_init] -> Arg1)", action="store_true") parser.add_argument("--json", help="Output solution in JSON", action="store_true") args = parser.parse_args()
from optparse import OptionParser from pdb import pm from future.utils import viewitems from miasm.analysis.machine import Machine from miasm.analysis.binary import Container from miasm.expression.expression import ExprInt, ExprCond, ExprId, \ get_expr_ids, ExprAssign, ExprLoc from miasm.core.bin_stream import bin_stream_str from miasm.ir.symbexec import SymbolicExecutionEngine, get_block from miasm.expression.simplifications import expr_simp from miasm.core import parse_asm from miasm.ir.translators.translator import Translator machine = Machine("x86_32") parser = OptionParser(usage="usage: %prog [options] file") parser.add_option('-a', "--address", dest="address", metavar="ADDRESS", help="address to disasemble", default="0") (options, args) = parser.parse_args(sys.argv[1:]) if not args: parser.print_help() sys.exit(0) def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done): while states_todo: addr, symbols, conds = states_todo.pop()
class MyStruct(MemStruct): fields = [ # Number field: just struct.pack fields with one value ("num", Num("I")), ("flags", Num("B")), # This field is a pointer to another struct, it has a numeric # value (mystruct.other.val) and can be dereferenced to get an # OtherStruct instance (mystruct.other.deref) ("other", Ptr("I", OtherStruct)), # Ptr to a variable length String ("s", Ptr("I", Str())), ("i", Ptr("I", Num("I"))), ] jitter = Machine("x86_32").jitter("python") jitter.init_stack() addr = 0x1000 size = 0x1000 addr_str = 0x1100 addr_str2 = 0x1200 addr_str3 = 0x1300 # Initialize all mem with 0xaa jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, b"\xaa"*size) # MemStruct tests ## Creation # Use manual allocation with explicit addr for the first example mstruct = MyStruct(jitter.vm, addr) ## Fields are read from the virtual memory
from __future__ import print_function import sys from future.utils import viewvalues from miasm.analysis.binary import Container from miasm.analysis.machine import Machine ##################################### # Common section from dis_binary.py # ##################################### fdesc = open(sys.argv[1], 'rb') cont = Container.from_stream(fdesc) machine = Machine(cont.arch) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) addr = cont.entry_point asmcfg = mdis.dis_multiblock(addr) ##################################### # End common section # ##################################### # Get an IRA converter # The sub call are modelised by default operators # call_func_ret and call_func_stack ir_arch_analysis = machine.ira(mdis.loc_db)
from __future__ import print_function # Minimalist Symbol Exec example from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.ir.symbexec import SymbolicExecutionEngine from miasm.core.locationdb import LocationDB START_ADDR = 0 machine = Machine("x86_32") loc_db = LocationDB() # Assemble and disassemble a MOV ## Ensure that attributes 'offset' and 'l' are set line = machine.mn.fromstring("MOV EAX, EBX", loc_db, 32) asm = machine.mn.asm(line)[0] # Get back block cont = Container.from_string(asm, loc_db = loc_db) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) mdis.lines_wd = 1 asm_block = mdis.dis_block(START_ADDR) # Translate ASM -> IR ira = machine.ira(mdis.loc_db) ircfg = ira.new_ircfg() ira.add_asmblock_to_ircfg(asm_block, ircfg) # Instantiate a Symbolic Execution engine with default value for registers symb = SymbolicExecutionEngine(ira) # Emulate one IR basic block
def __init__(self, **kwargs): self.machine = Machine(self._ARCH_) self.jitter = self.machine.jitter(self.options.jitter)
from pdb import pm parser = ArgumentParser(description="x86 32 basic Jitter") parser.add_argument("filename", help="x86 32 shellcode filename") parser.add_argument("-j", "--jitter", help="Jitter engine (default is 'gcc')", default="gcc") args = parser.parse_args() def code_sentinelle(jitter): jitter.run = False jitter.pc = 0 return True myjit = Machine("x86_32").jitter(args.jitter) myjit.init_stack() data = open(args.filename, 'rb').read() run_addr = 0x40000000 myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) myjit.set_trace_log() myjit.push_uint32_t(0x1337beef) myjit.add_breakpoint(0x1337beef, code_sentinelle) myjit.init_run(run_addr) myjit.continue_run()
if args.verbose: syscall.log.setLevel(logging.DEBUG) # Get corresponding interpreter and reloc address cont_target_tmp = Container.from_stream(open(args.target, 'rb')) ld_path = bytes(cont_target_tmp.executable.getsectionbyname(".interp").content).strip(b"\x00") if cont_target_tmp.executable.Ehdr.type in [elf_csts.ET_REL, elf_csts.ET_DYN]: elf_base_addr = 0x40000000 elif cont_target_tmp.executable.Ehdr.type == elf_csts.ET_EXEC: elf_base_addr = 0 # Not relocatable else: raise ValueError("Unsupported type %d" % cont_target_tmp.executable.Ehdr.type) # Instantiate a jitter machine = Machine(cont_target_tmp.arch) jitter = machine.jitter(args.jitter) jitter.init_stack() # Get elements for the target architecture if cont_target_tmp.arch == "arml": LinuxEnvironment = environment.LinuxEnvironment_arml syscall_callbacks = syscall.syscall_callbacks_arml prepare_loader = environment.prepare_loader_arml elif cont_target_tmp.arch == "x86_64": LinuxEnvironment = environment.LinuxEnvironment_x86_64 syscall_callbacks = syscall.syscall_callbacks_x86_64 prepare_loader = environment.prepare_loader_x86_64 else: raise ValueError("Unsupported architecture: %r", cont_target_tmp.arch)
from miasm.arch.x86.arch import mn_x86 from miasm.core.locationdb import LocationDB from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.ir.symbexec import SymbolicExecutionEngine from miasm.analysis.dse import DSEEngine from miasm.expression.expression import * from miasm.ir.translators.z3_ir import Z3Mem, TranslatorZ3 loc_db = LocationDB() s = '\x8dI\x04\x8d[\x01\x80\xf9\x01t\x05\x8d[\xff\xeb\x03\x8d[\x01\x89\xd8\xc3' s = '\x55\x8b\xec\x83\xec\x08\xc7\x45\xf8\xcc\xcc\xcc\xcc\xc7\x45\xfc\xcc\xcc\xcc\xcc\xc7\x45\xfc\x03\x00\x00\x00\xc7\x45\xf8\x05\x00\x00\x00\x83\x7d\xfc\x05\x7e\x07\x8b\x45\xfc\xeb\x09\xeb\x05\x8b\x45\xf8\xeb\x02\x33\xc0\x8b\xe5\x5d\xc3' c = Container.from_string(s) machine = Machine('x86_32') mdis = machine.dis_engine(c.bin_stream) asmcfg = mdis.dis_multiblock(0) for block in asmcfg.blocks: print(block.to_string(asmcfg.loc_db)) ira = machine.ira(loc_db) ircfg = ira.new_ircfg_from_asmcfg(asmcfg) # print(ircfg) # ircfg = ira.new_ircfg(asmcfg) # print(loc_db._offset_to_loc_key.keys()[0]) sb = SymbolicExecutionEngine(ira) # symbolic_pc = sb.run_at(ircfg, loc_db._offset_to_loc_key.keys()[0]) # for index, info in enumerate(sb.info_ids): # print('###### step', index+1) # print('\t', info[0]) # for reg in info[1]:
from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.jitter.llvmconvert import LLVMType, LLVMContext_IRCompilation, LLVMFunction_IRCompilation from llvmlite import ir as llvm_ir from miasm.expression.simplifications import expr_simp_high_to_explicit from miasm.core.locationdb import LocationDB parser = ArgumentParser("LLVM export example") parser.add_argument("target", help="Target binary") parser.add_argument("addr", help="Target address") parser.add_argument("--architecture", "-a", help="Force architecture") args = parser.parse_args() loc_db = LocationDB() # This part focus on obtaining an IRCFG to transform # cont = Container.from_stream(open(args.target, 'rb'), loc_db) machine = Machine(args.architecture if args.architecture else cont.arch) lifter = machine.lifter(loc_db) dis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) asmcfg = dis.dis_multiblock(int(args.addr, 0)) ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) ircfg.simplify(expr_simp_high_to_explicit) ###################################################### # Instantiate a context and the function to fill context = LLVMContext_IRCompilation() context.lifter = lifter func = LLVMFunction_IRCompilation(context, name="test") func.ret_type = llvm_ir.VoidType() func.init_fc()
# check for unsat return solver.check() == unsat # hardcode file path and address file_path = "samples/ac3e087e43be67bdc674747c665b46c2" start_addr = 0x491aa0 # symbol table loc_db = LocationDB() # open the binary for analysis container = Container.from_stream(open(file_path, 'rb'), loc_db) # cpu abstraction machine = Machine(container.arch) # init disassemble engine mdis = machine.dis_engine(container.bin_stream, loc_db=loc_db) # initialize intermediate representation ira = machine.ira(mdis.loc_db) # disassemble the function at address asm_cfg = mdis.dis_multiblock(start_addr) # translate asm_cfg into ira_cfg ira_cfg = ira.new_ircfg_from_asmcfg(asm_cfg) # set opaque predicate counter opaque_counter = 0
from miasm.ir.ir import AssignBlock, IRBlock from miasm.analysis.simplifier import IRCFGSimplifierCommon, IRCFGSimplifierSSA log = logging.getLogger("dis") console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.INFO) parser = ArgumentParser("Disassemble a binary") parser.add_argument('filename', help="File to disassemble") parser.add_argument('address', help="Starting address for disassembly engine", nargs="*") parser.add_argument('-m', '--architecture', help="architecture: " + \ ",".join(Machine.available_machine())) parser.add_argument('-f', "--followcall", action="store_true", help="Follow call instructions") parser.add_argument('-b', "--blockwatchdog", default=None, type=int, help="Maximum number of basic block to disassemble") parser.add_argument('-n', "--funcswatchdog", default=None, type=int, help="Maximum number of function to disassemble") parser.add_argument('-r', "--recurfunctions", action="store_true", help="Disassemble founded functions") parser.add_argument('-v', "--verbose", action="count", help="Verbose mode", default=0) parser.add_argument('-g', "--gen_ir", action="store_true", help="Compute the intermediate representation") parser.add_argument('-z', "--dis-nulstart-block", action="store_true", help="Do not disassemble NULL starting block") parser.add_argument('-l', "--dontdis-retcall", action="store_true",
def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.stack_base = 0x1000 self.myjit.stack_size = 0x1000 self.myjit.init_stack()
from miasm.analysis.simplifier import IRCFGSimplifierCommon, IRCFGSimplifierSSA from miasm.core.locationdb import LocationDB log = logging.getLogger("dis") console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.INFO) parser = ArgumentParser("Disassemble a binary") parser.add_argument('filename', help="File to disassemble") parser.add_argument('address', help="Starting address for disassembly engine", nargs="*") parser.add_argument('-m', '--architecture', help="architecture: " + \ ",".join(Machine.available_machine())) parser.add_argument('-f', "--followcall", action="store_true", help="Follow call instructions") parser.add_argument('-b', "--blockwatchdog", default=None, type=int, help="Maximum number of basic block to disassemble") parser.add_argument('-n', "--funcswatchdog", default=None, type=int, help="Maximum number of function to disassemble") parser.add_argument('-r',
parser = ArgumentParser("DSE Example") parser.add_argument("filename", help="Target x86 shellcode") parser.add_argument("strategy", choices=["code-cov", "branch-cov", "path-cov"], help="Strategy to use for solution creation") args = parser.parse_args() # Convert strategy to the correct value strategy = { "code-cov": DSEPathConstraint.PRODUCE_SOLUTION_CODE_COV, "branch-cov": DSEPathConstraint.PRODUCE_SOLUTION_BRANCH_COV, "path-cov": DSEPathConstraint.PRODUCE_SOLUTION_PATH_COV, }[args.strategy] # Map the shellcode run_addr = 0x40000 machine = Machine("x86_32") jitter = machine.jitter("python") with open(args.filename, "rb") as fdesc: jitter.vm.add_memory_page( run_addr, PAGE_READ | PAGE_WRITE, fdesc.read(), "Binary" ) # Expect a binary with one argument on the stack jitter.init_stack() # Argument jitter.push_uint32_t(0)
#! /usr/bin/env python2 #-*- coding:utf-8 -*- import unittest import logging from miasm.analysis.machine import Machine import miasm.os_dep.linux_stdlib as stdlib from miasm.core.utils import pck32 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE machine = Machine("x86_32") jit = machine.jitter() jit.init_stack() heap = stdlib.linobjs.heap class TestLinuxStdlib(unittest.TestCase): def test_xxx_sprintf(self): def alloc_str(s): s += b"\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr fmt = alloc_str(b"'%s' %d") str_ = alloc_str(b"coucou") buf = heap.alloc(jit,1024) jit.push_uint32_t(1111) jit.push_uint32_t(str_)
from future.utils import viewitems from miasm.analysis.machine import Machine from miasm.analysis.binary import Container from miasm.analysis.depgraph import DependencyGraph from miasm.expression.expression import ExprMem, ExprId, ExprInt parser = ArgumentParser("Dependency grapher") parser.add_argument("filename", help="Binary to analyse") parser.add_argument("func_addr", help="Function address") parser.add_argument("target_addr", help="Address to start") parser.add_argument("element", nargs="+", help="Elements to track") parser.add_argument("-m", "--architecture", help="Architecture (%s)" % Machine.available_machine()) parser.add_argument("-i", "--implicit", help="Use implicit tracking", action="store_true") parser.add_argument("--unfollow-mem", help="Stop on memory statements", action="store_true") parser.add_argument("--unfollow-call", help="Stop on call statements", action="store_true") parser.add_argument("--do-not-simplify", help="Do not simplify expressions", action="store_true") parser.add_argument("--rename-args", help="Rename common arguments (@32[ESP_init] -> Arg1)",
import sys from pdb import pm from miasm.core.utils import decode_hex, encode_hex from miasm.jitter.csts import PAGE_READ, PAGE_WRITE from miasm.analysis.machine import Machine from miasm.expression.expression import ExprId, ExprAssign, ExprInt, ExprMem # Initial data: from 'example/samples/x86_32_sc.bin' data = decode_hex("8d49048d5b0180f90174058d5bffeb038d5b0189d8c3") # Init jitter myjit = Machine("x86_32").jitter(sys.argv[1]) myjit.init_stack() run_addr = 0x40000000 myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) # Sentinelle called on terminate def code_sentinelle(jitter): jitter.run = False jitter.pc = 0 return True myjit.push_uint32_t(0x1337beef) myjit.add_breakpoint(0x1337beef, code_sentinelle) # Run myjit.init_run(run_addr) myjit.continue_run()
import sys from miasm.core.utils import decode_hex from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_ACCESS_VIOL from miasm.analysis.machine import Machine def code_sentinelle(jitter): jitter.run = False jitter.pc = 0 return True machine = Machine("x86_32") jitter = machine.jitter(sys.argv[1]) jitter.init_stack() # nop # mov eax, 0x42 # jmp 0x20 data = decode_hex("90b842000000eb20") # Will raise memory error at 0x40000028 error_raised = False def raise_me(jitter): global error_raised error_raised = True
from __future__ import print_function from miasm.analysis.binary import Container from miasm.analysis.machine import Machine # The Container will provide a *bin_stream*, bytes source for the disasm engine cont = Container.from_string(b"\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3") # Instantiate a x86 32 bit architecture machine = Machine("x86_32") # Instantiate a disassembler engine, using the previous bin_stream and its # associated location DB. mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) # Run a recursive traversal disassembling from address 0 asmcfg = mdis.dis_multiblock(0) # Display each basic blocks for block in asmcfg.blocks: print(block) # Output control flow graph in a dot file open('str_cfg.dot', 'w').write(asmcfg.dot())
def get_str(jit, addr): data = jit.vm.get_mem(addr, 10) return data[:data.find(b'\x00')].decode('utf-8') def exception_int(jitter): print("SYSCALL {}".format(jitter.cpu.EAX)) jitter.cpu.set_exception(0) return True if __name__ == '__main__': parser = ArgumentParser(description="x86 64 basic Jitter") parser.add_argument("filename", help="x86 64 shellcode filename") parser.add_argument("-j", "--jitter", help="Jitter engine", default="python") args = parser.parse_args() myjit = Machine("x86_64").jitter(args.jitter) myjit.init_stack() data = open(args.filename, 'rb').read() run_addr = 0x40000000 myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) #myjit.set_trace_log() myjit.add_exception_handler(EXCEPT_SYSCALL, exception_int) myjit.run(run_addr)
import sys from miasm.core.utils import decode_hex from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_UNK_MNEMO from miasm.analysis.machine import Machine from miasm.core.locationdb import LocationDB def code_sentinelle(jitter): jitter.running = False jitter.pc = 0 return True machine = Machine("x86_32") loc_db = LocationDB() jitter = machine.jitter(loc_db, sys.argv[1]) jitter.init_stack() # nop # mov eax, 0x42 # XX data = decode_hex("90b842000000ffff90909090") # Will raise memory error at 0x40000006 error_raised = False def raise_me(jitter): global error_raised
def __init__(self, jitter_engine): self.myjit = Machine(self.arch_name).jitter(jitter_engine) self.myjit.init_stack()