diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2017-08-06 00:46:32 +0200 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2017-08-08 09:25:56 +0200 |
| commit | 4b200beb1bda68ee94844a81bd9d618da634f8e9 (patch) | |
| tree | 4f37057224ba4a26108a699a43bb740adb072571 /example/ida | |
| parent | 9ada9bd6b907d47b5819a0f96d386578a9da91a1 (diff) | |
| download | miasm-4b200beb1bda68ee94844a81bd9d618da634f8e9.tar.gz miasm-4b200beb1bda68ee94844a81bd9d618da634f8e9.zip | |
Example: update api
Diffstat (limited to 'example/ida')
| -rw-r--r-- | example/ida/ctype_propagation.py | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index cb342213..5b23e6a8 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -10,13 +10,14 @@ 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 +from miasm2.arch.x86.ctype import CTypeAMD64_unk, CTypeX86_unk from miasm2.expression.expression import ExprId -from miasm2.core.objc import CTypesManagerNotPacked, CTypeAnalyzer, ExprToAccessC, CHandler +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.ir.symbexec_types import SymbExecCType from miasm2.expression.parser import str_to_expr +from miasm2.ir.symbexec import SymbolicExecutionEngine, SymbolicState from utils import guess_machine @@ -25,7 +26,6 @@ class TypePropagationForm(ida_kernwin.Form): def __init__(self, ira): self.ira = ira - self.stk_unalias_force = False default_types_info = r"""ExprId("RDX", 64): char *""" archs = ["AMD64_unk", "X86_32_unk"] @@ -35,12 +35,12 @@ class TypePropagationForm(ida_kernwin.Form): BUTTON CANCEL NONE Dependency Graph Settings <##Header file :{headerFile}> -<Architecture/complator:{cbReg}> +<Architecture/complator:{arch}> <Types informations:{strTypesInfo}> <Unalias stack:{rUnaliasStack}>{cMethod}> """, { 'headerFile': ida_kernwin.Form.FileInput(swidth=20, open=True), - 'cbReg': ida_kernwin.Form.DropdownListControl( + 'arch': ida_kernwin.Form.DropdownListControl( items=archs, readonly=False, selval=archs[0]), @@ -48,11 +48,7 @@ Dependency Graph Settings flags=ida_kernwin.Form.MultiLineTextControl.TXTF_FIXEDFONT), 'cMethod': ida_kernwin.Form.ChkGroupControl(("rUnaliasStack",)), }) - self.Compile() - - @property - def unalias_stack(self): - return self.cMethod.value & 1 or self.stk_unalias_force + form, args = self.Compile() def get_block(ir_arch, mdis, addr): @@ -67,9 +63,14 @@ def get_block(ir_arch, mdis, addr): return irblock -def get_types_mngr(headerFile): +def get_types_mngr(headerFile, arch): text = open(headerFile).read() - base_types = CTypeAMD64_unk() + if arch == "AMD64_unk": + base_types = CTypeAMD64_unk() + elif arch =="X86_32_unk": + base_types = CTypeX86_unk() + else: + raise NotImplementedError("Unsupported arch") types_ast = CAstTypes() # Add C types definition @@ -79,16 +80,11 @@ def get_types_mngr(headerFile): return types_mngr -class MyCTypeAnalyzer(CTypeAnalyzer): - allow_none_result = True - - class MyExprToAccessC(ExprToAccessC): allow_none_result = True class MyCHandler(CHandler): - cTypeAnalyzer_cls = MyCTypeAnalyzer exprToAccessC_cls = MyExprToAccessC @@ -109,25 +105,37 @@ class SymbExecCTypeFix(SymbExecCType): @irb: irblock instance @step: display intermediate steps """ + offset2cmt = {} - for assignblk in irb.irs: + for index, assignblk in enumerate(irb.irs): instr = assignblk.instr - tmp_rw = assignblk.get_rw() - for dst, src in assignblk.iteritems(): - for arg in set(instr.args).union(set([src])): - if arg in tmp_rw and arg not in tmp_rw.values(): - continue - objc = self.eval_expr(arg) - if objc is None: - continue - if self.is_type_offset(objc): - continue + tmp_r = assignblk.get_r() + tmp_w = assignblk.get_w() + + todo = set() + + # Replace PC with value to match IR args + pc_fixed = {self.ir_arch.pc: m2_expr.ExprInt(instr.offset + instr.l, self.ir_arch.pc.size)} + args = instr.args + for arg in args: + arg = expr_simp(arg.replace_expr(pc_fixed)) + + if arg in tmp_w and not arg.is_mem(): + continue + todo.add(arg) + + for expr in todo: + if expr.is_int(): + continue + + for c_str, c_type in self.chandler.expr_to_c_and_types(expr, self.symbols): offset2cmt.setdefault(instr.offset, set()).add( - "%s: %s" % (arg, str(objc))) - self.eval_ir(assignblk) + "\n%s\n%s" % (c_str, c_type)) + self.eval_ir(assignblk) for offset, value in offset2cmt.iteritems(): idc.MakeComm(offset, '\n'.join(value)) + print "%x\n" % offset, '\n'.join(value) return self.eval_expr(self.ir_arch.IRDst) @@ -141,6 +149,25 @@ class CTypeEngineFixer(SymbExecCTypeFix): mychandler) +def get_ira_call_fixer(ira): + + class iraCallStackFixer(ira): + + def call_effects(self, ad, instr): + print hex(instr.offset), instr + stk_before = idc.GetSpd(instr.offset) + stk_after = idc.GetSpd(instr.offset + instr.l) + stk_diff = stk_after - stk_before + print hex(stk_diff) + return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad)), + ExprAff(self.sp, self.sp + ExprInt(stk_diff, self.sp.size)) + ], + instr + )] + + return iraCallStackFixer + + def add_state(ir_arch, todo, states, addr, state): addr = ir_arch.get_label(addr) if addr not in states: @@ -159,7 +186,11 @@ def analyse_function(): bs = bin_stream_ida() mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) - ir_arch = ira(mdis.symbol_pool) + + + iraCallStackFixer = get_ira_call_fixer(ira) + ir_arch = iraCallStackFixer(mdis.symbol_pool) + # Get the current function func = ida_funcs.get_func(idc.ScreenEA()) @@ -169,13 +200,15 @@ def analyse_function(): for block in blocks: ir_arch.add_block(block) + # Get settings settings = TypePropagationForm(ir_arch) ret = settings.Execute() if not ret: return - types_mngr = get_types_mngr(settings.headerFile.value) + + 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'): @@ -184,14 +217,13 @@ def analyse_function(): expr_str, ctype_str = line.split(':') expr_str, ctype_str = expr_str.strip(), ctype_str.strip() expr = str_to_expr(expr_str) - ast = mychandler.type_analyzer.types_mngr.types_ast.parse_c_type( + ast = mychandler.types_mngr.types_ast.parse_c_type( ctype_str) - ctype = mychandler.type_analyzer.types_mngr.types_ast.ast_parse_declaration(ast.ext[ - 0]) + ctype = mychandler.types_mngr.types_ast.ast_parse_declaration(ast.ext[0]) objc = types_mngr.get_objc(ctype) print '=' * 20 print expr, objc - infos_types[expr] = objc + infos_types[expr] = set([objc]) # Add fake head lbl_real_start = ir_arch.symbol_pool.getby_offset(addr) @@ -228,9 +260,7 @@ def analyse_function(): ir_arch._graph = None sons = ir_arch.graph.successors(lbl) for son in sons: - if son.offset is None: - continue - add_state(ir_arch, todo, states, son.offset, + add_state(ir_arch, todo, states, son, symbexec_engine.get_state()) for lbl, state in states.iteritems(): |