about summary refs log tree commit diff stats
path: root/example/ida
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2017-08-06 00:46:32 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2017-08-08 09:25:56 +0200
commit4b200beb1bda68ee94844a81bd9d618da634f8e9 (patch)
tree4f37057224ba4a26108a699a43bb740adb072571 /example/ida
parent9ada9bd6b907d47b5819a0f96d386578a9da91a1 (diff)
downloadmiasm-4b200beb1bda68ee94844a81bd9d618da634f8e9.tar.gz
miasm-4b200beb1bda68ee94844a81bd9d618da634f8e9.zip
Example: update api
Diffstat (limited to 'example/ida')
-rw-r--r--example/ida/ctype_propagation.py108
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():