diff options
Diffstat (limited to 'example')
| -rwxr-xr-x | example/asm/shellcode.py | 5 | ||||
| -rw-r--r-- | example/disasm/single_instr.py | 4 | ||||
| -rw-r--r-- | example/expression/get_read_write.py | 16 | ||||
| -rw-r--r-- | example/expression/solve_condition_stp.py | 46 | ||||
| -rw-r--r-- | example/ida/ctype_propagation.py | 120 | ||||
| -rw-r--r-- | example/ida/graph_ir.py | 4 | ||||
| -rw-r--r-- | example/symbol_exec/single_instr.py | 8 |
7 files changed, 138 insertions, 65 deletions
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py index bacb65fb..0c08a8a3 100755 --- a/example/asm/shellcode.py +++ b/example/asm/shellcode.py @@ -64,7 +64,10 @@ else: with open(args.source) as fstream: source = fstream.read() -blocks, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source) + +symbol_pool = asmblock.AsmSymbolPool() + +blocks, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source, symbol_pool) # Fix shellcode addrs symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main) diff --git a/example/disasm/single_instr.py b/example/disasm/single_instr.py index 0e29dcee..59b81de7 100644 --- a/example/disasm/single_instr.py +++ b/example/disasm/single_instr.py @@ -1,7 +1,9 @@ from miasm2.arch.x86.arch import mn_x86 from miasm2.arch.x86.regs import EDX +from miasm2.core.asmblock import AsmSymbolPool -l = mn_x86.fromstring('MOV EAX, EBX', 32) +symbol_pool = AsmSymbolPool() +l = mn_x86.fromstring('MOV EAX, EBX', symbol_pool, 32) print "instruction:", l print "arg:", l.args[0] x = mn_x86.asm(l) diff --git a/example/expression/get_read_write.py b/example/expression/get_read_write.py index b4a0773b..9e3b5caf 100644 --- a/example/expression/get_read_write.py +++ b/example/expression/get_read_write.py @@ -1,6 +1,9 @@ from miasm2.arch.x86.arch import mn_x86 from miasm2.expression.expression import get_rw from miasm2.arch.x86.ira import ir_a_x86_32 +from miasm2.core.asmblock import AsmSymbolPool + +symbol_pool = AsmSymbolPool() print """ @@ -11,17 +14,18 @@ Get read/written registers for a given instruction arch = mn_x86 ir_arch = ir_a_x86_32() -l = arch.fromstring('LODSB', 32) +l = arch.fromstring('LODSB', symbol_pool, 32) l.offset, l.l = 0, 15 ir_arch.add_instr(l) print '*' * 80 -for lbl, irblock in ir_arch.blocks.items(): +for lbl, irblock in ir_arch.blocks.iteritems(): print irblock for assignblk in irblock: - o_r, o_w = get_rw(assignblk) - print 'read: ', [str(x) for x in o_r] - print 'written:', [str(x) for x in o_w] - print + rw = assignblk.get_rw() + for dst, reads in rw.iteritems(): + print 'read: ', [str(x) for x in reads] + print 'written:', dst + print open('graph_instr.dot', 'w').write(ir_arch.graph.dot()) diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py index 44b73043..201d9f26 100644 --- a/example/expression/solve_condition_stp.py +++ b/example/expression/solve_condition_stp.py @@ -6,7 +6,6 @@ from pdb import pm from miasm2.analysis.machine import Machine from miasm2.expression.expression import ExprInt, ExprCond, ExprId, \ get_expr_ids, ExprAff -from miasm2.arch.x86.arch import ParseAst from miasm2.core.bin_stream import bin_stream_str from miasm2.core import asmblock from miasm2.ir.symbexec import SymbolicExecutionEngine, get_block @@ -50,7 +49,6 @@ def emul_symb(ir_arch, mdis, states_todo, states_done): symbexec.dump(mems=False) assert addr is not None - if isinstance(addr, ExprCond): # Create 2 states, each including complementary conditions cond_group_a = {addr.cond: ExprInt(0, addr.cond.size)} @@ -67,15 +65,15 @@ def emul_symb(ir_arch, mdis, states_todo, states_done): addr_b = int(addr_b.arg) states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + cond_group_a.items()))) states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items()))) + elif addr == ret_addr: + print 'Return address reached' + continue elif isinstance(addr, ExprInt): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif asmblock.expr_is_label(addr): addr = addr.name states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) - elif addr == ret_addr: - print 'Return address reached' - continue else: raise ValueError("Unsupported destination") @@ -92,32 +90,6 @@ if __name__ == '__main__': symbols_init = dict(machine.mn.regs.regs_init) - # config parser for 32 bit - reg_and_id = dict(machine.mn.regs.all_regs_ids_byname) - - def my_ast_int2expr(name): - return ExprInt(name, 32) - - # Modifify parser to avoid label creation in PUSH argc - def my_ast_id2expr(string_parsed): - if string_parsed in reg_and_id: - return reg_and_id[string_parsed] - return ExprId(string_parsed, size=32) - - my_var_parser = ParseAst(my_ast_id2expr, my_ast_int2expr) - machine.base_expr.setParseAction(my_var_parser) - - argc = ExprId('argc', 32) - argv = ExprId('argv', 32) - ret_addr = ExprId('ret_addr', 32) - reg_and_id[argc.name] = argc - reg_and_id[argv.name] = argv - reg_and_id[ret_addr.name] = ret_addr - - my_symbols = [argc, argv, ret_addr] - my_symbols = dict([(x.name, x) for x in my_symbols]) - my_symbols.update(machine.mn.regs.all_regs_ids_byname) - ir_arch = machine.ir(mdis.symbol_pool) symbexec = SymbolicExecutionEngine(ir_arch, symbols_init) @@ -126,7 +98,17 @@ if __name__ == '__main__': PUSH argv PUSH argc PUSH ret_addr - ''') + ''', + symbol_pool=mdis.symbol_pool) + + + argc_lbl = symbol_pool.getby_name('argc') + argv_lbl = symbol_pool.getby_name('argv') + ret_addr_lbl = symbol_pool.getby_name('ret_addr') + + argc = ExprId(argc_lbl, 32) + argv = ExprId(argv_lbl, 32) + ret_addr = ExprId(ret_addr_lbl, 32) b = list(blocks)[0] diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index b2c7d5ab..9b9c2e95 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -1,6 +1,3 @@ -import os -import tempfile - import ida_kernwin import idc import ida_funcs @@ -8,17 +5,14 @@ import ida_funcs from miasm2.core.bin_stream_ida import bin_stream_ida from miasm2.expression import expression as m2_expr from miasm2.expression.simplifications import expr_simp -from miasm2.analysis.depgraph import DependencyGraph from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.arch.x86.ctype import CTypeAMD64_unk, CTypeX86_unk from miasm2.arch.msp430.ctype import CTypeMSP430_unk -from miasm2.expression.expression import ExprId from miasm2.core.objc import CTypesManagerNotPacked, ExprToAccessC, CHandler from miasm2.core.ctypesmngr import CAstTypes -from miasm2.expression.expression import ExprMem, ExprId, ExprInt, ExprOp, ExprAff +from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprAff from miasm2.ir.symbexec_types import SymbExecCType from miasm2.expression.parser import str_to_expr -from miasm2.ir.symbexec import SymbolicExecutionEngine, SymbolicState from miasm2.analysis.cst_propag import add_state, propagate_cst_expr from utils import guess_machine @@ -32,27 +26,96 @@ class TypePropagationForm(ida_kernwin.Form): default_types_info = r"""ExprId("RDX", 64): char *""" archs = ["AMD64_unk", "X86_32_unk", "msp430_unk"] + func = ida_funcs.get_func(idc.ScreenEA()) + func_addr = func.startEA + + start_addr = idc.SelStart() + if start_addr == idc.BADADDR: + start_addr = idc.ScreenEA() + end_addr = idc.SelEnd() + ida_kernwin.Form.__init__(self, r"""BUTTON YES* Launch BUTTON CANCEL NONE -Dependency Graph Settings -<##Header file :{headerFile}> -<Architecture/complator:{arch}> -<Types informations:{strTypesInfo}> +Type Propagation Settings + +{FormChangeCb} +Analysis scope: +<Whole function:{rFunction}> +<From an address to the end of function:{rAddr}> +<Between two addresses:{r2Addr}>{cScope}> + +<Target function:{functionAddr}> +<Start address :{startAddr}> +<End address :{endAddr}> + +<Architecture/compilator :{arch}> + +<##Header file :{headerFile}> +<Use a file for type informations:{rTypeFile}>{cTypeFile}> +<##Types informations :{typeFile}> +<Types informations :{strTypesInfo}> + <Unalias stack:{rUnaliasStack}>{cUnalias}> """, { - 'headerFile': ida_kernwin.Form.FileInput(swidth=20, open=True), + 'FormChangeCb': ida_kernwin.Form.FormChangeCb(self.OnFormChange), + 'cScope': ida_kernwin.Form.RadGroupControl( + ("rFunction", "rAddr", "r2Addr")), + 'functionAddr': ida_kernwin.Form.NumericInput( + tp=ida_kernwin.Form.FT_RAWHEX, + value=func_addr), + 'startAddr': ida_kernwin.Form.NumericInput( + tp=ida_kernwin.Form.FT_RAWHEX, + value=start_addr), + 'endAddr': ida_kernwin.Form.NumericInput( + tp=ida_kernwin.Form.FT_RAWHEX, + value=end_addr), 'arch': ida_kernwin.Form.DropdownListControl( items=archs, readonly=False, selval=archs[0]), + 'headerFile': ida_kernwin.Form.FileInput(swidth=20, open=True), + 'cTypeFile': ida_kernwin.Form.ChkGroupControl(("rTypeFile",)), + 'typeFile': ida_kernwin.Form.FileInput(swidth=20, open=True), 'strTypesInfo': ida_kernwin.Form.MultiLineTextControl(text=default_types_info, flags=ida_kernwin.Form.MultiLineTextControl.TXTF_FIXEDFONT), 'cUnalias': ida_kernwin.Form.ChkGroupControl(("rUnaliasStack",)), }) form, args = self.Compile() form.rUnaliasStack.checked = True - + form.rTypeFile.checked = True + + def OnFormChange(self, fid): + if fid == -1: # INIT + self.EnableField(self.functionAddr, True) + self.EnableField(self.startAddr, False) + self.EnableField(self.endAddr, False) + self.EnableField(self.strTypesInfo, False) + self.EnableField(self.typeFile, True) + elif fid == self.cTypeFile.id: + if self.GetControlValue(self.cTypeFile) == 0: + self.EnableField(self.strTypesInfo, True) + self.EnableField(self.typeFile, False) + elif self.GetControlValue(self.cTypeFile) == 1: + self.EnableField(self.strTypesInfo, False) + self.EnableField(self.typeFile, True) + elif fid == self.cScope.id: + # "Whole function" scope + if self.GetControlValue(self.cScope) == 0: + self.EnableField(self.functionAddr, True) + self.EnableField(self.startAddr, False) + self.EnableField(self.endAddr, False) + # "From an address" scope + elif self.GetControlValue(self.cScope) == 1: + self.EnableField(self.functionAddr, False) + self.EnableField(self.startAddr, True) + self.EnableField(self.endAddr, False) + # "Between two addresses" scope + elif self.GetControlValue(self.cScope) == 2: + self.EnableField(self.functionAddr, False) + self.EnableField(self.startAddr, True) + self.EnableField(self.endAddr, True) + return 1 def get_types_mngr(headerFile, arch): text = open(headerFile).read() @@ -193,21 +256,25 @@ def analyse_function(): ir_arch = iraCallStackFixer(mdis.symbol_pool) - # Get the current function - func = ida_funcs.get_func(idc.ScreenEA()) - addr = func.startEA - blocks = mdis.dis_multiblock(addr) - # Generate IR - for block in blocks: - ir_arch.add_block(block) - - # Get settings settings = TypePropagationForm(ir_arch) ret = settings.Execute() if not ret: return + if settings.cScope.value == 0: + addr = settings.functionAddr.value + else: + addr = settings.startAddr.value + if settings.cScope.value == 2: + end = settings.endAddr + mdis.dont_dis = [end] + + blocks = mdis.dis_multiblock(addr) + # Generate IR + for block in blocks: + ir_arch.add_block(block) + cst_propag_link = {} if settings.cUnalias.value: init_infos = {ir_arch.sp: ir_arch.arch.regs.regs_init[ir_arch.sp] } @@ -217,7 +284,14 @@ def analyse_function(): types_mngr = get_types_mngr(settings.headerFile.value, settings.arch.value) mychandler = MyCHandler(types_mngr, {}) infos_types = {} - for line in settings.strTypesInfo.value.split('\n'): + infos_types_raw = [] + + if settings.cTypeFile.value: + infos_types_raw = open(settings.typeFile.value).read().split('\n') + else: + infos_types_raw = settings.strTypesInfo.value.split('\n') + + for line in infos_types_raw: if not line: continue expr_str, ctype_str = line.split(':') diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py index 7e303aac..6dfa1f7d 100644 --- a/example/ida/graph_ir.py +++ b/example/ida/graph_ir.py @@ -121,6 +121,10 @@ def build_graph(verbose=False, simplify=False): # print hex(ad), repr(name) if name is None: continue + if (mdis.symbol_pool.getby_offset(addr) or + mdis.symbol_pool.getby_name(name)): + # Symbol alias + continue mdis.symbol_pool.add_label(name, addr) if verbose: diff --git a/example/symbol_exec/single_instr.py b/example/symbol_exec/single_instr.py index e5637ad8..22a48fc6 100644 --- a/example/symbol_exec/single_instr.py +++ b/example/symbol_exec/single_instr.py @@ -2,18 +2,22 @@ from miasm2.core.bin_stream import bin_stream_str from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.analysis.machine import Machine +from miasm2.core.asmblock import AsmSymbolPool START_ADDR = 0 machine = Machine("x86_32") +symbol_pool = AsmSymbolPool() + + # Assemble and disassemble a MOV ## Ensure that attributes 'offset' and 'l' are set -line = machine.mn.fromstring("MOV EAX, EBX", 32) +line = machine.mn.fromstring("MOV EAX, EBX", symbol_pool, 32) asm = machine.mn.asm(line)[0] # Get back block bin_stream = bin_stream_str(asm) -mdis = machine.dis_engine(bin_stream) +mdis = machine.dis_engine(bin_stream, symbol_pool=symbol_pool) mdis.lines_wd = 1 asm_block = mdis.dis_block(START_ADDR) |