about summary refs log tree commit diff stats
path: root/example/ida
diff options
context:
space:
mode:
Diffstat (limited to 'example/ida')
-rw-r--r--example/ida/ctype_propagation.py5
-rw-r--r--example/ida/graph_ir.py12
-rw-r--r--example/ida/symbol_exec.py87
-rw-r--r--example/ida/utils.py118
4 files changed, 150 insertions, 72 deletions
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py
index 76d4fa2d..8c64c6d2 100644
--- a/example/ida/ctype_propagation.py
+++ b/example/ida/ctype_propagation.py
@@ -11,6 +11,7 @@ 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
@@ -29,7 +30,7 @@ class TypePropagationForm(ida_kernwin.Form):
         self.ira = ira
 
         default_types_info = r"""ExprId("RDX", 64): char *"""
-        archs = ["AMD64_unk", "X86_32_unk"]
+        archs = ["AMD64_unk", "X86_32_unk", "msp430_unk"]
 
         ida_kernwin.Form.__init__(self,
                       r"""BUTTON YES* Launch
@@ -59,6 +60,8 @@ def get_types_mngr(headerFile, arch):
         base_types = CTypeAMD64_unk()
     elif arch =="X86_32_unk":
         base_types = CTypeX86_unk()
+    elif arch =="msp430_unk":
+        base_types = CTypeMSP430_unk()
     else:
         raise NotImplementedError("Unsupported arch")
     types_ast = CAstTypes()
diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py
index 9a65617b..8d9dea4f 100644
--- a/example/ida/graph_ir.py
+++ b/example/ida/graph_ir.py
@@ -95,18 +95,9 @@ class GraphMiasmIR(idaapi.GraphViewer):
     def OnClick(self, node_id):
         return True
 
-    def OnCommand(self, cmd_id):
-        if self.cmd_test == cmd_id:
-            print 'TEST!'
-            return
-        print "command:", cmd_id
-
     def Show(self):
         if not idaapi.GraphViewer.Show(self):
             return False
-        self.cmd_test = self.AddCommand("Test", "F2")
-        if self.cmd_test == 0:
-            print "Failed to add popup menu item!"
         return True
 
 
@@ -185,9 +176,6 @@ def build_graph(verbose=False, simplify=False):
 
     g = GraphMiasmIR(ir_arch, title, None)
 
-    g.cmd_a = g.AddCommand("cmd a", "x")
-    g.cmd_b = g.AddCommand("cmd b", "y")
-
     g.Show()
 
 if __name__ == "__main__":
diff --git a/example/ida/symbol_exec.py b/example/ida/symbol_exec.py
index 3d4a64fa..b65b97a1 100644
--- a/example/ida/symbol_exec.py
+++ b/example/ida/symbol_exec.py
@@ -8,6 +8,29 @@ from miasm2.expression.expression import ExprAff
 from utils import expr2colorstr, translatorForm
 
 
+
+class ActionHandler(idaapi.action_handler_t):
+    def activate(self, ctx):
+        view_index = get_focused_view()
+        if view_index is None:
+            return 1
+        self.custom_action(all_views[view_index])
+        return 1
+
+    def update(self, ctx):
+        return idaapi.AST_ENABLE_ALWAYS
+
+
+class ActionHandlerExpand(ActionHandler):
+    def custom_action(self, view):
+        view.expand_expr()
+
+
+class ActionHandlerTranslate(ActionHandler):
+    def custom_action(self, view):
+        view.translate_expr(view.GetLineNo())
+
+
 class symbolicexec_t(idaapi.simplecustviewer_t):
 
     def add(self, key, value):
@@ -48,10 +71,12 @@ class symbolicexec_t(idaapi.simplecustviewer_t):
 
         self.print_lines()
 
-        self.menu_expand = self.AddPopupMenu("Expand [E]")
-        self.menu_translate = self.AddPopupMenu("Translate [T]")
         return True
 
+    def expand_expr(self):
+        self.expand(self.GetLineNo())
+        self.print_lines()
+
     def OnPopupMenu(self, menu_id):
         if menu_id == self.menu_expand:
             self.expand(self.GetLineNo())
@@ -65,15 +90,29 @@ class symbolicexec_t(idaapi.simplecustviewer_t):
         if vkey == 27:
             self.Close()
             return True
-        # E (expand)
-        if vkey == 69:
-            self.OnPopupMenu(self.menu_expand)
-        # T (translate)
-        if vkey == 84:
-            self.OnPopupMenu(self.menu_translate)
+
+        if vkey == ord('E'):
+            self.expand_expr()
+
+        if vkey == ord('T'):
+            self.translate_expr(self.GetLineNo())
+
         return False
 
 
+def get_focused_view():
+    for i, view in enumerate(all_views):
+        if view.IsFocused():
+            return i
+    return None
+
+
+class Hooks(idaapi.UI_Hooks):
+    def finish_populating_tform_popup(self, form, popup):
+        idaapi.attach_action_to_popup(form, popup, 'my:expand', None)
+        idaapi.attach_action_to_popup(form, popup, 'my:translate', None)
+
+
 def symbolic_exec():
     from miasm2.ir.symbexec import SymbolicExecutionEngine
     from miasm2.core.bin_stream_ida import bin_stream_ida
@@ -109,17 +148,45 @@ def symbolic_exec():
 
 
     view = symbolicexec_t()
+    all_views.append(view)
     if not view.Create(modified, machine,
                        "Symbolic Execution - 0x%x to 0x%x" % (start, end)):
         return
 
     view.Show()
 
-if __name__ == "__main__":
+
+# Support ida 6.9 and ida 7
+all_views = []
+
+hooks = Hooks()
+hooks.hook()
+
+action_expand = idaapi.action_desc_t(
+    'my:expand',
+    'Expand',
+    ActionHandlerExpand(),
+    'E',
+    'Expand expression',
+    50)
+
+action_translate = idaapi.action_desc_t(
+    'my:translate',
+    'Translate',
+    ActionHandlerTranslate(),
+    'T',
+    'Translate expression in C/python/z3...',
+    103)
+
+idaapi.register_action(action_expand)
+idaapi.register_action(action_translate)
+
+
+if __name__ == '__main__':
     idaapi.CompileLine('static key_F3() { RunPythonStatement("symbolic_exec()"); }')
     idc.AddHotkey("F3", "key_F3")
 
     print "=" * 50
     print """Available commands:
-        symbolic_exec() - F3: Symbolic execution of current selection
+    symbolic_exec() - F3: Symbolic execution of current selection
     """
diff --git a/example/ida/utils.py b/example/ida/utils.py
index 3f7c3c8a..b147cde2 100644
--- a/example/ida/utils.py
+++ b/example/ida/utils.py
@@ -64,61 +64,81 @@ def guess_machine():
     return machine
 
 
+class TranslatorIDA(Translator):
+    """Translate a Miasm expression to a IDA colored string"""
+
+    # Implemented language
+    __LANG__ = "ida_w_color"
+
+    def __init__(self, regs_ids=None, **kwargs):
+        super(TranslatorIDA, self).__init__(**kwargs)
+        if regs_ids is None:
+            regs_ids = {}
+        self.regs_ids = regs_ids
+
+    def str_protected_child(self, child, parent):
+        return ("(%s)" % self.from_expr(child)) if m2_expr.should_parenthesize_child(child, parent) else self.from_expr(child)
+
+    def from_ExprInt(self, expr):
+        return idaapi.COLSTR(str(expr), idaapi.SCOLOR_NUMBER)
+
+    def from_ExprId(self, expr):
+        out = str(expr)
+        if expr in self.regs_ids:
+            out = idaapi.COLSTR(out, idaapi.SCOLOR_REG)
+        return out
+
+    def from_ExprMem(self, expr):
+        ptr = self.from_expr(expr.arg)
+        size = idaapi.COLSTR('@' + str(expr.size), idaapi.SCOLOR_RPTCMT)
+        out = '%s[%s]' % (size, ptr)
+        return out
+
+    def from_ExprSlice(self, expr):
+        base = self.from_expr(expr.arg)
+        start = idaapi.COLSTR(str(expr.start), idaapi.SCOLOR_RPTCMT)
+        stop = idaapi.COLSTR(str(expr.stop), idaapi.SCOLOR_RPTCMT)
+        out = "(%s)[%s:%s]" % (base, start, stop)
+        return out
+
+    def from_ExprCompose(self, expr):
+        out = "{"
+        out += ", ".join(["%s, %s, %s" % (self.from_expr(subexpr),
+                                          idaapi.COLSTR(str(idx), idaapi.SCOLOR_RPTCMT),
+                                          idaapi.COLSTR(str(idx + subexpr.size), idaapi.SCOLOR_RPTCMT))
+                          for idx, subexpr in expr.iter_args()])
+        out += "}"
+        return out
+
+    def from_ExprCond(self, expr):
+        cond = self.str_protected_child(expr.cond, expr)
+        src1 = self.from_expr(expr.src1)
+        src2 = self.from_expr(expr.src2)
+        out = "%s?(%s,%s)" % (cond, src1, src2)
+        return out
+
+    def from_ExprOp(self, expr):
+        if expr._op == '-':		# Unary minus
+            return '-' + self.str_protected_child(expr._args[0], expr)
+        if expr.is_associative() or expr.is_infix():
+            return (' ' + expr._op + ' ').join([self.str_protected_child(arg, expr)
+                                                for arg in expr._args])
+        return (expr._op + '(' +
+                ', '.join([self.from_expr(arg) for arg in expr._args]) + ')')
+
+    def from_ExprAff(self, expr):
+        return "%s = %s" % tuple(map(expr.from_expr, (expr.dst, expr.src)))
+
+
+
 def expr2colorstr(regs_ids, expr):
     """Colorize an Expr instance for IDA
     @regs_ids: list of ExprId corresponding to available registers
     @expr: Expr instance to colorize
     """
 
-    if isinstance(expr, m2_expr.ExprId):
-        s = str(expr)
-        if expr in regs_ids:
-            s = idaapi.COLSTR(s, idaapi.SCOLOR_REG)
-    elif isinstance(expr, m2_expr.ExprInt):
-        s = str(expr)
-        s = idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER)
-    elif isinstance(expr, m2_expr.ExprMem):
-        s = '%s[%s]' % (idaapi.COLSTR('@' + str(expr.size),
-                                      idaapi.SCOLOR_RPTCMT),
-                         expr2colorstr(regs_ids, expr.arg))
-    elif isinstance(expr, m2_expr.ExprOp):
-        out = []
-        for a in expr.args:
-            s = expr2colorstr(regs_ids, a)
-            if isinstance(a, m2_expr.ExprOp):
-                s = "(%s)" % s
-            out.append(s)
-        if len(out) == 1:
-            s = "%s %s" % (expr.op, str(out[0]))
-        else:
-            s = (" " + expr.op + " ").join(out)
-    elif isinstance(expr, m2_expr.ExprAff):
-        s = "%s = %s" % (
-            expr2colorstr(regs_ids, expr.dst), expr2colorstr(regs_ids, expr.src))
-    elif isinstance(expr, m2_expr.ExprCond):
-        cond = expr2colorstr(regs_ids, expr.cond)
-        src1 = expr2colorstr(regs_ids, expr.src1)
-        src2 = expr2colorstr(regs_ids, expr.src2)
-        s = "(%s?%s:%s)" % (cond, src1, src2)
-    elif isinstance(expr, m2_expr.ExprSlice):
-        s = "(%s)[%s:%s]" % (expr2colorstr(regs_ids, expr.arg),
-                             idaapi.COLSTR(str(expr.start),
-                                           idaapi.SCOLOR_RPTCMT),
-                             idaapi.COLSTR(str(expr.stop),
-                                           idaapi.SCOLOR_RPTCMT))
-    elif isinstance(expr, m2_expr.ExprCompose):
-        s = "{"
-        s += ", ".join(["%s, %s, %s" % (expr2colorstr(regs_ids, subexpr),
-                                        idaapi.COLSTR(str(idx),
-                                                      idaapi.SCOLOR_RPTCMT),
-                                        idaapi.COLSTR(str(idx + subexpr.size),
-                                                      idaapi.SCOLOR_RPTCMT))
-                        for idx, subexpr in expr.iter_args()])
-        s += "}"
-    else:
-        s = str(expr)
-
-    return s
+    translator = TranslatorIDA(regs_ids)
+    return translator.from_expr(expr)
 
 
 class translatorForm(idaapi.Form):