diff options
Diffstat (limited to 'example/ida')
| -rw-r--r-- | example/ida/ctype_propagation.py | 93 | ||||
| -rw-r--r-- | example/ida/depgraph.py | 67 | ||||
| -rw-r--r-- | example/ida/graph_ir.py | 78 | ||||
| -rw-r--r-- | example/ida/symbol_exec.py | 38 | ||||
| -rw-r--r-- | example/ida/utils.py | 45 |
5 files changed, 174 insertions, 147 deletions
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index 9b9c2e95..e8b52e3e 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -10,7 +10,7 @@ from miasm2.arch.x86.ctype import CTypeAMD64_unk, CTypeX86_unk from miasm2.arch.msp430.ctype import CTypeMSP430_unk from miasm2.core.objc import CTypesManagerNotPacked, ExprToAccessC, CHandler from miasm2.core.ctypesmngr import CAstTypes -from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprAff +from miasm2.expression.expression import ExprLoc, ExprInt, ExprOp, ExprAff from miasm2.ir.symbexec_types import SymbExecCType from miasm2.expression.parser import str_to_expr from miasm2.analysis.cst_propag import add_state, propagate_cst_expr @@ -19,9 +19,7 @@ from utils import guess_machine class TypePropagationForm(ida_kernwin.Form): - def __init__(self, ira): - - self.ira = ira + def __init__(self): default_types_info = r"""ExprId("RDX", 64): char *""" archs = ["AMD64_unk", "X86_32_unk", "msp430_unk"] @@ -201,10 +199,9 @@ class SymbExecCTypeFix(SymbExecCType): if expr.is_int(): continue for c_str, c_type in self.chandler.expr_to_c_and_types(expr, self.symbols): - expr = self.cst_propag_link.get((irb.label, index), {}).get(expr, expr) + expr = self.cst_propag_link.get((irb.loc_key, index), {}).get(expr, expr) offset2cmt.setdefault(instr.offset, set()).add( "\n%s: %s\n%s" % (expr, c_str, c_type)) - self.eval_updt_assignblk(assignblk) for offset, value in offset2cmt.iteritems(): idc.MakeComm(offset, '\n'.join(value)) @@ -243,42 +240,42 @@ def get_ira_call_fixer(ira): def analyse_function(): - - # Init - machine = guess_machine() - mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira - - bs = bin_stream_ida() - mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) - - - iraCallStackFixer = get_ira_call_fixer(ira) - ir_arch = iraCallStackFixer(mdis.symbol_pool) - - # Get settings - settings = TypePropagationForm(ir_arch) + settings = TypePropagationForm() ret = settings.Execute() if not ret: return + + end = None 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) + # Init + machine = guess_machine(addr=addr) + mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira + + bs = bin_stream_ida() + mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) + if end is not None: + mdis.dont_dis = [end] + + + iraCallStackFixer = get_ira_call_fixer(ira) + ir_arch = iraCallStackFixer(mdis.loc_db) + + asmcfg = mdis.dis_multiblock(addr) # Generate IR - for block in blocks: - ir_arch.add_block(block) + ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) cst_propag_link = {} if settings.cUnalias.value: init_infos = {ir_arch.sp: ir_arch.arch.regs.regs_init[ir_arch.sp] } - cst_propag_link = propagate_cst_expr(ir_arch, addr, init_infos) + cst_propag_link = propagate_cst_expr(ir_arch, ircfg, addr, init_infos) types_mngr = get_types_mngr(settings.headerFile.value, settings.arch.value) @@ -298,7 +295,8 @@ def analyse_function(): expr_str, ctype_str = expr_str.strip(), ctype_str.strip() expr = str_to_expr(expr_str) ast = mychandler.types_mngr.types_ast.parse_c_type( - ctype_str) + ctype_str + ) ctype = mychandler.types_mngr.types_ast.ast_parse_declaration(ast.ext[0]) objc = types_mngr.get_objc(ctype) print '=' * 20 @@ -306,18 +304,21 @@ def analyse_function(): infos_types[expr] = set([objc]) # Add fake head - lbl_real_start = ir_arch.symbol_pool.getby_offset(addr) - lbl_head = ir_arch.symbol_pool.getby_name_create("start") - - first_block = blocks.label2block(lbl_real_start) - - assignblk_head = AssignBlock([ExprAff(ir_arch.IRDst, ExprId(lbl_real_start, ir_arch.IRDst.size)), - ExprAff( - ir_arch.sp, ir_arch.arch.regs.regs_init[ir_arch.sp]) - ], first_block.lines[0]) + lbl_real_start = ir_arch.loc_db.get_offset_location(addr) + lbl_head = ir_arch.loc_db.get_or_create_name_location("start") + + first_block = asmcfg.label2block(lbl_real_start) + + assignblk_head = AssignBlock( + [ + ExprAff(ir_arch.IRDst, ExprLoc(lbl_real_start, ir_arch.IRDst.size)), + ExprAff(ir_arch.sp, ir_arch.arch.regs.regs_init[ir_arch.sp]) + ], + first_block.lines[0] + ) irb_head = IRBlock(lbl_head, [assignblk_head]) - ir_arch.blocks[lbl_head] = irb_head - ir_arch.graph.add_uniq_edge(lbl_head, lbl_real_start) + ircfg.blocks[lbl_head] = irb_head + ircfg.add_uniq_edge(lbl_head, lbl_real_start) state = TypePropagationEngine.StateEngine(infos_types) states = {lbl_head: state} @@ -330,24 +331,24 @@ def analyse_function(): if (lbl, state) in done: continue done.add((lbl, state)) - if lbl not in ir_arch.blocks: + if lbl not in ircfg.blocks: continue - symbexec_engine = TypePropagationEngine(ir_arch, types_mngr, state) - addr = symbexec_engine.run_block_at(lbl) + addr = symbexec_engine.run_block_at(ircfg, lbl) symbexec_engine.del_mem_above_stack(ir_arch.sp) - ir_arch._graph = None - sons = ir_arch.graph.successors(lbl) + sons = ircfg.successors(lbl) for son in sons: - add_state(ir_arch, todo, states, son, - symbexec_engine.get_state()) + add_state( + ircfg, todo, states, son, + symbexec_engine.get_state() + ) for lbl, state in states.iteritems(): - if lbl not in ir_arch.blocks: + if lbl not in ircfg.blocks: continue symbexec_engine = CTypeEngineFixer(ir_arch, types_mngr, state, cst_propag_link) - addr = symbexec_engine.run_block_at(lbl) + addr = symbexec_engine.run_block_at(ircfg, lbl) symbexec_engine.del_mem_above_stack(ir_arch.sp) diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py index 5342313a..297877a1 100644 --- a/example/ida/depgraph.py +++ b/example/ida/depgraph.py @@ -19,16 +19,18 @@ from utils import guess_machine class depGraphSettingsForm(ida_kernwin.Form): - def __init__(self, ira): + def __init__(self, ira, ircfg): self.ira = ira + self.ircfg = ircfg self.stk_args = {'ARG%d' % i:i for i in xrange(10)} self.stk_unalias_force = False self.address = idc.ScreenEA() cur_block = None - for block in ira.getby_offset(self.address): - if block.label.offset is not None: + for block in ircfg.getby_offset(self.address): + offset = self.ircfg.loc_db.get_location_offset(block.loc_key) + if offset is not None: # Only one block non-generated assert cur_block is None cur_block = block @@ -38,8 +40,8 @@ class depGraphSettingsForm(ida_kernwin.Form): if assignblk.instr.offset == self.address: break assert line_nb is not None - cur_label = str(cur_block.label) - labels = sorted(map(str, ira.blocks.keys())) + cur_loc_key = str(cur_block.loc_key) + loc_keys = sorted(map(str, ircfg.blocks.keys())) regs = sorted(ira.arch.regs.all_regs_ids_byname.keys()) regs += self.stk_args.keys() reg_default = regs[0] @@ -85,21 +87,21 @@ Method to use: tp=ida_kernwin.Form.FT_RAWHEX, value=line_nb), 'cbBBL': ida_kernwin.Form.DropdownListControl( - items=labels, + items=loc_keys, readonly=False, - selval=cur_label), + selval=cur_loc_key), 'cColor': ida_kernwin.Form.ColorInput(value=0xc0c020), }) self.Compile() @property - def label(self): + def loc_key(self): value = self.cbBBL.value - for real_label in self.ira.blocks: - if str(real_label) == value: - return real_label - raise ValueError("Bad label") + for real_loc_key in self.ircfg.blocks: + if str(real_loc_key) == value: + return real_loc_key + raise ValueError("Bad loc_key") @property def line_nb(self): @@ -110,13 +112,13 @@ Method to use: elif mode == 1: return value + 1 else: - return len(self.ira.blocks[self.label]) + return len(self.ircfg.blocks[self.loc_key]) @property def elements(self): value = self.cbReg.value if value in self.stk_args: - line = self.ira.blocks[self.label][self.line_nb].instr + line = self.ircfg.blocks[self.loc_key][self.line_nb].instr arg_num = self.stk_args[value] stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size) stk_off = m2_expr.ExprInt(self.ira.sp.size/8 * arg_num, ir_arch.sp.size) @@ -134,7 +136,7 @@ Method to use: @property def depgraph(self): value = self.cMethod.value - return DependencyGraph(self.ira, + return DependencyGraph(self.ircfg, implicit=value & 4, follow_mem=value & 1, follow_call=value & 2) @@ -174,7 +176,7 @@ def treat_element(): for node in graph.relevant_nodes: try: - offset = ir_arch.blocks[node.label][node.line_nb].instr.offset + offset = ir_arch.blocks[node.loc_key][node.line_nb].instr.offset except IndexError: print "Unable to highlight %s" % node continue @@ -184,7 +186,7 @@ def treat_element(): if graph.has_loop: print 'Graph has dependency loop: symbolic execution is inexact' else: - print "Possible value: %s" % graph.emul().values()[0] + print "Possible value: %s" % graph.emul(self.ira).values()[0] for offset, elements in comments.iteritems(): idc.MakeComm(offset, ", ".join(map(str, elements))) @@ -197,38 +199,39 @@ def next_element(): def launch_depgraph(): global graphs, comments, sol_nb, settings, addr, ir_arch + # Get the current function + addr = idc.ScreenEA() + func = ida_funcs.get_func(addr) + # Init - machine = guess_machine() + machine = guess_machine(addr=func.startEA) mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira bs = bin_stream_ida() mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) - ir_arch = ira(mdis.symbol_pool) + ir_arch = ira(mdis.loc_db) # Populate symbols with ida names for ad, name in idautils.Names(): if name is None: continue - mdis.symbol_pool.add_label(name, ad) + mdis.loc_db.add_location(name, ad) - # Get the current function - addr = idc.ScreenEA() - func = ida_funcs.get_func(addr) - blocks = mdis.dis_multiblock(func.startEA) + asmcfg = mdis.dis_multiblock(func.startEA) # Generate IR - for block in blocks: - ir_arch.add_block(block) + ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) # Get settings - settings = depGraphSettingsForm(ir_arch) + settings = depGraphSettingsForm(ir_arch, ircfg) settings.Execute() - label, elements, line_nb = settings.label, settings.elements, settings.line_nb + loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb # Simplify affectations for irb in ir_arch.blocks.values(): irs = [] - fix_stack = irb.label.offset is not None and settings.unalias_stack + offset = ir_arch.loc_db.get_location_offset(irb.loc_key) + fix_stack = offset is not None and settings.unalias_stack for assignblk in irb: if fix_stack: stk_high = m2_expr.ExprInt(idc.GetSpd(assignblk.instr.offset), ir_arch.sp.size) @@ -243,12 +246,12 @@ def launch_depgraph(): dst, src = expr_simp(dst), expr_simp(src) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) - ir_arch.blocks[irb.label] = IRBlock(irb.label, irs) + ir_arch.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) # Get dependency graphs dg = settings.depgraph - graphs = dg.get(label, elements, line_nb, - set([ir_arch.symbol_pool.getby_offset(func.startEA)])) + graphs = dg.get(loc_key, elements, line_nb, + set([ir_arch.loc_db.get_offset_location(func.startEA)])) # Display the result comments = {} diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py index 6dfa1f7d..afd00d5c 100644 --- a/example/ida/graph_ir.py +++ b/example/ida/graph_ir.py @@ -6,7 +6,7 @@ import idc import idautils from miasm2.core.bin_stream_ida import bin_stream_ida -from miasm2.core.asmblock import expr_is_label, AsmLabel, is_int +from miasm2.core.asmblock import is_int from miasm2.expression.simplifications import expr_simp from miasm2.analysis.data_flow import dead_simp from miasm2.ir.ir import AssignBlock, IRBlock @@ -33,17 +33,15 @@ def label_str(self): else: return "%s:%s" % (self.name, str(self.offset)) -AsmLabel.__init__ = label_init -AsmLabel.__str__ = label_str def color_irblock(irblock, ir_arch): out = [] - lbl = idaapi.COLSTR(str(irblock.label), idaapi.SCOLOR_INSN) + lbl = idaapi.COLSTR(ir_arch.loc_db.pretty_str(irblock.loc_key), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock: for dst, src in sorted(assignblk.iteritems()): - dst_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, dst) - src_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, src) + dst_f = expr2colorstr(dst, loc_db=ir_arch.loc_db) + src_f = expr2colorstr(src, loc_db=ir_arch.loc_db) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) out.append(' %s' % line) out.append("") @@ -56,31 +54,29 @@ def color_irblock(irblock, ir_arch): class GraphMiasmIR(idaapi.GraphViewer): - def __init__(self, ir_arch, title, result): + def __init__(self, ircfg, title, result): idaapi.GraphViewer.__init__(self, title) - self.ir_arch = ir_arch + self.ircfg = ircfg self.result = result self.names = {} def OnRefresh(self): self.Clear() addr_id = {} - for irblock in self.ir_arch.blocks.values(): - id_irblock = self.AddNode(color_irblock(irblock, self.ir_arch)) + for irblock in self.ircfg.blocks.values(): + id_irblock = self.AddNode(color_irblock(irblock, self.ircfg)) addr_id[irblock] = id_irblock - for irblock in self.ir_arch.blocks.values(): + for irblock in self.ircfg.blocks.values(): if not irblock: continue - all_dst = self.ir_arch.dst_trackback(irblock) + all_dst = self.ircfg.dst_trackback(irblock) for dst in all_dst: - if not expr_is_label(dst): + if not dst.is_loc(): continue - - dst = dst.name - if not dst in self.ir_arch.blocks: + if not dst.loc_key in self.ircfg.blocks: continue - dst_block = self.ir_arch.blocks[dst] + dst_block = self.ircfg.blocks[dst.loc_key] node1 = addr_id[irblock] node2 = addr_id[dst_block] self.AddEdge(node1, node2) @@ -102,7 +98,9 @@ class GraphMiasmIR(idaapi.GraphViewer): def build_graph(verbose=False, simplify=False): - machine = guess_machine() + start_addr = idc.ScreenEA() + + machine = guess_machine(addr=start_addr) mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira if verbose: @@ -114,43 +112,37 @@ def build_graph(verbose=False, simplify=False): bs = bin_stream_ida() mdis = dis_engine(bs) - ir_arch = ira(mdis.symbol_pool) + ir_arch = ira(mdis.loc_db) # populate symbols with ida names for addr, name in idautils.Names(): - # print hex(ad), repr(name) if name is None: continue - if (mdis.symbol_pool.getby_offset(addr) or - mdis.symbol_pool.getby_name(name)): + if (mdis.loc_db.get_offset_location(addr) or + mdis.loc_db.get_name_location(name)): # Symbol alias continue - mdis.symbol_pool.add_label(name, addr) + mdis.loc_db.add_location(name, addr) if verbose: print "start disasm" - addr = idc.ScreenEA() if verbose: print hex(addr) - blocks = mdis.dis_multiblock(addr) + asmcfg = mdis.dis_multiblock(start_addr) if verbose: print "generating graph" - open('asm_flow.dot', 'w').write(blocks.dot()) + open('asm_flow.dot', 'w').write(asmcfg.dot()) - print "generating IR... %x" % addr + print "generating IR... %x" % start_addr - for block in blocks: - if verbose: - print 'ADD' - print block - ir_arch.add_block(block) + ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) if verbose: - print "IR ok... %x" % addr + print "IR ok... %x" % start_addr - for irb in ir_arch.blocks.itervalues(): + for irb in ircfg.blocks.itervalues(): irs = [] for assignblk in irb: new_assignblk = { @@ -158,27 +150,27 @@ def build_graph(verbose=False, simplify=False): for dst, src in assignblk.iteritems() } irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) - ir_arch.blocks[irb.label] = IRBlock(irb.label, irs) + ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) if verbose: - out = ir_arch.graph.dot() + out = ircfg.dot() open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out) title = "Miasm IR graph" if simplify: - dead_simp(ir_arch) + dead_simp(ir_arch, ircfg) - ir_arch.simplify(expr_simp) + ircfg.simplify(expr_simp) modified = True while modified: modified = False - modified |= dead_simp(ir_arch) - modified |= ir_arch.remove_empty_assignblks() - modified |= ir_arch.remove_jmp_blocks() - modified |= ir_arch.merge_blocks() + modified |= dead_simp(ir_arch, ircfg) + modified |= ircfg.remove_empty_assignblks() + modified |= ircfg.remove_jmp_blocks() + modified |= ircfg.merge_blocks() title += " (simplified)" - g = GraphMiasmIR(ir_arch, title, None) + g = GraphMiasmIR(ircfg, title, None) g.Show() diff --git a/example/ida/symbol_exec.py b/example/ida/symbol_exec.py index f019f77d..ffaa9b27 100644 --- a/example/ida/symbol_exec.py +++ b/example/ida/symbol_exec.py @@ -34,8 +34,16 @@ class ActionHandlerTranslate(ActionHandler): class symbolicexec_t(idaapi.simplecustviewer_t): def add(self, key, value): - self.AddLine("%s = %s" % (expr2colorstr(self.machine.mn.regs.all_regs_ids, key), - expr2colorstr(self.machine.mn.regs.all_regs_ids, value))) + self.AddLine("%s = %s" % ( + expr2colorstr( + key, + loc_db=self.loc_db + ), + expr2colorstr( + value, + loc_db=self.loc_db + ) + )) def expand(self, linenum): element = self.line2eq[linenum] @@ -61,11 +69,12 @@ class symbolicexec_t(idaapi.simplecustviewer_t): form.Compile() form.Execute() - def Create(self, equations, machine, *args, **kwargs): + def Create(self, equations, machine, loc_db, *args, **kwargs): if not super(symbolicexec_t, self).Create(*args, **kwargs): return False self.machine = machine + self.loc_db = loc_db self.line2eq = sorted(equations.items(), key=operator.itemgetter(0)) self.lines_expanded = set() @@ -119,21 +128,25 @@ def symbolic_exec(): from utils import guess_machine + start, end = idc.SelStart(), idc.SelEnd() + bs = bin_stream_ida() - machine = guess_machine() + machine = guess_machine(addr=start) mdis = machine.dis_engine(bs) - start, end = idc.SelStart(), idc.SelEnd() + + if start == idc.BADADDR and end == idc.BADADDR: + start = idc.ScreenEA() + end = idc.next_head(start) # Get next instruction address mdis.dont_dis = [end] - blocks = mdis.dis_multiblock(start) - ira = machine.ira() - for block in blocks: - ira.add_block(block) + asmcfg = mdis.dis_multiblock(start) + ira = machine.ira(loc_db=mdis.loc_db) + ircfg = ira.new_ircfg_from_asmcfg(asmcfg) print "Run symbolic execution..." sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) - sb.run_at(start) + sb.run_at(ircfg, start) modified = {} for dst, src in sb.modified(init_state=machine.mn.regs.regs_init): @@ -141,8 +154,9 @@ 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)): + if not view.Create(modified, machine, mdis.loc_db, + "Symbolic Execution - 0x%x to 0x%x" + % (start, idc.prev_head(end))): return view.Show() diff --git a/example/ida/utils.py b/example/ida/utils.py index e026f2fc..c66475f2 100644 --- a/example/ida/utils.py +++ b/example/ida/utils.py @@ -5,7 +5,7 @@ from miasm2.analysis.machine import Machine from miasm2.ir.translators import Translator import miasm2.expression.expression as m2_expr -def guess_machine(): +def guess_machine(addr=None): "Return an instance of Machine corresponding to the IDA guessed processor" processor_name = GetLongPrm(INF_PROCNAME) @@ -39,7 +39,14 @@ def guess_machine(): (False, 64, True): "aarch64b", (False, 64, False): "aarch64l", } - is_armt = globals().get('armt', False) + + # Get T reg to detect arm/thumb function + # Default is arm + is_armt = False + if addr is not None: + t_reg = GetReg(addr, "T") + is_armt = t_reg == 1 + is_bigendian = info.is_be() infos = (is_armt, size, is_bigendian) if not infos in info2machine: @@ -72,22 +79,29 @@ class TranslatorIDA(Translator): # Implemented language __LANG__ = "ida_w_color" - def __init__(self, regs_ids=None, **kwargs): + def __init__(self, loc_db=None, **kwargs): super(TranslatorIDA, self).__init__(**kwargs) - if regs_ids is None: - regs_ids = {} - self.regs_ids = regs_ids + self.loc_db = loc_db 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) + 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) + out = idaapi.COLSTR(str(expr), idaapi.SCOLOR_REG) + return out + + def from_ExprLoc(self, expr): + if self.loc_db is not None: + out = self.loc_db.pretty_str(expr.loc_key) + else: + out = str(expr) + out = idaapi.COLSTR(out, idaapi.SCOLOR_REG) return out def from_ExprMem(self, expr): @@ -126,20 +140,23 @@ class TranslatorIDA(Translator): 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]) + ')') + ', '.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): +def expr2colorstr(expr, loc_db): """Colorize an Expr instance for IDA - @regs_ids: list of ExprId corresponding to available registers @expr: Expr instance to colorize + @loc_db: LocationDB instance """ - translator = TranslatorIDA(regs_ids) + translator = TranslatorIDA(loc_db=loc_db) return translator.from_expr(expr) |