def scan_virtual_function(self, index): if Helper.is_imported_ea(self.virtual_functions[index].address): print "[INFO] Ignoring import function at 0x{0:08X}".format( self.address) return try: function = idaapi.decompile(self.virtual_functions[index].address) except idaapi.DecompilationFailure: print "[ERROR] Failed to decompile function at 0x{0:08X}".format( self.address) return if Helper.FunctionTouchVisitor(function).process(): function = idaapi.decompile(self.virtual_functions[index].address) if function.arguments and function.arguments[ 0].is_arg_var and Helper.is_legal_type( function.arguments[0].tif): print "[Info] Scanning virtual function at 0x{0:08X}".format( function.entry_ea) scanner = VariableScanner.DeepSearchVisitor( function, self.offset, 0) scanner.apply_to(function.body, None) for candidate in scanner.candidates: Helper.temporary_structure.add_row(candidate) else: print "[Warning] Bad type of first argument in virtual function at 0x{0:08X}".format( function.entry_ea)
def scan_virtual_function(self, index): if Helper.is_imported_ea(self.virtual_functions[index].address): print "[INFO] Ignoring import function at 0x{0:08X}".format( self.address) return try: function = idaapi.decompile(self.virtual_functions[index].address) except idaapi.DecompilationFailure: print "[ERROR] Failed to decompile function at 0x{0:08X}".format( self.address) return if Helper.FunctionTouchVisitor(function).process(): function = idaapi.decompile(self.virtual_functions[index].address) if function.arguments and function.arguments[ 0].is_arg_var and Helper.is_legal_type( function.arguments[0].tif): print "[Info] Scanning virtual function at 0x{0:08X}".format( function.entry_ea) # TODO: Remove usage `temporary_structure' as global obj = Api.VariableObject(function.get_lvars()[0], 0) scanner = VariableScanner.NewDeepSearchVisitor( function, self.offset, obj, Cache.temporary_structure) scanner.process() else: print "[Warning] Bad type of first argument in virtual function at 0x{0:08X}".format( function.entry_ea)
def scan_virtual_function(self, index, temp_struct): if helper.is_imported_ea(self.virtual_functions[index].address): print("[INFO] Ignoring import function at 0x{0:08X}".format( self.address)) return try: function = idaapi.decompile(self.virtual_functions[index].address) except idaapi.DecompilationFailure: print("[ERROR] Failed to decompile function at 0x{0:08X}".format( self.address)) return if helper.FunctionTouchVisitor(function).process(): function = idaapi.decompile(self.virtual_functions[index].address) if function.arguments and function.arguments[ 0].is_arg_var and helper.is_legal_type( function.arguments[0].tif): from . import variable_scanner print("[Info] Scanning virtual function at 0x{0:08X}".format( function.entry_ea)) obj = api.VariableObject(function.get_lvars()[0], 0) scanner = variable_scanner.NewDeepSearchVisitor( function, self.offset, obj, temp_struct) scanner.process() else: print( "[Warning] Bad type of first argument in virtual function at 0x{0:08X}" .format(function.entry_ea))
def touch_all(self): for address in self.functions.difference(touched_functions): touched_functions.add(address) try: cfunc = idaapi.decompile(address) if cfunc: FunctionTouchVisitor(cfunc).process() except idaapi.DecompilationFailure: print "[ERROR] IDA failed to decompile function at 0x{address:08X}".format(address=address) idaapi.decompile(self.cfunc.entry_ea)
def touch_all(self): diff = self.functions.difference(Cache.touched_functions) for address in diff: if is_imported_ea(address): continue try: cfunc = idaapi.decompile(address) if cfunc: FunctionTouchVisitor(cfunc).process() except idaapi.DecompilationFailure: logger.warn("IDA failed to decompile function at {}".format(to_hex(address))) Cache.touched_functions.add(address) idaapi.decompile(self.cfunc.entry_ea)
def do_rename(category, ctor_addr, class_name): # type: (str, int, str) -> None if category == "Action": cfunc = idaapi.decompile(ctor_addr) do_rename_action(cfunc, class_name) if category == "AI": cfunc = idaapi.decompile(ctor_addr) do_rename_ai(cfunc, class_name) if category == "Behavior": cfunc = idaapi.decompile(ctor_addr) do_rename_behavior(cfunc, class_name) if category == "Query": cfunc = idaapi.decompile(ctor_addr) do_rename_query(cfunc, class_name)
def do_decompile(addr, filter=lambda x: True): func = addr name = GetFunctionName(func) name = demangle(name) code = idaapi.decompile(func) return name, code
def checkFunc(self, ea, **kwargs): usage = kwargs.get('usage') or False fn = idc.GetFunctionName(ea) try: func = idaapi.decompile(ea) if not func: return None except Exception as e: Logger.error("Error decompiling " + fn + ": " + str(e)) return None vrs = [] for v in func.lvars: t = v.type().dstr() if self.stname in t: vrs += [v.name + ("->" if '*' in t else '.') + self.fname] #Logger.debug("Checking function %s %s", fn, str(vrs)) ret = [] for i, x in enumerate(str(func).split("\n")): for y in vrs: if y not in x: continue x = x.strip() if not usage: p = x.find(y) if p != 0 or '=' not in x: continue ret += [{ 'address': fn + " : " + str(i), 'code': x, }] return ret
def set_hexrays_comment(address, text): cfunc = idaapi.decompile(address) tl = idaapi.treeloc_t() tl.ea = address tl.itp = idaapi.ITP_SEMI cfunc.set_user_cmt(tl, text) cfunc.save_user_cmts()
def get_decode_xrefs(): """ Find all cross-refernces to 0x132549a in our REvil malware sample. Decode the string and annotate the IDA database, this will make analysis a lot easier """ for xref in idautils.XrefsTo(0x132549a): # first of all, we need to find the arguments to this function, the signature is: # BYTE* __cdecl decode_string(char* base, int keyOffset, int keyLen, int dataLen, BYTE* pOut); args = get_decode_args(xref.frm) if args: base, key_offset, key_len, data_len = args # get the data from the image, data = [keyBytes][encryptedData] data = ida_bytes.get_bytes(base + key_offset, key_len + data_len) str = data_to_str(decode_string(data, key_len, data_len)) print("0x%08x: %s" % (xref.frm, str)) # put a comment in the code cfunc = idaapi.decompile(xref.frm) if cfunc is not None: tl = idaapi.treeloc_t() tl.ea = xref.frm tl.itp = idaapi.ITP_SEMI cfunc.set_user_cmt(tl, str) cfunc.save_user_cmts() idaapi.set_cmt(int(xref.frm), str, True) else: # We could not get the arguments, likely because it may be a register and not an immediate # value, so we'd need to go back further and find what value that register was assigned with. # Would be easier to just tell user, and let him decode it manually (HexRays has the actual args) print("0x%08x: Could not decode arguments" % xref.frm)
def auto_map_lvars(self, vdui=None, start_ea=None): func = None if start_ea is None: func = idaapi.get_func(idaapi.get_screen_ea()) start_ea = func.startEA if vdui is None: vdui = idaapi.get_tform_vdui(idaapi.get_current_tform()) if vdui is None: idaapi.jumpto(start_ea) vdui = idaapi.get_tform_vdui(idaapi.get_current_tform()) if func is None: func = idaapi.get_func(start_ea) self.de = idaapi.decompile(func) mapped_vars = False did_stuff = False self.assignments, overall_refs = self.analyze_fn() if self.map_vars_used_only_once(vdui, overall_refs): did_stuff = True mapped_vars = True elif self.map_lvars(vdui): did_stuff = True mapped_vars = True if mapped_vars: vdui.refresh_view(True) elif did_stuff: vdui.refresh_ctext() return did_stuff
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 floss_make_decompiler_comment(self, ea, str): cfunc = idaapi.decompile(ea) tl = idaapi.treeloc_t() tl.ea = ea tl.itp = idaapi.ITP_SEMI cfunc.set_user_cmt(tl, str) cfunc.save_user_cmts()
def activate(self, ctx): hx_view = idaapi.get_tform_vdui(ctx.form) address = hx_view.cfunc.entry_ea xref_ea = idaapi.get_first_cref_to(address) xrefs = set() while xref_ea != idaapi.BADADDR: xref_func_ea = idc.GetFunctionAttr(xref_ea, idc.FUNCATTR_START) if xref_func_ea != idaapi.BADADDR: xrefs.add(xref_func_ea) else: print "[Warning] Function not found at 0x{0:08X}".format(xref_ea) xref_ea = idaapi.get_next_cref_to(address, xref_ea) for func_ea in xrefs: visitor = VariableLookupVisitor(address) try: cfunc = idaapi.decompile(func_ea) if cfunc: FunctionTouchVisitor(cfunc).process() visitor.apply_to(cfunc.body, None) for idx in visitor.result: scanner = DeepSearchVisitor(cfunc, 0, idx) scanner.process() for field in scanner.candidates: self.temporary_structure.add_row(field) except idaapi.DecompilationFailure: print "[Warning] Failed to decompile function at 0x{0:08X}".format(xref_ea) DeepSearchVisitor.clear()
def parse_func(pfn): try: hf = idaapi.hexrays_failure_t() cfunc = idaapi.decompile(pfn.start_ea, hf) mbr = idaapi.mba_ranges_t(pfn) mba = idaapi.gen_microcode( mbr, hf, None, idaapi.DECOMP_NO_WAIT | idaapi.DECOMP_NO_CACHE, idaapi.MMAT_GLBOPT3 ) except Exception: return if mba is None: return G = Graph() ctree_state, ctree_expr, ctree_int, ctree_str, micro_int = [], [], [], [], [] # node level for i in range(mba.qty): mb = mba.get_mblock(i) minsn = mb.head blk = [] while minsn: ins = parse_minsn(minsn, micro_int) blk.append(ins) minsn = minsn.next vp = idaapi.qstring_printer_t(None, True) mb._print(vp) G.add_node(mb.serial, feat=blk, raw_data=vp.s) for succ in mb.succset: G.add_edge(mb.serial, succ) G.remove_featempty_nodes() if not G.have_nodes(): return # add a fake edge if there is no edge if not G.have_edges(): G.add_edge(G.graph['nodes'][0]['id'], G.graph['nodes'][0]['id']) # graph level ctree_fea = CtreeFeature(ctree_state, ctree_expr, ctree_int, ctree_str) ctree_fea.apply_to(cfunc.body, None) G.graph['graph']['c_state'], G.graph['graph']['c_expr'], G.graph['graph']['c_int'], G.graph['graph'][ 'c_str'], G.graph['graph']['m_int'] = ctree_state, ctree_expr, ctree_int, ctree_str, micro_int G.graph['graph']['arg_num'] = len(cfunc.argidx) func_bytes = b'' for start, end in idautils.Chunks(pfn.start_ea): fb = idaapi.get_bytes(start, end-start) func_bytes += fb G.graph['graph']['hash'] = hashlib.md5(func_bytes).hexdigest() return G.graph
def cfunc_from_ea(ea): """Get cfuncptr_t from EA.""" func = idaapi.get_func(ea) if func is None: return None cfunc = idaapi.decompile(func) return cfunc
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 decompile(self): """ decompile function """ try: return idaapi.decompile(self.at) except idaapi.DecompilationFailure, e: return repr(str(e))
def tinfo(self): # TODO: return void() when failed to decompile decompiled_function = idaapi.decompile(self.address) if decompiled_function: return idaapi.tinfo_t(decompiled_function.type) print "[ERROR] Failed to decompile function at 0x{0:08X}".format( self.address)
def set_hexray_cmmts(ea,text): cfunc = idaapi.decompile(ea) tl = idaapi.treeloc_t() tl.ea = ea tl.itp = idaapi.ITP_SEMI cfunc.set_user_cmt(tl,text) cfunc.save_user_cmts()
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 run(self): '''Start the plugin.''' if not idaapi.init_hexrays_plugin(): print "HRDEV Error: Failed to initialise Hex-Rays plugin." return function_name = idaapi.get_func_name(idaapi.get_screen_ea()) demangled_name = self.tools.demangle_name(function_name) file_name = '{}.cpp'.format(self.tools.to_file_name(demangled_name)) cache_path = os.path.sep.join([self.current_dir, 'data', 'cache', self._bin_name]) if not os.path.isdir(cache_path): os.mkdir(cache_path) complete_path = os.path.sep.join([cache_path, file_name]) if not os.path.isfile(complete_path): src = str(idaapi.decompile(idaapi.get_screen_ea())) self.tools.save_file(complete_path, src) self.tools.set_file_path(complete_path) max_title = self.config_main.getint('etc', 'max_title') self.gui = include.gui.Canvas(self.config_main, self.config_theme, self.tools, demangled_name[:max_title]) self.gui.Show('HRDEV') self.parser = include.syntax.Parser(self) self.parser.run(complete_path) return
def export_pseudocomments_from_fun(f_ea): d = {} d[f_ea] = {} #f_ea = 0x040033EC print "Attempting to decompile %x" % f_ea try: ct = idaapi.decompile(f_ea) except idaapi.DecompilationFailure: print "error during decompilation (IDA API)" return d user_cmts = ct.user_cmts num_cmts = idaapi.user_cmts_size(user_cmts) #export_user_variables(ct, f_ea) print "Function 0x%08x has %d pseudocomments" % (f_ea, num_cmts) it = idaapi.user_cmts_begin(user_cmts) #while it != idaapi.user_cmts_end(user_cmts) i = 0 while (i < num_cmts): t = idaapi.user_cmts_first(it) #treeloc_t c = idaapi.user_cmts_second(it) #user_cmts_t print "Comment: %s at addr: 0x%08x itp: %d" % (c.c_str(), t.ea, t.itp) d[f_ea][i] = {"ea": t.ea, "comment": c.c_str(), "itp": t.itp} i += 1 it = idaapi.user_cmts_next(it) return d
def import_pseudocomments_to_fun(f_ea, d): if d == {}: #print "skipping %x, empty" % f_ea return print "Attempting to decompile %x" % f_ea try: ct = idaapi.decompile(f_ea) except idaapi.DecompilationFailure: print "error during decompilation (IDA API)" return # i dont know when this happens, but for 404E1404, which is not really a function # this is triggered if not ct or ct.user_cmts == None: print "failed obtaining user cmts at %x" % f_ea return user_cmts = ct.user_cmts it = idaapi.user_cmts_begin(user_cmts) for i in d.iterkeys(): t = idaapi.treeloc_t() t.ea = d[i]["ea"] t.itp = d[i]["itp"] c = idaapi.citem_cmt_t(d[i]["comment"]) idaapi.user_cmts_insert(user_cmts, t, c)
def process_funcs(all_funcs): for func in all_funcs: # rename idc.set_name(func.start_ea, f"string_{func.start_ea:X}") # set type struc_id = idaapi.get_struc_id("std::string") # print(f"{struc_id:x}") if struc_id == idaapi.BADADDR: idc.set_local_type(-1, "struct std::string {char *ptr; size_t length; char buf[0x10];};", idaapi.PT_TYP) print("create std::string") func_tinfo = idaapi.tinfo_t() cfunc = idaapi.decompile(func.start_ea) cfunc.get_func_type(func_tinfo) func_details = idaapi.func_type_data_t() func_tinfo.get_func_details(func_details) std_string_tinfo = idaapi.tinfo_t() std_string_tinfo.get_named_type(idaapi.get_idati(), "std::string") std_string_ptr_tinfo = idaapi.tinfo_t() std_string_ptr_tinfo.create_ptr(std_string_tinfo) func_details[0].type = std_string_ptr_tinfo func_tinfo.create_func(func_details) idaapi.apply_tinfo(func.start_ea, func_tinfo, idaapi.TINFO_DEFINITE)
def _get_function_tif_with_hex_rays(offset): """ Attempt to get the tinfo_t object of a function using the Hex-Rays decompiler plugin. :param offset: Offset of function. :raises: RuntimeError on failure. :returns: tinfo_t object on success. """ tif = ida_typeinf.tinfo_t() # This requires Hexrays decompiler, load it and make sure it's available before continuing. if not idaapi.init_hexrays_plugin(): idc.load_and_run_plugin("hexrays", 0) or idc.load_and_run_plugin("hexx64", 0) if not idaapi.init_hexrays_plugin(): raise RuntimeError("Unable to load Hexrays decompiler.") # Pull type from decompiled C code. try: decompiled = idaapi.decompile(offset) except idaapi.DecompilationFailure: decompiled = None if decompiled is None: raise RuntimeError("Cannot decompile function at 0x{:X}".format(offset)) decompiled.get_func_type(tif) # Save type for next time. fmt = decompiled.print_dcl() fmt = "".join(c for c in fmt if c in string.printable and c not in ("\t", "!")) set_type_result = idc.SetType(offset, "{};".format(fmt)) if not set_type_result: logger.warning("Failed to SetType for function at 0x{:X} with decompiler type {!r}".format(offset, fmt)) return tif
def match_lines_asm(offset): func = idaapi.decompile(idaapi.get_func(offset)) lines = get_lines_ea(func) return [ (l, [(idc.GetDisasm(addr), int(addr), ) for addr in addrs]) for l, addrs in zip(str(func).splitlines(), lines) ]
def dump_functions(filter_text=None, fname=None): if fname is None: fname = dump_file f = open(fname, 'w') f.write( 'This file is a result of dump_decompiled(filter = %s, fname = %s)\n\n\n' % (filter_text, fname)) if not idaapi.init_hexrays_plugin(): return False for head in idautils.Functions(): func = idaapi.get_func(head) if func is None: continue nm = idaapi.get_func_name(head) if filter_text and not filter_text in nm: continue try: cfunc = idaapi.decompile(func) except: print "Failed to decompile %s!" % nm continue if cfunc is None: print "Failed to decompile %s!" % nm continue f.write(str(cfunc) + "\n\n\n") print "Dump complete. File %s" % fname
def export_pseudocomments_from_fun(f_ea): d = {} d[f_ea] = {} #f_ea = 0x040033EC print "Attempting to decompile %x" % f_ea try: ct = idaapi.decompile(f_ea) except idaapi.DecompilationFailure: print "error during decompilation (IDA API)" return d user_cmts = ct.user_cmts num_cmts = idaapi.user_cmts_size(user_cmts) #export_user_variables(ct, f_ea) print "Function 0x%08x has %d pseudocomments" % (f_ea, num_cmts) it = idaapi.user_cmts_begin(user_cmts) #while it != idaapi.user_cmts_end(user_cmts) i = 0 while (i < num_cmts): t = idaapi.user_cmts_first(it) #treeloc_t c = idaapi.user_cmts_second(it) #user_cmts_t print "Comment: %s at addr: 0x%08x itp: %d" % (c.c_str(), t.ea, t.itp) d[f_ea][i] = {"ea" : t.ea, "comment": c.c_str(), "itp": t.itp} i += 1 it = idaapi.user_cmts_next(it) return d
def decomp(self, decompPath, gameFiles=None): if not gameFiles: gameFiles = self.gameFiles for file in sorted(gameFiles.keys(), key=gameFiles.__getitem__): if file.endswith('.s'): filename = file[:file.rindex('.')] decomp = '' # decompile all functions within file print("> Decompiling %s... " % (self._getBaseFilename(file)[:-2] + '.c')) ea = gameFiles[file][0] while ea < gameFiles[file][1]: if Function.isFunction(ea): func = Function.Function(ea) # include address for ease of search in case of label name changes decomp += '// 0x%07x\n' % func.func_ea # try to decompile, or put the asm try: decomp += str(idaapi.decompile(func.func_ea)) + '\n\n' except ida_hexrays.DecompilationFailure as e: print('\tFailed to decompile %07X <%s>' % (func.func_ea, func.getName())) decomp += 'int %s() { // could not decompile\n' % func.getName() decomp += '\tasm("%s"\n\t);\n}\n\n' % func.getFormattedDisasm().replace('\n', '\\\n\t').rstrip() ea = func.func_ea + func.getSize(withPool=True) else: ea += idaapi.get_item_size(ea) # write decomp to file.c if decomp: decomp = decomp.replace(' ', ' ') decomp = decomp.replace('\t', ' ') print(self.projPath, decompPath) cFile = open(self.projPath[0] + decompPath + self._getBaseFilename(file)[:-2] + '.c', 'w') cFile.write(decomp) cFile.close() print("Decompilation complete!")
def run(self): '''Start the plugin.''' if not idaapi.init_hexrays_plugin(): print "HRDEV Error: Failed to initialise Hex-Rays plugin." return function_name = idaapi.get_func_name(idaapi.get_screen_ea()) demangled_name = self.tools.demangle_name(function_name) file_name = '{}.cpp'.format(self.tools.to_file_name(demangled_name)) cache_path = os.path.sep.join( [self.current_dir, 'data', 'cache', self._bin_name]) if not os.path.isdir(cache_path): os.mkdir(cache_path) complete_path = os.path.sep.join([cache_path, file_name]) if not os.path.isfile(complete_path): src = str(idaapi.decompile(idaapi.get_screen_ea())) self.tools.save_file(complete_path, src) self.tools.set_file_path(complete_path) max_title = self.config_main.getint('etc', 'max_title') self.gui = include.gui.Canvas(self.config_main, self.config_theme, self.tools, demangled_name[:max_title]) self.gui.Show('HRDEV') self.parser = include.syntax.Parser(self) self.parser.run(complete_path) return
def get_f5_comments(self): cmts = [] for seg in idautils.Segments(): ea = idc.SegStart(seg) if idc.GetSegmentAttr(ea, idc.SEGATTR_TYPE) != idaapi.SEG_CODE: continue seg_name = idc.SegName(seg) end = idc.SegEnd(seg) while ea < end: if ea != idc.BADADDR and idc.GetFunctionFlags( ea) != 0xffffffff: try: cfunc = idaapi.decompile(ea) for tl, citem in cfunc.user_cmts.items(): current_cmt = [ "%s:%-16X" % (seg_name, tl.ea), 'F5', idc.GetDisasm(tl.ea), citem.c_str() ] # F5 comments cmts.append(current_cmt) self.n += 1 except idaapi.DecompilationFailure: pass finally: ea = idc.GetFunctionAttr(ea, idc.FUNCATTR_END) else: ea = idc.next_head(ea, end) return cmts
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 decompile(addr): """ Function that overwrites `idaapi.decompile` for xmlrpc so that instead of throwing an exception on `idaapi.DecompilationFailure` it just returns `None`. (so that we don't have to parse xmlrpc Fault's exception string on pwndbg side as it differs between IDA versions). """ try: return idaapi.decompile(addr) except idaapi.DecompilationFailure: return None
def activate(self, ctx): for pfn_idx in ctx.chooser_selection: pfn = ida_funcs.getn_func(pfn_idx) if pfn: xrefs = [x for x in idautils.CodeRefsTo(pfn.start_ea, 0)] for xref in list(set(xrefs)): cfunc = idaapi.decompile(xref) if cfunc: xref_args = get_args(cfunc, xref, self.var_prop) self.callback(xref, cfunc, xref_args) return 1
def run(self): '''Start the plugin.''' if not idaapi.init_hexrays_plugin(): print "HRDEV Error: Failed to initialise Hex-Rays plugin." return function_name = idaapi.get_func_name(idaapi.get_screen_ea()) demangled_name = self.tools.demangle_name(function_name) file_name = '{}.cpp'.format(self.tools.to_file_name(demangled_name)) cache_path = os.path.sep.join([tempfile.gettempdir(), 'hrdev_cache', self._bin_name]) # Create require directories if they dont exist tmp_dir_path = os.path.sep.join([tempfile.gettempdir(), 'hrdev_cache']) if not os.path.isdir(tmp_dir_path): os.mkdir(tmp_dir_path) if not os.path.isdir(cache_path): os.mkdir(cache_path) complete_path = os.path.sep.join([cache_path, file_name]) idaapi.msg("HRDEV cache path: {}\n".format(complete_path)) src = idaapi.decompile(idaapi.get_screen_ea()) lvars = {} for v in src.lvars: _type = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, v.tif, '', '') lvars[str(v.name)] = "{} {} {}".\ format(_type, str(v.name), str(v.cmt)) # Check if file is already in cache if not os.path.isfile(complete_path): self.tools.save_file(complete_path, str(src)) self.tools.set_file_path(complete_path) max_title = self.config_main.getint('etc', 'max_title') self.gui = hrdev_plugin.include.gui.Canvas(self.config_main, self.config_theme, self.tools, lvars, demangled_name[:max_title]) self.gui.Show('HRDEV') self.parser = hrdev_plugin.include.syntax.Parser(self) self.parser.run(complete_path) return
def remove_rettype(self, vu): if vu.item.citype == idaapi.VDI_FUNC: # current function ea = vu.cfunc.entry_ea old_func_type = idaapi.tinfo_t() if not vu.cfunc.get_func_type(old_func_type): return False elif vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr() and vu.item.e.type.is_funcptr(): # call xxx ea = vu.item.get_ea() old_func_type = idaapi.tinfo_t() func = idaapi.get_func(ea) if func: try: cfunc = idaapi.decompile(func) except idaapi.DecompilationFailure: return False if not cfunc.get_func_type(old_func_type): return False else: return False else: return False fi = idaapi.func_type_data_t() if ea != idaapi.BADADDR and old_func_type.get_func_details(fi): # Return type is already void if fi.rettype.is_decl_void(): # Restore ret type if ea not in self.ret_type: return True ret = self.ret_type[ea] else: # Save ret type and change it to void self.ret_type[ea] = fi.rettype ret = idaapi.BT_VOID # Create new function info with new rettype fi.rettype = idaapi.tinfo_t(ret) # Create new function type with function info new_func_type = idaapi.tinfo_t() new_func_type.create_func(fi) # Apply new function type if idaapi.apply_tinfo2(ea, new_func_type, idaapi.TINFO_DEFINITE): return vu.refresh_view(True) return False
def get_items_for_ea(self, ea): frm = [x.frm for x in idautils.XrefsTo(self.__ea)] items = [] for ea in frm: try: cfunc = idaapi.decompile(ea) self.functions.append(cfunc.entry_ea) self.items.append((ea, idc.GetFunctionName(cfunc.entry_ea), self.get_decompiled_line(cfunc, ea))) except Exception as e: print 'could not decompile: %s' % (str(e), ) raise return
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 get_items_for_type(self): x = self.target.operands['x'] m = self.target.operands['m'] xtype = typestring(x.type.u_str()) xtype.remove_ptr_or_array() typename = str(xtype) addresses = [] for ea in idautils.Functions(): try: cfunc = idaapi.decompile(ea) cfunc.refcnt += 1 except: print 'Decompilation of %x failed' % (ea, ) continue str(cfunc) for citem in cfunc.treeitems: citem = citem.to_specific_type if not (type(citem) == idaapi.cexpr_t and citem.opname in ('memptr', 'memref')): continue _x = citem.operands['x'] _m = citem.operands['m'] _xtype = typestring(_x.type.u_str()) _xtype.remove_ptr_or_array() _typename = str(_xtype) #~ print 'in', hex(cfunc.entry_ea), _typename, _m if not (_typename == typename and _m == m): continue parent = citem while parent: if type(parent.to_specific_type) == idaapi.cinsn_t: break parent = cfunc.body.find_parent_of(parent) if not parent: print 'cannot find parent statement (?!)' continue if parent.ea in addresses: continue if parent.ea == idaapi.BADADDR: print 'parent.ea is BADADDR' continue addresses.append(parent.ea) self.functions.append(cfunc.entry_ea) self.items.append((parent.ea, idc.GetFunctionName(cfunc.entry_ea), self.get_decompiled_line(cfunc, int(parent.ea)))) return []
for stmt in insnvec: qp = idaapi.qstring_printer_t(c.__deref__(), False) stmt._print(0, qp) ss = qp.s.split('\n') for line in ss: print line if func_name in line and 'android_log_print' not in line: lines.append(line) #fcl.add(ref_ea, '\n'.join(lines)) else: #print 'reference %X in another function!' %ref_ea pass func_name = 'sub_1614' func_ea = getFunctionWithName(func_name) c = idaapi.decompile(func_ea) eamap = c.get_eamap() #print dir(eamap) func_name_to_fcl('accept') ''' print dir(c) args = c.arguments for arg in args: print arg.name print arg.get_regnum() #print dir(arg) #print arg.location.get_reginfo() b = c.body print dir(b) print dir(b.details) eamap = c.get_eamap()
import idc import idaapi import idautils from sets import Set from collections import defaultdict c = idaapi.decompile(idaapi.get_screen_ea()) func_ea = c.entry_ea class BasicBlock(): def __init__(self): self.start = 0 self.end = 0 self.succs = Set() self.preds = Set() def isIn(ea): return ea>=self.start and ea<=self.end def CFG(function_ea): f_start = function_ea f_end = FindFuncEnd(function_ea) edges = Set() boundaries = Set((f_start,)) # For each defined element in the function. for head in Heads(f_start, f_end): # If the element is an instruction if isCode(GetFlags(head)):
def run(): cfunc = idaapi.decompile(idaapi.get_screen_ea()) if not cfunc: print('Please move the cursor into a function.') return entry_ea = cfunc.entry_ea print("Dump of user-defined information for function at %x" % (entry_ea, )) # Display user defined labels. labels = idaapi.restore_user_labels(entry_ea); if labels is not None: print("------- %u user defined labels" % (len(labels), )) for org_label, name in labels.iteritems(): print("Label %d: %s" % (org_label, str(name))) idaapi.user_labels_free(labels) # Display user defined comments cmts = idaapi.restore_user_cmts(entry_ea); if cmts is not None: print("------- %u user defined comments" % (len(cmts), )) for tl, cmt in cmts.iteritems(): print("Comment at %x, preciser %x:\n%s\n" % (tl.ea, tl.itp, str(cmt))) idaapi.user_cmts_free(cmts) # Display user defined citem iflags iflags = idaapi.restore_user_iflags(entry_ea) if iflags is not None: print("------- %u user defined citem iflags" % (len(iflags), )) for cl, f in iflags.iteritems(): print("%x(%d): %08X%s" % (cl.ea, cl.op, f, " CIT_COLLAPSED" if f & idaapi.CIT_COLLAPSED else "")) idaapi.user_iflags_free(iflags) # Display user defined number formats numforms = idaapi.restore_user_numforms(entry_ea) if numforms is not None: print("------- %u user defined number formats" % (len(numforms), )) for ol, nf in numforms.iteritems(): print("Number format at %a, operand %d: %s" % (ol.ea, ol.opnum, "negated " if (nf.props & NF_NEGATE) != 0 else "")) if nf.is_enum(): print("enum %s (serial %d)" % (str(nf.type_name), nf.serial)) elif nf.is_char(): print("char") elif nf.is_stroff(): print("struct offset %s" % (str(nf.type_name), )) else: print("number base=%d" % (idaapi.get_radix(nf.flags, ol.opnum), )) idaapi.user_numforms_free(numforms) # Display user-defined local variable information lvinf = idaapi.lvar_uservec_t() if idaapi.restore_user_lvar_settings(lvinf, entry_ea): print("------- User defined local variable information\n") for lv in lvinf.lvvec: print("Lvar defined at %x" % (lv.ll.defea, )) if len(str(lv.name)): print(" Name: %s" % (str(lv.name), )) if len(str(lv.type)): #~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str()); print(" Type: %s" % (str(lv.type), )) if len(str(lv.cmt)): print(" Comment: %s" % (str(lv.cmt), )) return
def run(): cfunc = idaapi.decompile(idaapi.get_screen_ea()) if not cfunc: print 'Please move the cursor into a function.' return entry_ea = cfunc.entry_ea print "Dump of user-defined information for function at %x" % (entry_ea, ) # Display user defined labels. labels = idaapi.restore_user_labels(entry_ea); if labels is not None: print "------- %u user defined labels" % (len(labels), ) for org_label, name in labels.iteritems(): print "Label %d: %s" % (org_label, str(name)) idaapi.user_labels_free(labels) # Display user defined comments cmts = idaapi.restore_user_cmts(entry_ea); if cmts is not None: print "------- %u user defined comments" % (len(cmts), ) for tl, cmt in cmts.iteritems(): print "Comment at %x, preciser %x:\n%s\n" % (tl.ea, tl.itp, str(cmt)) idaapi.user_cmts_free(cmts) # Display user defined citem iflags iflags = idaapi.restore_user_iflags(entry_ea) if iflags is not None: print "------- %u user defined citem iflags" % (len(iflags), ) for cl, t in iflags.iteritems(): print "%a(%d): %08X%s" % (cl.ea, cl.op, f, " CIT_COLLAPSED" if f & CIT_COLLAPSED else "") idaapi.user_iflags_free(iflags) # Display user defined number formats numforms = idaapi.restore_user_numforms(entry_ea) if numforms is not None: print "------- %u user defined number formats" % (len(numforms), ) for ol, nf in numforms.iteritems(): print "Number format at %a, operand %d: %s" % (ol.ea, ol.opnum, "negated " if (nf.props & NF_NEGATE) != 0 else "") if nf.isEnum(): print "enum %s (serial %d)" % (str(nf.type_name), nf.serial) elif nf.isChar(): print "char" elif nf.isStroff(): print "struct offset %s" % (str(nf.type_name), ) else: print "number base=%d" % (idaapi.getRadix(nf.flags, ol.opnum), ) idaapi.user_numforms_free(numforms) # Display user-defined local variable information # First defined the visitor class class dump_lvar_info_t(idaapi.user_lvar_visitor_t): def __init__(self): idaapi.user_lvar_visitor_t.__init__(self) self.displayed_header = False return def get_info_qty_for_saving(self): return 0 def get_info_for_saving(self, lv): return False def handle_retrieved_info(self, lv): try: if not self.displayed_header: self.displayed_header = True; print "------- User defined local variable information" print "Lvar defined at %x" % (lv.ll.defea, ) if len(str(lv.name)): print " Name: %s" % (str(lv.name), ) if len(str(lv.type)): #~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str()); print " Type: %s" % (str(lv.type), ) if len(str(lv.cmt)): print " Comment: %s" % (str(lv.cmt), ) except: traceback.print_exc() return 0 def handle_retrieved_mapping(self, lm): return 0 def get_info_mapping_for_saving(self): return None # Now iterate over all user definitions dli = dump_lvar_info_t(); idaapi.restore_user_lvar_settings(entry_ea, dli) return