diff options
Diffstat (limited to 'example/ida')
| -rw-r--r-- | example/ida/ctype_propagation.py | 5 | ||||
| -rw-r--r-- | example/ida/graph_ir.py | 12 | ||||
| -rw-r--r-- | example/ida/symbol_exec.py | 87 | ||||
| -rw-r--r-- | example/ida/utils.py | 118 |
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): |