def _parse_function(self, e): args = e.a # carglist_t dst_name = idaapi.tag_remove(e.print1(None)) numOfArgs = args.size() risk = "" for trisk in DICT[idaapi.tag_remove(e.x.print1(None))]: if str(numOfArgs) == trisk: risk = DICT[idaapi.tag_remove(e.x.print1(None))][trisk] break self._add_func_call(TakeAttributes(e.ea, dst_name, numOfArgs, risk)) return True
def decode_instr(eip): MakeCode(eip) mnem = idaapi.ua_mnem(eip) sz = idaapi.decode_insn(eip) x = dict(nextip=[], inst=mnem, ops=[]) if not idaapi.cmd.itype in (idaapi.NN_jmp, idaapi.NN_retn): x['nextip'].append(eip + sz) for n, op in enumerate(idaapi.cmd.Operands): if op.type == 0: break ty = op.type text = idaapi.tag_remove(idaapi.ua_outop2(eip, n)) if op.dtyp == 0: bits = 8 elif op.dtyp == 1: bits = 16 elif op.dtyp == 2: bits = 32 if ty == idc.o_reg: x['ops'].append(IR.Var(text, bits)) elif ty == idc.o_mem: x['ops'].append(IR.Mem(IR.Const(op.addr), bits)) elif ty in (idc.o_phrase, idc.o_displ): x['ops'].append(IR.Mem(parse_mem(op), bits)) elif ty == idc.o_imm: x['ops'].append(IR.Const(op.value, bits)) elif ty == idc.o_near: x['ops'].append(IR.Const(op.addr)) x['nextip'].append(op.addr) else: raise UnknownError return x
def get_function_para(func_name): func_args = [] code_buf = [] ea = idc.LocByName(func_name) if ea != idc.BADADDR: f = idaapi.get_func(ea) if f is not None: try: cfunc = idaapi.decompile(f) if cfunc != None: # sv = cfunc.get_pseudocode() for sline in sv: code_line = idaapi.tag_remove(sline.line) code_buf.append(code_line) #print('find: %s(' %func_name, end='') for arg in cfunc.arguments: func_args.append(arg.name) #print(arg.name+', ', end='') #print(')') except Exception as e: print(e) #code_str = '\n'.join(code_buf) return func_args, code_buf
def main(): if not idaapi.init_hexrays_plugin(): return False f = idaapi.get_func(idaapi.get_screen_ea()) if f is None: print "Please position the cursor within a function" return True cfunc = idaapi.decompile(f) if cfunc is None: print "Failed to decompile!" return True with open(SUPER_DUPER_OUTPUT, 'w') as f: sv = cfunc.get_pseudocode() for sline in sv: removido = idaapi.tag_remove(sline.line) if 'DoAssert' in removido: #This might be the ugliest code I've ever written, but hey it works ¯\_(ツ)_/¯ removido = removido.lstrip()[9:].replace(');', '').split(',') removido = map(lambda x: x.lstrip(), removido) if len(removido[0]) > 4 and removido[0][0] == 'a': removido = removido[0] else: removido = removido[1] f.write(get_string(get_name_ea_simple(removido)) + '\n') elif 'case' in removido: #lstrip is bae and saviour of bad code f.write('Command ' + removido.lstrip()[4:].replace(':', '').lstrip() + '\n') return True
def visit_expr(self, e): op = e.op if op == idaapi.cot_call: name = idaapi.tag_remove(e.x.print1(None)) if name in function_list: self._parse_memcpy(e) return 0
def func(ea, vuu): f = idaapi.get_func(ea) function_name = idaapi.get_func_name(ea) if f is None: print('Please position the cursor within a function') cfunc = None try: cfunc = idaapi.decompile(f) except ida_hexrays.DecompilationFailure as e: print('Failed to decompile %x: %s!' % (ea, function_name)) raise e # Rename decompilation graph cg = CFuncGraph(None) gb = GraphBuilder(cg) gb.apply_to(cfunc.body, None) #ac = AddressCollector(cg) #ac.collect() rg = RenamedGraphBuilder(cg, cfunc, vuu) rg.apply_to(cfunc.body, None) # Create tree from collected names cfunc.build_c_tree() new_graph = CFuncGraph(None) new_builder = GraphBuilder(new_graph) new_builder.apply_to(cfunc.body, None) function_info = dict() function_info["function"] = function_name function_info["ast"] = new_graph.json_tree(0) raw_code = "" for line in cfunc.get_pseudocode(): raw_code += idaapi.tag_remove(line.line) + '\n' function_info["raw_code"] = raw_code return function_info, cfunc
def to_masm(self): if self.verbatim: return "\t%s" % (idaapi.tag_remove( idaapi.generate_disasm_line(self.ea))) else: return "\t%s %s" % (idaapi.ua_mnem(self.ea), ", ".join( map(lambda e: e.to_masm(), self.ops)))
def callback(self, event, *args): if event == idaapi.hxe_populating_popup: form, phandle, vu = args if vu.item.citype == idaapi.VDI_FUNC or (vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr() and vu.item.e.type.is_funcptr()): idaapi.attach_action_to_popup(form, phandle, ACTION_HX_REMOVERETTYPE, None) elif event == idaapi.hxe_double_click: vu, shift_state = args # auto jump to target if clicked item is xxx->func(); if vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr(): expr = idaapi.tag_remove(vu.item.e.print1(None)) if "->" in expr: # find target function name = expr.split("->")[-1] addr = LocByName(name) if addr == idaapi.BADADDR: # try class::function e = vu.item.e while e.x: e = e.x addr = LocByName("%s::%s" % (str(e.type).split()[0], name)) if addr != idaapi.BADADDR: Jump(addr) return 1 return 0
def decompile(self, ea): if not self.use_decompiler: return False if ea in self.pseudo: return "\n".join(self.pseudo[ea]) decompiler_plugin = get_decompiler_plugin() if not init_hexrays_plugin() and not (load_plugin(decompiler_plugin) and init_hexrays_plugin()): return False f = get_func(ea) if f is None: return False try: cfunc = decompile(f) except: Warning("Error decompiling function: %s" % str(sys.exc_info())[1]) return False if cfunc is None: # Failed to decompile return False sv = cfunc.get_pseudocode() self.pseudo[ea] = [] for sline in sv: line = tag_remove(sline.line) if line.startswith("//"): continue self.pseudo[ea].append(line) return "\n".join(self.pseudo[ea])
def instruction(ea): insn = idaapi.generate_disasm_line(ea) unformatted = idaapi.tag_remove(insn) nocomment = unformatted[:unformatted.rfind(';')] return reduce( lambda t, x: t + (('' if t.endswith(' ') else ' ') if x == ' ' else x), nocomment, '')
def decode_instr(eip): MakeCode(eip) mnem = idaapi.ua_mnem(eip) sz = idaapi.decode_insn(eip) x = dict(nextip=[],inst=mnem, ops=[]) if not idaapi.cmd.itype in (idaapi.NN_jmp, idaapi.NN_retn): x['nextip'].append(eip+sz) for n, op in enumerate(idaapi.cmd.Operands): if op.type == 0: break ty = op.type text = idaapi.tag_remove(idaapi.ua_outop2(eip, n)) if op.dtyp == 0: bits = 8 elif op.dtyp == 1: bits = 16 elif op.dtyp == 2: bits = 32 if ty == idc.o_reg: x['ops'].append(IR.Var(text, bits)) elif ty == idc.o_mem: x['ops'].append(IR.Mem(IR.Const(op.addr),bits)) elif ty in (idc.o_phrase, idc.o_displ): x['ops'].append(IR.Mem(parse_mem(op),bits)) elif ty == idc.o_imm: x['ops'].append(IR.Const(op.value,bits)) elif ty == idc.o_near: x['ops'].append(IR.Const(op.addr)) x['nextip'].append(op.addr) else: raise UnknownError return x
def disasm(ea, count=1): res = [] while count > 0: insn = idaapi.generate_disasm_line(ea) unformatted = idaapi.tag_remove(insn) nocomment = unformatted[:unformatted.rfind(';')] if ';' in unformatted else unformatted res.append( '{:x}: {:s}'.format(ea, reduce(lambda t,x: t + (('' if t.endswith(' ') else ' ') if x == ' ' else x), nocomment, '')) ) ea = next(ea) count -= 1 return '\n'.join(res)
def decompile_context(addr, context_lines): cfunc = decompile(addr) if cfunc is None: return None y = get_decompile_coord_by_ea(cfunc, addr) lines = cfunc.get_pseudocode() retlines = (idaapi.tag_remove(lines[lnnum].line) for lnnum in range( max(0, y - context_lines), min(len(lines), y + context_lines))) return '\n'.join(retlines)
def visit_expr(self, e): op = e.op # if expression type is call if op == idaapi.cot_call: name = idaapi.tag_remove(e.x.print1(None)) # and if the function name is supported if name in MEMCPY_FAM: # parse self._parse_memcpy(e) return 0
def nab(address, IOCTL={}): for xref in idat.CodeRefsTo(address, True): name = ida.get_func_name(xref) offset = xref count = 0 while count < 16: if ida.tag_remove(ida.print_operand(offset, 0)) == 'esi': request = ida.tag_remove(ida.print_operand(offset, 1))[:-1] if len(request) != 8: request = request[1:] break offset -= 0x1 count += 1 IOCTL[name] = request return IOCTL
def get_selected_reg(self): reg = None lineno = self.GetLineNo() if lineno > len(dbg.registers) - 1: return reg line = self.GetLine(lineno) if line and len(line) > 0: line_str = idaapi.tag_remove(line[0]) reg = line_str[1:dbg.registers.max_len + 2].strip() return reg
def visit_expr(self, e): op = e.op # if expression type is call if op == idaapi.cot_call: name = idaapi.tag_remove(e.x.print1(None)) # print "name func = %s" % name # and if the function name is supported if name in DICT: # parse self._parse_function(e) return 0
def main(): if not idaapi.init_hexrays_plugin(): return False print "Hex-rays version %s has been detected" % idaapi.get_hexrays_version() f = idaapi.get_func(idaapi.get_screen_ea()); if f is None: print "Please position the cursor within a function" return True cfunc = idaapi.decompile(f); if cfunc is None: print "Failed to decompile!" return True sv = cfunc.get_pseudocode(); for sline in sv: print idaapi.tag_remove(sline.line); return True
def decompile_context(addr, context_lines): cfunc = decompile(addr) if cfunc is None: return None item = cfunc.body.find_closest_addr(addr) y_holder = idaapi.int_pointer() if not cfunc.find_item_coords(item, None, y_holder): return cfunc y = y_holder.value() lines = cfunc.get_pseudocode() retlines = (idaapi.tag_remove(lines[lnnum].line) for lnnum in range( max(0, y - context_lines), min(len(lines), y + context_lines))) return '\n'.join(retlines)
def func(ea): f = idaapi.get_func(ea) if hasattr(idaapi, "GetFunctionName"): function_name = GetFunctionName(ea) else: function_name = get_func_name(ea) print("Decompiling %s" % function_name) if f is None: print('Please position the cursor within a function') # Ignore thunk functions flags = idc.get_func_flags(ea) if flags > 0 and (flags & idaapi.FUNC_THUNK) != 0: print("Ignoring thunk function %s" % function_name) return None cfunc = None try: cfunc = idaapi.decompile(f) except ida_hexrays.DecompilationFailure as e: print('Failed to decompile %x: %s!' % (ea, function_name)) raise e # Rename decompilation graph cg = CFuncGraph(None) gb = GraphBuilder(cg) gb.apply_to(cfunc.body, None) ac = AddressCollector(cg) ac.collect() rg = RenamedGraphBuilder(cg, cfunc, ac.addresses) rg.apply_to(cfunc.body, None) # This will force the function porameters to be renamed even if # they aren't used in the body of the function for arg in cfunc.arguments: rg.visit_var(arg) # Create tree from collected names cfunc.build_c_tree() new_graph = CFuncGraph(None) new_builder = GraphBuilder(new_graph) new_builder.apply_to(cfunc.body, None) function_info = dict() function_info["function"] = function_name function_info["ast"] = new_graph.json_tree(0) raw_code = "" for line in cfunc.get_pseudocode(): raw_code += idaapi.tag_remove(line.line) + '\n' function_info["raw_code"] = raw_code return function_info
def _parse_memcpy(self, e): args = e.a dst_name = [] for i in args: if idc.GetString(i.obj_ea, -1, idc.ASCSTR_C) is not None: dst_name += [idc.GetString(i.obj_ea, -1, idc.ASCSTR_C)] else: dst_name += ["."] name = idaapi.tag_remove(e.x.print1(None)) self._add_func_call(TakeAttributes(e.ea, name, dst_name)) return True
def __init__(self, ea): self.ea = ea self.columns = [] if not isCode(GetFlags(ea)): MakeCode(ea) t = idaapi.generate_disasm_line(ea) if t: line = idaapi.tag_remove(t) else: line = "" self.columns.append ("%08X" % ea) n = SegName(ea) self.columns.append (n) self.columns.append (line)
def decompile_context(addr, context_lines): cfunc = decompile(addr) if cfunc is None: return None y = get_decompile_coord_by_ea(cfunc, addr) if y is None: return cfunc lines = cfunc.get_pseudocode() retlines = [] for lnnum in range(max(0, y - context_lines), min(len(lines), y + context_lines)): retlines.append(idaapi.tag_remove(lines[lnnum].line)) if lnnum == y: retlines[-1] = '>' + retlines[-1][1:] return '\n'.join(retlines)
def switch_value(self): lineno = self.GetLineNo() if lineno > len(dbg.registers.flags): return line = self.GetLine(lineno) line = idaapi.tag_remove(line[0]) flag = line[:4].strip() new_val = not self.flag_vals[flag] rc = idc.SetRegValue(int(new_val), flag) if not rc: idaapi.warning("Unable to update the register value") return self.parent.reload_view()
def add_comment(self): """ Add a commment to the selected line """ print("GhIDA:: [DEBUG] add_comment called") colored_line = self.GetCurrentLine(notags=1) if not colored_line: idaapi.warning("Select a line") return False # Use pygments to parse the line to check if there are comments line = idaapi.tag_remove(colored_line) lexer = CLexer() tokens = list(lexer.get_tokens(line)) text = "" text_comment = "" for t in tokens: ttype = t[0] ttext = str(t[1]) if ttype == Token.Comment.Single: text_comment = ttext.replace('//', '').strip() else: text += ttext # Get the new comment comment = gl.display_comment_form(text_comment) if not comment or len(comment) == 0: return False comment = comment.replace("//", "").replace("\n", " ") comment = comment.strip() # Create the new text full_comment = " // %s" % comment text = text.rstrip() new_text = text + full_comment text_colored = self.color_line(new_text) num_line = self.GetLineNo() self.EditLine(num_line, text_colored) self.RefreshCurrent() # Add comment to cache COMMENTS_CACHE.add_comment_to_cache(self.__ea, num_line, full_comment) print("GhIDA:: [DEBUG] Added comment to #line: %d (%s)" % (num_line, new_text)) return
def __init__(self, ea): self.ea = ea if not isCode(GetFlags(ea)): MakeCode(ea) t = idaapi.generate_disasm_line(ea) if t: line = idaapi.tag_remove(t) else: line = "" func = GetFunctionName(ea) self.display = hex(ea) + ": " if func: self.display += func + ": " else: n = SegName(ea) if n: self.display += n + ": " self.display += line
def OnDblClick(self, shift): line = self.GetCurrentLine() line = idaapi.tag_remove(line) #print('line is %s' % line) parts = line.split() index = None try: index = int(parts[0]) except: print('no index found in %s' % line) return command = '@cgc.goToWriteMark(%d)' % index #print('cmd is %s' % command) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = gdbProt.getEIPWhenStopped() self.isim.signalClient() return True
def OnDblClick(self, shift): line = self.GetCurrentLine() line = idaapi.tag_remove(line) #print('line is %s' % line) parts = line.split() branch_from = None try: branch_from = int(parts[3], 16) except: print('branch from not found in %s' % line) return command = '@cgc.goToBasicBlock(0x%x)' % branch_from #print('cmd is %s' % command) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = gdbProt.getEIPWhenStopped() self.isim.signalClient() return True
def get_decompiled_line(self, cfunc, ea): if ea not in cfunc.eamap: print 'strange, %x is not in %x eamap' % (ea, cfunc.entry_ea) return insnvec = cfunc.eamap[ea] lines = [] for stmt in insnvec: d = stmt.details s = stmt.details.print1(cfunc.__deref__()) s = idaapi.tag_remove(s) lines.append(s) return '\n'.join(lines)
def startarm(): curEA = idc.ScreenEA() isCont = 1 while isCont: t = idaapi.generate_disasm_line(curEA) if t: line = idaapi.tag_remove(t) else: line = "" str = AskStr(line,"Address :"+hex(curEA)+"\nInstruction") if str: try: arm(curEA,str) curEA = curEA + 4 except InputError as e: print e.msg else: isCont = 0
def __init__(self, ea): self.ea = ea if not is_code(get_flags(ea)): create_insn(ea) t = idaapi.generate_disasm_line(ea) if t: line = idaapi.tag_remove(t) else: line = "" func = get_func_name(ea) self.display = "" if func: self.display += func + ": " else: n = get_segm_name(ea) if n: self.display += n + ": " self.display += line
def decompile_func(ea): if not idaapi.init_hexrays_plugin(): return False f = idaapi.get_func(ea) if f is None: return False cfunc = idaapi.decompile(f) if cfunc is None: # Failed to decompile return False lines = [] sv = cfunc.get_pseudocode() for sline in sv: line = idaapi.tag_remove(sline.line) lines.append(line) return "\n".join(lines)
def to_masm(self): if self.verbatim: return "\t%s" % (idaapi.tag_remove(idaapi.generate_disasm_line(self.ea))) else: return "\t%s %s" % (idaapi.ua_mnem(self.ea), ", ".join(map(lambda e: e.to_masm(), self.ops)))
def instruction(ea): insn = idaapi.generate_disasm_line(ea) unformatted = idaapi.tag_remove(insn) nocomment = unformatted[:unformatted.rfind(';')] return reduce(lambda t,x: t + (('' if t.endswith(' ') else ' ') if x == ' ' else x), nocomment, '')
def AnalyzeRange( self, startEA, endEA ): CurrentAddress = startEA CurrentBlockAddress = CurrentAddress NewBlockStart = True last_op_code = '' while CurrentAddress < endEA: if idaapi.isCode( idaapi.get_flags_novalue( CurrentAddress ) ): idaapi.decode_insn( CurrentAddress ) op_code = idaapi.ua_mnem( CurrentAddress ) operands=[] disasm_line = op_code + ' ' for i in range(0, 6, 1): operand = idaapi.ua_outop2( CurrentAddress, i ) if not operand: break; operand = idaapi.tag_remove( operand ) operands.append( operand ) if i != 0: disasm_line += ',' disasm_line += operand #disasm_line = idaapi.tag_remove( idaapi.generate_disasm_line( CurrentAddress ) ) xref = idaapi.xrefblk_t() ret = xref.first_to( CurrentAddress, idaapi.XREF_FAR ) while ret: ret = xref.next_to() NewBlockStart = True if NewBlockStart and last_op_code[0:3] != 'ret' and last_op_code != 'new block': self.AddToMap( CurrentBlockAddress, CurrentAddress, None, 'link') if NewBlockStart: CurrentBlockAddress = CurrentAddress self.BlockData[CurrentBlockAddress]=[] if self.DebugLevel > 2: print '='*80 if self.DebugLevel > 2: print hex(CurrentAddress), disasm_line self.BlockData[CurrentBlockAddress].append( ( CurrentAddress, disasm_line ) ) NewBlockStart = False CallIsResolved = False ret = xref.first_from( CurrentAddress, idaapi.XREF_FAR ) while ret: if xref.iscode: if op_code == 'jmp' and xref.to == CurrentAddress + idaapi.cvar.cmd.size: NewBlockStart = True elif op_code == 'call': CallIsResolved = True self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'call') else: if len(operands) > 0 : self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'from') NewBlockStart = True ret = xref.next_from() if ( op_code == 'call' or op_code =='' ) and not CallIsResolved: self.AddToMap( CurrentBlockAddress, operands[0], operands[0], 'call') if NewBlockStart and op_code != 'jmp': self.AddToMap( CurrentBlockAddress, CurrentAddress + idaapi.cvar.cmd.size, '', 'link') if op_code[0:3] == 'ret': NewBlockStart = True last_op_code = op_code CurrentAddress += idaapi.cvar.cmd.size else: CurrentAddress += 1
def to_masm(self): s = idaapi.tag_remove(idaapi.ua_outop2(self.ea, self.idx)) s = do_special_op_replacements(s) return qualify_stack_struct_references(s, self.struct_vars)