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 sym(data, addr, status): cont = Container.from_string(data, loc_db=loc_db, addr=addr) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) asm_block = mdis.dis_block(addr) # Translate ASM -> IR ircfg = ira.new_ircfg() try: ira.add_asmblock_to_ircfg(asm_block, ircfg) except NotImplementedError: return None # Instantiate a Symbolic Execution engine with default value for registers regs_init = regs.regs_init sympool = copy.deepcopy(regs_init) sympool.update(status) symb = SymbolicExecutionEngine(ira, sympool) # Emulate one IR basic block ## Emulation of several basic blocks can be done through .emul_ir_blocks cur_addr = symb.run_at(ircfg, addr) IRDst = symb.symbols[ira.IRDst] expr = expr_simp_explicit(IRDst) #if isinstance(expr, ExprMem): # expr = expr.ptr return expr
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))
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 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!")
from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_32 from miasm.core.asmblock import AsmCFG from miasm.core.locationdb import LocationDB from miasm.expression.simplifications import expr_simp loc_db = LocationDB() cont = Container.from_stream(open("crackme0x02", "rb"), loc_db) machine = Machine(cont.arch) # --- Disassemble --- # mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db, follow_call=True) # Disassemble at the block that checks the key entry_addr = 0x804842B asmcfg = mdis.dis_multiblock(entry_addr) # Write Graphviz open("cfg.dot", "w").write(asmcfg.dot()) # --- Get IR --- # lifter = LifterModelCall_x86_32(loc_db) ircfg = lifter.new_ircfg() first_block = list(asmcfg.blocks)[0] lifter.add_asmblock_to_ircfg(first_block, ircfg) # --- Symbolic execution --- #
merge_blocks, remove_empty_assignblks from miasm.expression.simplifications import expr_simp parser = ArgumentParser("Constant expression propagation") parser.add_argument('filename', help="File to analyze") parser.add_argument('address', help="Starting address for disassembly engine") parser.add_argument('-s', "--simplify", action="store_true", help="Apply simplifications rules (liveness, graph simplification, ...)") args = parser.parse_args() machine = Machine("x86_32") cont = Container.from_stream(open(args.filename, 'rb')) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ir_arch = machine.ira(mdis.loc_db) addr = int(args.address, 0) asmcfg = mdis.dis_multiblock(addr) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) entry_points = set([mdis.loc_db.get_offset_location(addr)]) init_infos = ir_arch.arch.regs.regs_init cst_propag_link = propagate_cst_expr(ir_arch, ircfg, addr, init_infos) if args.simplify: ircfg.simplify(expr_simp) modified = True while modified:
#!/usr/bin/python3 from miasm.analysis.binary import Container from miasm.analysis.machine import Machine from miasm.core.locationdb import LocationDB from miasm.ir.symbexec import SymbolicExecutionEngine start_addr = 0x402300 loc_db = LocationDB() target_file = open("hello_world.exe", 'rb') container = Container.from_stream(target_file, loc_db) machine = Machine(container.arch) mdis = machine.dis_engine(container.bin_stream, loc_db=loc_db) ira = machine.ira(mdis.loc_db) asm_cfg = mdis.dis_multiblock(start_addr) ira_cfg = ira.new_ircfg_from_asmcfg(asm_cfg) symbex = SymbolicExecutionEngine(ira) symbex_state = symbex.run_block_at(ira_cfg, start_addr) print(symbex_state)
from argparse import ArgumentParser 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()
"Use only with --propagexpr option. " "WARNING: not reliable, may fail.") parser.add_argument('-e', "--loadint", action="store_true", help="Load integers from binary in fixed memory lookup.") parser.add_argument('-j', "--calldontmodstack", action="store_true", help="Consider stack high is not modified in subcalls") args = parser.parse_args() if args.verbose: log_asmblock.setLevel(logging.DEBUG) log.info('Load binary') if args.rawbinary: cont = Container.fallback_container(open(args.filename, "rb").read(), vm=None, addr=args.base_address) else: with open(args.filename, "rb") as fdesc: cont = Container.from_stream(fdesc, addr=args.base_address) default_addr = cont.entry_point bs = cont.bin_stream e = cont.executable log.info('ok') log.info("import machine...") # Use the guessed architecture or the specified one arch = args.architecture if args.architecture else cont.arch if not arch: print("Architecture recognition fail. Please specify it in arguments") exit(-1)
# add constraint solver.add( translator.from_expr(expression) == translator.from_expr(jump_target)) # 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)
fpath = '../testbins/tests-linux-x64-elf' if sys.argv[1:]: fpath = sys.argv[1] sym_name = 'collatz_message' if sys.argv[2:]: sym_name = sys.argv[2] with open(fpath, 'rb') as fp: data = fp.read() # 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)
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())
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)
parser = ArgumentParser("Constant expression propagation") parser.add_argument('filename', help="File to analyze") parser.add_argument('address', help="Starting address for disassembly engine") parser.add_argument( '-s', "--simplify", action="store_true", help="Apply simplifications rules (liveness, graph simplification, ...)") args = parser.parse_args() machine = Machine("x86_32") loc_db = LocationDB() cont = Container.from_stream(open(args.filename, 'rb'), loc_db) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) ir_arch = machine.ira(mdis.loc_db) addr = int(args.address, 0) deadrm = DeadRemoval(ir_arch) asmcfg = mdis.dis_multiblock(addr) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) entry_points = set([mdis.loc_db.get_offset_location(addr)]) init_infos = ir_arch.arch.regs.regs_init cst_propag_link = propagate_cst_expr(ir_arch, ircfg, addr, init_infos) if args.simplify: ircfg.simplify(expr_simp) modified = True
"--passthrough", help="Reg-exp for passthrough files", default="^$") parser.add_argument("-f", "--flags", help="Flags") parser.add_argument("-v", "--verbose", action="store_true", help="Activate verbose syscalls") args = parser.parse_args() if args.verbose: syscall.log.setLevel(logging.DEBUG) loc_db = LocationDB() # Get corresponding interpreter and reloc address cont_target_tmp = Container.from_stream(open(args.target, 'rb'), loc_db) 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(loc_db, args.jitter) jitter.init_stack()
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 ## Emulation of several basic blocks can be done through .emul_ir_blocks cur_addr = symb.run_at(ircfg, START_ADDR)
from pdb import pm from future.utils import viewitems from miasm.core.utils import decode_hex from miasm.analysis.machine import Machine from miasm.analysis.binary import Container from miasm.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \ AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \ bbl_simplifier from miasm.core.graph import DiGraphSimplifier, MatchGraphJoker from miasm.expression.expression import ExprId # Initial data: from 'samples/simple_test.bin' data = decode_hex("5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3") cont = Container.from_string(data) # Test Disasm engine machine = Machine("x86_32") mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ## Disassembly of one block first_block = mdis.dis_block(0) assert len(first_block.lines) == 5 print(first_block) ## Test redisassemble asmcfg first_block_bis = mdis.dis_block(0) assert len(first_block.lines) == len(first_block_bis.lines) print(first_block_bis) ## Disassembly of several block, with cache
# Update next blocks to process in the disassembly engine cur_bloc.bto.clear() cur_bloc.add_cst(loc_key, AsmConstraint.c_next) # Prepare a tiny shellcode shellcode = ( b"\xe8\x00\x00\x00\x00" # CALL $ b"X" # POP EAX b"\xc3" # RET ) # Instantiate a x86 32 bit architecture machine = Machine("x86_32") cont = Container.from_string(shellcode) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) print("Without callback:\n") asmcfg = mdis.dis_multiblock(0) print("\n".join(str(block) for block in asmcfg.blocks)) # Enable callback mdis.dis_block_callback = cb_x86_callpop print("=" * 40) print("With callback:\n") asmcfg_after = mdis.dis_multiblock(0) print("\n".join(str(block) for block in asmcfg_after.blocks)) # Ensure the callback has been called
}; struct ll_human { struct ll_human* next; struct human human; }; """ base_types = CTypeAMD64_unk() types_ast = CAstTypes() types_ast.add_c_decl(text) types_mngr = CTypesManagerNotPacked(types_ast, base_types) # Analyze binary cont = Container.fallback_container(data, None, addr=0) machine = Machine("x86_64") dis_engine, ira = machine.dis_engine, machine.ira mdis = dis_engine(cont.bin_stream, loc_db=cont.loc_db) addr_head = 0 asmcfg = mdis.dis_multiblock(addr_head) lbl_head = mdis.loc_db.get_offset_location(addr_head) ir_arch_a = ira(mdis.loc_db) ircfg = ir_arch_a.new_ircfg_from_asmcfg(asmcfg) open('graph_irflow.dot', 'w').write(ircfg.dot()) # Main function's first argument's type is "struct ll_human*"
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 lifter_model_call = machine.lifter_model_call(mdis.loc_db) ircfg = lifter_model_call.new_ircfg() lifter_model_call.add_asmblock_to_ircfg(asm_block, ircfg) # Instantiate a Symbolic Execution engine with default value for registers symb = SymbolicExecutionEngine(lifter_model_call) # Emulate one IR basic block ## Emulation of several basic blocks can be done through .emul_ir_blocks cur_addr = symb.run_at(ircfg, START_ADDR)
parser.add_argument("target", help="Target ELF") parser.add_argument("extra_args", help="Arguments for the target ELF", nargs="*", default=[]) parser.add_argument("-j", "--jitter", help="Jitter engine", default="llvm") parser.add_argument("-p", "--passthrough", help="Reg-exp for passthrough files", default="^$") parser.add_argument("-f", "--flags", help="Flags") parser.add_argument("-v", "--verbose", action="store_true", help="Activate verbose syscalls") args = parser.parse_args() 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":
elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination") if __name__ == '__main__': translator_smt2 = Translator.to_language("smt2") addr = int(options.address, 16) cont = Container.from_stream(open(args[0], 'rb')) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ir_arch = machine.ir(mdis.loc_db) ircfg = ir_arch.new_ircfg() symbexec = SymbolicExecutionEngine(ir_arch) asmcfg, loc_db = parse_asm.parse_txt(machine.mn, 32, ''' init: PUSH argv PUSH argc PUSH ret_addr ''', loc_db=mdis.loc_db) argc_lbl = loc_db.get_name_location('argc')
hdr_rom_size = gb_header[0x48] hdr_ram_size = gb_header[0x49] hdr_destination_code = gb_header[0x4A] hdr_old_licensee_code = gb_header[0x4B] hdr_mask_rom_version_number = gb_header[0x4C] hdr_header_checksum = gb_header[0x4D] calculated_header_checksum = 0 for i in range(0x34, 0x4D): calculated_header_checksum = (calculated_header_checksum - gb_header[i] - 1) & 0xFF if calculated_header_checksum != hdr_header_checksum: log.debug('Gameboy header checksum does not match: %02x != %02x', calculated_header_checksum, hdr_header_checksum) raise ContainerSignatureException() hdr_global_checksum = struct.unpack('>H', gb_header[0x4E:0x50])[0] calculated_global_checksum = (sum(data[:0x14E])+sum(data[0x150:])) & 0xFFFF if calculated_global_checksum != hdr_global_checksum: log.warn('Global checksum does not match: %04x != %04x', calculated_global_checksum, hdr_global_checksum) if not ignore_checksum: raise ContainerSignatureException() self._executable = None self._bin_stream = None self._entry_point = 0x100 self._arch = None #self._loc_db = None Container.register_container(ContainerGameboyROM)
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())
elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination") if __name__ == '__main__': loc_db = LocationDB() translator_smt2 = Translator.to_language("smt2") addr = int(options.address, 16) cont = Container.from_stream(open(args[0], 'rb'), loc_db) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) lifter = machine.lifter(mdis.loc_db) ircfg = lifter.new_ircfg() symbexec = SymbolicExecutionEngine(lifter) asmcfg = parse_asm.parse_txt( machine.mn, 32, ''' init: PUSH argv PUSH argc PUSH ret_addr ''', loc_db )
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() loc_db = LocationDB() # Get architecture with open(args.filename, "rb") as fstream: cont = Container.from_stream(fstream, loc_db) arch = args.architecture if args.architecture else cont.arch machine = Machine(arch) # Check elements elements = set() regs = machine.mn.regs.all_regs_ids_byname for element in args.element: try: elements.add(regs[element]) except KeyError: raise ValueError("Unknown element '%s'" % element) mdis = machine.dis_engine(cont.bin_stream, dont_dis_nulstart_bloc=True,
import z3 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])
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() # Get architecture with open(args.filename, "rb") as fstream: cont = Container.from_stream(fstream) arch = args.architecture if args.architecture else cont.arch machine = Machine(arch) # Check elements elements = set() regs = machine.mn.regs.all_regs_ids_byname for element in args.element: try: elements.add(regs[element]) except KeyError: raise ValueError("Unknown element '%s'" % element) mdis = machine.dis_engine(cont.bin_stream, dont_dis_nulstart_bloc=True) ir_arch = machine.ira(mdis.loc_db)
"""This example illustrate the Sandbox.call API, for direct call of a given function""" from miasm.analysis.sandbox import Sandbox_Linux_arml from miasm.analysis.binary import Container from miasm.os_dep.linux_stdlib import linobjs from miasm.core.utils import hexdump from miasm.core.locationdb import LocationDB # Parse arguments parser = Sandbox_Linux_arml.parser(description="ELF sandboxer") parser.add_argument("filename", help="ELF Filename") options = parser.parse_args() loc_db = LocationDB() sb = Sandbox_Linux_arml(loc_db, options.filename, options, globals()) with open(options.filename, "rb") as fdesc: cont = Container.from_stream(fdesc, loc_db) loc_key = cont.loc_db.get_name_location("md5_starts") addr_to_call = cont.loc_db.get_location_offset(loc_key) # Calling md5_starts(malloc(0x64)) addr = linobjs.heap.alloc(sb.jitter, 0x64) sb.call(addr_to_call, addr) hexdump(sb.jitter.vm.get_mem(addr, 0x64))
from miasm.core.utils import decode_hex from miasm.analysis.machine import Machine from miasm.analysis.binary import Container from miasm.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \ AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \ bbl_simplifier from miasm.core.graph import DiGraphSimplifier, MatchGraphJoker from miasm.expression.expression import ExprId from miasm.core.locationdb import LocationDB # Initial data: from 'samples/simple_test.bin' data = decode_hex( "5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3" ) loc_db = LocationDB() cont = Container.from_string(data, loc_db) # Test Disasm engine machine = Machine("x86_32") mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) ## Disassembly of one block first_block = mdis.dis_block(0) assert len(first_block.lines) == 5 print(first_block) ## Test redisassemble asmcfg first_block_bis = mdis.dis_block(0) assert len(first_block.lines) == len(first_block_bis.lines) print(first_block_bis) ## Disassembly of several block, with cache
}; struct ll_human { struct ll_human* next; struct human human; }; """ base_types = CTypeAMD64_unk() types_ast = CAstTypes() types_ast.add_c_decl(text) types_mngr = CTypesManagerNotPacked(types_ast, base_types) # Analyze binary cont = Container.fallback_container(data, None, addr=0) machine = Machine("x86_64") dis_engine, ira = machine.dis_engine, machine.ira mdis = dis_engine(cont.bin_stream, loc_db=loc_db) addr_head = 0 asmcfg = mdis.dis_multiblock(addr_head) lbl_head = loc_db.get_offset_location(addr_head) ir_arch_a = ira(loc_db) ircfg = ir_arch_a.new_ircfg_from_asmcfg(asmcfg) open('graph_irflow.dot', 'w').write(ircfg.dot()) # Main function's first argument's type is "struct ll_human*"
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() # Get architecture with open(args.filename, "rb") as fstream: cont = Container.from_stream(fstream) arch = args.architecture if args.architecture else cont.arch machine = Machine(arch) # Check elements elements = set() regs = machine.mn.regs.all_regs_ids_byname for element in args.element: try: elements.add(regs[element]) except KeyError: raise ValueError("Unknown element '%s'" % element) mdis = machine.dis_engine(cont.bin_stream, dont_dis_nulstart_bloc=True) ir_arch = machine.ira(mdis.loc_db)
# Update next blocks to process in the disassembly engine cur_bloc.bto.clear() cur_bloc.add_cst(loc_key, AsmConstraint.c_next) # Prepare a tiny shellcode shellcode = ( b"\xe8\x00\x00\x00\x00" # CALL $ b"X" # POP EAX b"\xc3" # RET ) # Instantiate a x86 32 bit architecture machine = Machine("x86_32") loc_db = LocationDB() cont = Container.from_string(shellcode, loc_db) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) print("Without callback:\n") asmcfg = mdis.dis_multiblock(0) print("\n".join(str(block) for block in asmcfg.blocks)) # Enable callback mdis.dis_block_callback = cb_x86_callpop print("=" * 40) print("With callback:\n") asmcfg_after = mdis.dis_multiblock(0) print("\n".join(str(block) for block in asmcfg_after.blocks)) # Ensure the callback has been called
parser.add_argument('-j', "--calldontmodstack", action="store_true", help="Consider stack high is not modified in subcalls") args = parser.parse_args() if args.verbose: log_asmblock.setLevel(logging.DEBUG) loc_db = LocationDB() log.info('Load binary') if args.rawbinary: cont = Container.fallback_container( open(args.filename, "rb").read(), vm=None, addr=args.base_address, loc_db=loc_db, ) else: with open(args.filename, "rb") as fdesc: cont = Container.from_stream( fdesc, addr=args.base_address, loc_db=loc_db, ) default_addr = cont.entry_point bs = cont.bin_stream e = cont.executable log.info('ok')
from argparse import ArgumentParser 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 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() # This part focus on obtaining an IRCFG to transform # cont = Container.from_stream(open(args.target, 'rb')) machine = Machine(args.architecture if args.architecture else cont.arch) ir = machine.ir(cont.loc_db) dis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) asmcfg = dis.dis_multiblock(int(args.addr, 0)) ircfg = ir.new_ircfg_from_asmcfg(asmcfg) ircfg.simplify(expr_simp_high_to_explicit) ###################################################### # Instantiate a context and the function to fill context = LLVMContext_IRCompilation() context.ir_arch = ir func = LLVMFunction_IRCompilation(context, name="test") func.ret_type = llvm_ir.VoidType() func.init_fc()