def __init__(self, ea, identifier=None, create_if_not_exists=True): """ :param ea: An address within the function. :param identifier: **DEPRECATED** Some custom unique identifier for this function. Historically this was the id of the YARA rule that hit this function. :param create_if_not_exists: If True, the function_creator will be used to attempt to create function if not defined by IDA. :raises AttributeError: If no function exists at the given address. """ self.origin_ea = ea self._identifier = identifier self.function_obj = idaapi.get_func(ea) if not self.function_obj: if create_if_not_exists: if create_function_precise(ea, False): self.function_obj = idaapi.get_func(ea) logger.debug("Created function at 0x%X" % self.function_obj.start_ea) else: raise AttributeError("No function at 0x%X" % ea) else: raise AttributeError("No function at 0x%X" % ea) if self.function_obj: self.start_ea = self.function_obj.start_ea self.end_ea = self.function_obj.end_ea self.name = idaapi.get_func_name(self.function_obj.start_ea) self.xrefs_to = [ ref.frm for ref in idautils.XrefsTo(self.function_obj.start_ea) if idaapi.get_func_name(ref.frm) != self.name ] self.xref_count = len(self.xrefs_to) self._flowchart = None self._api_calls = None
def __init__(self, ea, identifier=None, create_if_not_exists=True): super(SuperFunc_t, self).__init__() self.origin_ea = ea self.identifier = identifier self.function_obj = idaapi.get_func(ea) if not self.function_obj: if create_if_not_exists: if create_function_precise(ea, False): self.function_obj = idaapi.get_func(ea) logger.debug("Created function at 0x%X" % self.function_obj.start_ea) else: raise AttributeError("No function at 0x%X" % ea) else: raise AttributeError("No function at 0x%X" % ea) if self.function_obj: self.start_ea = self.function_obj.start_ea self.end_ea = self.function_obj.end_ea self.name = idaapi.get_func_name(self.function_obj.start_ea) self.xrefs_to = [ ref.frm for ref in idautils.XrefsTo(self.function_obj.start_ea) if idaapi.get_func_name(ref.frm) != self.name ] self.xref_count = len(self.xrefs_to) self._flowchart = None self._api_calls = None
def search_relationships(self): """Searching relationships between patterns. The goal of the method is to link pattern matches that are in the same area (function). It fills the `_links` attribute of each `Match`. """ patterns = self._patterns.get_patterns() # For all patterns for p1 in patterns: for p2 in patterns: # For all matches for m1 in p1.get_matches(): # Get the first node_t n1 = m1.get_match().values()[0][0] for m2 in p2.get_matches(): # Get the first node_t n2 = m2.get_match().values()[0][0] # If they are in the same area (function) try: b = get_func_name( n1.info.address) == get_func_name( n2.info.address) except: b = GetFunctionName( n1.info.address) == GetFunctionName( n2.info.address) if b: m1.add_link(m2)
def handleHookFuncCust(self, screenEA=None): if screenEA is not None: func = get_func(screenEA) else: func = get_func(ScreenEA()) if func is None: return address = func.startEA # safety checks, can be start of the function if address in self.idbHookMap and self.idbHookMap[ address].hook.type == "inst": dlg = AskYN( 0, "Address contains instruction hook!\nDo you want to remove it?" ) if dlg != 1: return # remove instruction hook self.handleUnhookInst(address) offset, moduleName = self.getAddressDetails(address) hookDlg = FunctionHookDialog(moduleName, "%X" % address, get_func_name(address), None, None) hookDlg.Compile() hookDlg.script_enter.value = "" hookDlg.script_leave.value = "" ok = hookDlg.Execute() if ok != 1: return hook = FuncHook() hook.id = address hook.symbol = get_func_name(address) hook.address = offset hook.module = moduleName hook.once = True if hookDlg.trigger.value == 0 else False hook.enterRecentSrcFile = hookDlg.recentScriptFileEnter hook.enterScript = hookDlg.script_enter.value hook.leaveRecentSrcFile = hookDlg.recentScriptFileLeave hook.leaveScript = hookDlg.script_leave.value entry = HookEntry(hook) outJSON = json.dumps({ "req_id": kFridaLink_SetHookRequest, "data": entry.genSetRequest() }) SetColor(address, CIC_FUNC, kIDAViewColor_HookedFunc) refresh_idaview_anyway() self.clientSocket.sendto(outJSON, self.clientAddress) self.idbHookMap[address] = entry self.idbHooksView.setContent(self.idbHookMap)
def upload(self, ea): try: func_id = self.mgr.upload(ea) except DecompilationFailure as e: BinaryAILog.fail(idaapi.get_func_name(ea), str(e)) except BinaryAIException as e: BinaryAILog.fatal(e) if func_id: BinaryAILog.success(idaapi.get_func_name(ea), "uploaded")
def get_func_name(self, address): name = idc.Demangle(idaapi.get_func_name(address), idc.GetLongPrm(idc.INF_LONG_DN)) if name != None: name = re.sub(r'[A-Za-z0-9_]+::', r'', name) name = re.sub(r'^public: ', r'', name) name = re.sub(r'unsigned short const \*', r'const wchar_t *', name) name = re.sub(r'unsigned short \*', r'wchar_t *', name) return name else: return idaapi.get_func_name(address)
def handleReplaceFunc(self, screenEA = None): if screenEA is not None: func = get_func(screenEA) else: func = get_func(ScreenEA()) if func is None: return address = func.startEA; offset, moduleName = self.getAddressDetails(address) replaceDlg = FunctionReplaceDialog(moduleName, "%X" % address, get_func_name(address), None) replaceDlg.Compile() replaceDlg.script.value = "" ok = replaceDlg.Execute() if ok != 1: return replace = FuncReplace() replace.id = address replace.symbol = get_func_name(address) replace.address = offset replace.module = moduleName replace.moduleImport = False replace.ret_type = "\'" + replaceDlg.ret_type.value + "\'" replace.recentSrcFile = replaceDlg.recentScriptFile replace.script = replaceDlg.script.value replace.args_str = replaceDlg.args.value replace.arg_types = "" replace.arg_names = "" if replace.args_str != "": args_list = replace.args_str.split(",") for arg in args_list: arg_list = arg.split() replace.arg_types += "\'" + arg_list[0] + "\', " replace.arg_names += arg_list[1] + ", " replace.arg_types = replace.arg_types[:-2] replace.arg_names = replace.arg_names[:-2] outJSON = json.dumps({ "req_id": kFridaLink_SetReplaceRequest, "data": replace.genSetRequest() }) SetColor(address, CIC_FUNC, kIDAViewColor_ReplacedFunc) refresh_idaview_anyway() self.clientSocket.sendto(outJSON, self.clientAddress) self.funcReplaceMap[address] = replace self.funcReplaceView.setContent(self.funcReplaceMap)
def recursive_prefix(addr): """ Recursively prefix a function tree with a user defined string. """ func_addr = idaapi.get_name_ea(idaapi.BADADDR, idaapi.get_func_name(addr)) if func_addr == idaapi.BADADDR: idaapi.msg("Prefix: 0x%08X does not belong to a defined function\n" % addr) return # NOTE / COMPAT: # prompt the user for a prefix to apply to the selected functions if using_ida7api: tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag") else: tag = idaapi.askstr(0, PREFIX_DEFAULT, "Function Tag") # the user closed the window... ignore if tag == None: return # the user put a blank string and hit 'okay'... notify & ignore elif tag == '': idaapi.warning("[ERROR] Tag cannot be empty [ERROR]") return # recursively collect all the functions called by this function nodes_xref_down = graph_down(func_addr, path=set([])) # graph_down returns the int address needs to be converted tmp = [] tmp1 = '' for func_addr in nodes_xref_down: tmp1 = idaapi.get_func_name(func_addr) if tmp1: tmp.append(tmp1) nodes_xref_down = tmp # prefix the tree of functions for rename in nodes_xref_down: func_addr = idaapi.get_name_ea(idaapi.BADADDR, rename) if tag not in rename: idaapi.set_name(func_addr, '%s%s%s' % (str(tag), PREFIX_SEPARATOR, rename), idaapi.SN_NOWARN) # refresh the IDA views refresh_views()
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 apply_labels(fun_names): new_sub = 0 new_som = 0 new_oth = 0 named_overwrittens = [] for f_ea, name in fun_names.iteritems(): name = re.sub('[^a-zA-Z0-9_]+', '', name) curr_name = idaapi.get_func_name(f_ea) if curr_name.startswith("sub_"): new_sub += 1 elif "_something" in curr_name: new_som += 1 else: new_oth += 1 named_overwrittens.append(curr_name) #so we don't overwrite these continue # stats counting aside, make sure we don't overwrite non-sub # functions from e.g. our IDC assignments if not curr_name.startswith("sub_") and not "_something" in curr_name: continue ret = idc.LocByName(name) count = 1 while (ret != 0xffffffff): count += 1 ret = idc.LocByName(name + "__" + "%d" % count) idc.MakeName(f_ea, name + ("__%d" % count)*(count > 1))
def __init__(self, func): self.src = func ea = func.startEA self.ea = ea self.name = idaapi.get_func_name(ea) self.elts = [] if idaapi.is_func_tail(func): self.name += "_tail_" + str(ea) fr = idaapi.get_frame(func) struc_vars = [] if fr == None: self.frame = None else: self.frame = struct.frame_node(fr, func) struc_vars = self.frame.struct_vars while ea < func.endEA: if idaapi.isData(idaapi.getFlags(ea)): self.elts.append(data.data_node(ea, idaapi.next_not_tail(ea))) else: if ea == func.startEA and not (idaapi.is_func_tail(func)): self.elts.append(insn.insn_node(ea, struc_vars)) else: self.elts.append( names.name_wrap_insn(ea, insn.insn_node(ea, struc_vars))) ea = idaapi.next_head(ea, func.endEA)
def rename_parents(self, fn, user_prefix, layer): has_default = 0 if layer > 10: print("layer >10") return for ref in idautils.CodeRefsTo(self.start_ea_of(fn), 1): parrent_func_p = '{:x}'.format(ref) #if len(fn_an['math']) < self._MIN_MAX_MATH_OPS_TO_ALLOW_RENAME: jeanfixme: check the max length can be set here parent_name = idaapi.get_func_name(ref) print(parrent_func_p + ":" + parent_name) if not (user_prefix in parent_name): parent_prefix = user_prefix + 'p' + str(layer) + '_' print("user_prefix=" + user_prefix) if 'sub' in parent_name: #replace the sub_with user prefix parent_new_name = parent_name.replace( 'sub_', parent_prefix) parent_fn = idaapi.get_func(ref) force_name(self.start_ea_of(parent_fn), parent_new_name) print("[parent]rename \"" + parent_name + "\" (" + parrent_func_p + ") to " + parent_new_name) self.rename_parents(parent_fn, user_prefix, layer + 1) has_default = 1 #else: jeanfixme: only rename the default one. #parent_new_name= parent_prefix + parent_name #print("[parent]rename \"" + parent_name+ "\" ("+parrent_func_p+") to " + parent_new_name) else: print("user_prefix \"" + user_prefix + "\" in (" + parrent_func_p + ") " + parent_name) return has_default
def get_funcRVA_by_name(name): for section in idautils.Segments(): for func_rva in idautils.Functions(section, idc.SegEnd(section)): if name == idaapi.get_func_name(func_rva): return idaapi.get_func(func_rva) return None
def __init__(self, func): self.src = func ea = func.startEA self.ea = ea self.name = idaapi.get_func_name(ea) self.elts = [] if idaapi.is_func_tail(func): self.name += "_tail_"+str(ea) fr = idaapi.get_frame(func) struc_vars = [] if fr == None: self.frame = None else: self.frame = struct.frame_node(fr, func) struc_vars = self.frame.struct_vars while ea < func.endEA: if idaapi.isData(idaapi.getFlags(ea)): self.elts.append(data.data_node(ea, idaapi.next_not_tail(ea))) else: if ea == func.startEA and not (idaapi.is_func_tail(func)): self.elts.append(insn.insn_node(ea, struc_vars)) else: self.elts.append(names.name_wrap_insn(ea, insn.insn_node(ea, struc_vars))) ea = idaapi.next_head(ea, func.endEA)
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 retrieve_function_with_check(self, ea, topk, funcset_ids): succ, skip, fail = 0, 1, 2 targets = None pfn = idaapi.get_func(ea) if idaapi.FlowChart(pfn).size < self.cfg['minsize']: return skip try: targets = self.retrieve_function(ea, topk=topk, funcset_ids=funcset_ids) except DecompilationFailure: pass except BinaryAIException as e: idaapi.hide_wait_box() assert False, "[BinaryAI] {}".format(e._msg) if targets is None: print("[{}] {} failed because get function feature error".format( self.name, idaapi.get_func_name(ea))) return fail func = targets[0] if func['score'] < self.cfg['threshold']: return skip if not bai_mark.apply_bai_high_score( pfn.start_ea, targets[0]['function']['name'], func['score']): return skip return succ
def _match_with_check(self, ea, topk, funcset_ids): fail, skip, succ = -1, 0, 1 # < minsize pfn = idaapi.get_func(ea) if idaapi.FlowChart(pfn).size < bai_config['minsize']: return skip # do match try: targets = self.mgr.retrieve(ea, topk=bai_config['topk'], funcset_ids=funcset_ids) except DecompilationFailure as e: BinaryAILog.fail(idaapi.get_func_name(ea), str(e)) return fail except BinaryAIException as e: idaapi.hide_wait_box() BinaryAILog.fatal(e) if targets is None: return fail if targets[0]['score'] < bai_config['threshold'] or \ not bai_mark.apply_bai_high_score( ea, targets[0]['function']['name'], targets[0]['score']): return skip return succ
def fun_xrefs(self): res = {} for s in idautils.Strings(): s_ea = s.ea s_v = str(s).rstrip() dprint('checking %x - %s' % (s_ea, s_v)) s_xrefs_eas = self.xrefs_to(s_ea) if not s_xrefs_eas: dprint('no xref found for %s' % s_v) s_xrefs_eas = [s_ea] # same string can be xref'ed by more than one function for fs_ea in s_xrefs_eas: dprint('looking for function of %x' % fs_ea) f_name = idaapi.get_func_name(fs_ea) f_ea = idc.get_func_attr(fs_ea, idc.FUNCATTR_START) if not f_name or f_name == '': f_name = NO_FUNC if f_ea in res: res[f_ea]['strings'][s_v] = IdaString(s_v, s_ea, fs_ea) else: res[f_ea] = dict({ 'name': f_name, 'strings': { s_v: IdaString(s_v, s_ea, fs_ea) } }) return res
def renamer_init(): renamed = 0 gopclntab = get_gopclntab_seg() if gopclntab is not None: # Skip unimportant header and goto section size addr = gopclntab.startEA + 8 size, addr_size = create_pointer(addr) addr += addr_size # Unsure if this end is correct early_end = addr + (size * addr_size * 2) while addr < early_end: func_offset, addr_size = create_pointer(addr) name_offset, addr_size = create_pointer(addr + addr_size) addr += addr_size * 2 func_name_addr = Dword(name_offset + gopclntab.startEA + addr_size) + gopclntab.startEA func_name = GetString(func_name_addr) appended = clean_func_name = clean_function_name(func_name) debug( 'Going to remap function at 0x%x with %s - cleaned up as %s' % (func_offset, func_name, clean_func_name)) if idaapi.get_func_name(func_offset) is not None: if MakeName(func_offset, clean_func_name): renamed += 1 else: error('clean_func_name error %s' % clean_func_name) return renamed
def renamer_init(): renamed = 0 gopclntab = get_gopclntab_seg() if gopclntab is not None: # Skip unimportant header and goto section size addr = gopclntab.startEA + 8 size, addr_size = create_pointer(addr) addr += addr_size # Unsure if this end is correct early_end = addr + (size * addr_size * 2) while addr < early_end: func_offset, addr_size = create_pointer(addr) name_offset, addr_size = create_pointer(addr + addr_size) addr += addr_size * 2 func_name_addr = Dword(name_offset + gopclntab.startEA + addr_size) + gopclntab.startEA func_name = get_strlit_contents(func_name_addr) #RemotePdb('127.0.0.1', 7777).set_trace() # TODO: why does this flat out break? #MakeStr(func_name_addr, func_name_addr + len(func_name)) appended = clean_func_name = clean_function_name(func_name) debug( 'Going to remap function at 0x%x with %s - cleaned up as %s' % (func_offset, func_name, clean_func_name)) if idaapi.get_func_name(func_offset) is not None: if MakeName(func_offset, clean_func_name): renamed += 1 else: error('clean_func_name error %s' % clean_func_name) return renamed
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 handleQuickFuncHook(self, address, once): # safety checks, can be start of the function if address in self.idbHookMap and self.idbHookMap[ address].hook.type == "inst": dlg = AskYN( 0, "Address contains instruction hook!\nDo you want to remove it?" ) if dlg != 1: return # remove instruction hook self.handleUnhookInst(address) offset, moduleName = self.getAddressDetails(address) hook = FuncHook() hook.id = address hook.symbol = get_func_name(address) hook.address = offset hook.module = moduleName hook.once = once entry = HookEntry(hook) outJSON = json.dumps({ "req_id": kFridaLink_SetHookRequest, "data": entry.genSetRequest() }) SetColor(address, CIC_FUNC, kIDAViewColor_HookedFunc) refresh_idaview_anyway() self.clientSocket.sendto(outJSON, self.clientAddress) self.idbHookMap[address] = entry self.idbHooksView.setContent(self.idbHookMap)
def btn_pick_clicked(self): ida_f = idaapi.choose_func("Pick a function to hook", idaapi.BADADDR) func_addr = ida_f.startEA func_name = idaapi.get_func_name(func_addr) self.picked_function = func_addr self.edit_picked_fun.setText("0x{:X} ({})".format(func_addr, func_name))
def func_name_propagate_thunk(ea): current_name = get_func_name(ea) if current_name[0].isalpha(): return current_name func = idaapi.get_func(ea) temp_ptr = idaapi.ea_pointer() ea_new = idaapi.BADADDR if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK: ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast()) if ea_new != idaapi.BADADDR: ea = ea_new propagated_name = get_func_name(ea) or '' # Ensure it is not `None` if len(current_name) > len(propagated_name) > 0: return propagated_name else: return current_name
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 query_all_callback(self, threshold=0.8, minsize=3): for ea in idautils.Functions(): pfn = idaapi.get_func(ea) func_name = idaapi.get_func_name(ea) if idaapi.FlowChart(pfn).size < minsize: print( "[BinaryAI] {} is skipped because basicblock size lower than minsize({})" .format(func_name, minsize)) continue funcs = self.query_function(ea) if funcs is None: print( "[BinaryAI] {} is skipped because get function feature error" .format(func_name, threshold)) continue func = funcs[0] if func['score'] < threshold: print( "[BinaryAI] {} is skipped because top1_score lower than threshold({})" .format(func_name, threshold)) continue idc.set_color(ea, idc.CIC_FUNC, 0xFFFFE1) idc.set_func_flags(ea, idc.get_func_flags(ea) | 0x10000) comment = SourceCodeViewer.source_code_comment(func_name, func) idaapi.set_func_cmt(pfn, comment, 0)
def apply_labels(fun_names): new_sub = 0 new_som = 0 new_oth = 0 named_overwrittens = [] for f_ea, name in fun_names.iteritems(): name = re.sub('[^a-zA-Z0-9_]+', '', name) curr_name = idaapi.get_func_name(f_ea) if curr_name.startswith("sub_"): new_sub += 1 elif "_something" in curr_name: new_som += 1 else: new_oth += 1 named_overwrittens.append(curr_name) #so we don't overwrite these continue # stats counting aside, make sure we don't overwrite non-sub # functions from e.g. our IDC assignments if not curr_name.startswith("sub_") and not "_something" in curr_name: continue ret = idc.LocByName(name) count = 1 while (ret != 0xffffffff): count += 1 ret = idc.LocByName(name + "__" + "%d" % count) idc.MakeName(f_ea, name + ("__%d" % count) * (count > 1))
def __init__(self, node_id: int, obj_ea: int, func_name: t.Optional[str]): self.node_id = node_id self.obj_ea = obj_ea if func_name: self.func_name = func_name else: func_name = ida.get_func_name(self.obj_ea) self.func_name = func_name if func_name else None
def name(fn, name=None): fn = by(fn) if name is None: res = idaapi.get_func_name(fn.startEA) if not res: res = idaapi.get_name(-1, fn.startEA) if not res: res = idaapi.get_true_name(fn.startEA, fn.startEA) return res return idaapi.set_name(fn.startEA, name, idaapi.SN_PUBLIC)
def retrieve_function(self, ea, topk): func_feat = bai.ida.get_func_feature(ea) func_name = idaapi.get_func_name(ea) if func_feat and func_name: func_id = bai.function.upload_function(self.client, func_name, func_feat) targets = bai.function.search_sim_funcs(self.client, func_id, funcset_ids=None, topk=topk) return targets return None
def _refresh_name(self): """ Refresh the function name against the open database. """ if using_ida7api: self.name = idaapi.get_func_name(self.address) else: self.name = idaapi.get_func_name2(self.address)
def find_func_by_name(name): text_seg = idaapi.get_segm_by_name('.text') for addr in Functions(text_seg.startEA, text_seg.endEA): if name == idaapi.get_func_name(addr): return idaapi.get_func(addr) return None
def traverse_xrefs(func): func_created = 0 if func is None: return func_created # First func_xref = idaapi.get_first_cref_to(func.startEA) # Attempt to go through crefs while func_xref != BADADDR: # See if there is a function already here if idaapi.get_func(func_xref) is None: # Ensure instruction bit looks like a jump func_end = FindCode(func_xref, SEARCH_DOWN) if GetMnem(func_end) == "jmp": # Ensure we're jumping back "up" func_start = GetOperandValue(func_end, 0) if func_start < func_xref: if idc.MakeFunction(func_start, func_end): func_created += 1 else: # If this fails, we should add it to a list of failed functions # Then create small "wrapper" functions and backtrack through the xrefs of this error( 'Error trying to create a function @ 0x%x - 0x%x' % (func_start, func_end)) else: xref_func = idaapi.get_func(func_xref) # Simple wrapper is often runtime_morestack_noctxt, sometimes it isn't though... if is_simple_wrapper(xref_func.startEA): debug('Stepping into a simple wrapper') func_created += traverse_xrefs(xref_func) if idaapi.get_func_name( xref_func.startEA ) is not None and 'sub_' not in idaapi.get_func_name( xref_func.startEA): debug('Function @0x%x already has a name of %s; skipping...' % (func_xref, idaapi.get_func_name(xref_func.startEA))) else: debug('Function @ 0x%x already has a name %s' % (xref_func.startEA, idaapi.get_func_name(xref_func.startEA))) func_xref = idaapi.get_next_cref_to(func.startEA, func_xref) return func_created
def find_all_switch_jumps(self): self._switch_dict = defaultdict(list) next_switch = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24") while next_switch != idc.BADADDR: sw = idaapi.get_switch_info_ex(next_switch) if idc.GetMnem(next_switch).startswith("jmp") and sw: ic = self.get_jlocs(sw) self._switch_dict[idaapi.get_func_name(next_switch)].append((next_switch, sw.ncases, ic)) next_switch = idc.FindBinary(idc.NextHead(next_switch), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
def recursive_prefix(addr): """ Recursively prefix a function tree with a user defined string. """ func_addr = idc.LocByName(idaapi.get_func_name(addr)) if func_addr == idaapi.BADADDR: idaapi.msg("Prefix: 0x%08X does not belong to a defined function\n" % addr) return # prompt the user for a prefix to apply to the selected functions tag = idc.AskStr(PREFIX_DEFAULT, "Function Tag") # the user closed the window... ignore if tag == None: return # the user put a blank string and hit 'okay'... notify & ignore elif tag == '': idc.Warning("[ERROR] Tag cannot be empty [ERROR]") return # recursively collect all the functions called by this function nodes_xref_down = graph_down(func_addr, path=set([])) # graph_down returns the int address needs to be converted tmp = [] tmp1 = '' for func in nodes_xref_down: tmp1 = idaapi.get_func_name(func) if tmp1: tmp.append(tmp1) nodes_xref_down = tmp # prefix the tree of functions for rename in nodes_xref_down: func_addr = idc.LocByName(rename) if tag not in rename: idc.MakeNameEx(func_addr, '%s%s%s' % (str(tag), PREFIX_SEPARATOR, rename), idaapi.SN_NOWARN) # refresh the IDA views refresh_views()
def getName(ea): '''fetches the function name, or the global name''' res = idaapi.get_func_name(ea) if res is None: res = idaapi.get_name(-1, ea) if res is None: res = idaapi.get_true_name(ea, ea) # if name is mangled... and version <= 6.4 if res and res.startswith('@'): return '$'+res return res
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 load(self): self._bytestring_table.clear() self._bytestring_table.setColumnCount(3) self._bytestring_table.setHorizontalHeaderLabels(("Address", "Function", "String")) self._bytestring_table.itemDoubleClicked.connect(self.click_row) self.find_byte_strings() self._bytestring_table.setRowCount(len(self.byte_strings.keys())) row = 0 for addr, bstr in self.byte_strings.items(): self._bytestring_table.setItem(row, 0, QtGui.QTableWidgetItem(addr)) self._bytestring_table.setItem(row, 1, QtGui.QTableWidgetItem(idaapi.get_func_name(int(addr[2:], 16)))) self._bytestring_table.setItem(row, 2, QtGui.QTableWidgetItem(bstr)) self._bytestring_table.resizeRowToContents(row) row += 1 self._bytestring_table.setSortingEnabled(True) self._bytestring_table.resizeRowsToContents() self._bytestring_table.resizeColumnsToContents()
def find_import_ref(dllname): imports = find_imported_funcs(dllname) R = dict() for i, (ea, name,_) in enumerate(imports): #print "%x -> %s" % (ea, name) for xref in idautils.XrefsTo(ea): # check if referrer is a thunk ea = xref.frm f = idaapi.get_func(ea) if f and (f.flags & idaapi.FUNC_THUNK) != 0: imports.append([f.startEA, idaapi.get_func_name(f.startEA), 0]) #print "\t%x %s: from a thunk, parent added %x" % (ea, name, f.startEA) continue # save results if not R.has_key(i): R[i] = [] R[i].append(ea) return (imports, R)
def req_rln(self, hash): raddr, rbase, offset, base = hash["raddr"], hash["rbase"], hash["offset"], hash["base"] print ("[*] 0x%x - 0x%x - 0x%x - 0x%x" % (raddr, rbase, offset, base)) addr = self.rebase(rbase, raddr) if not addr: print ("[*] could not rebase this address (0x%x)" % raddr) return sym = idaapi.get_func_name(addr) if sym: sym = self.demangle(sym) func = idaapi.get_func(addr) if not func: print ("[*] could not find func for 0x%x" % addr) return lck = idaapi.lock_func(func) limits = idaapi.area_t() if idaapi.get_func_limits(func, limits): if limits.startEA != addr: if addr > limits.startEA: sym = "%s%s0x%x" % (sym, "+", addr - limits.startEA) else: sym = "%s%s0x%x" % (sym, "-", limits.startEA - addr) lck = None else: sym = idc.Name(addr) if sym: sym = self.demangle(sym) if sym: self.notice_broker("cmd", '"cmd":"%s"' % sym) print ("[*] resolved symbol: %s" % sym) else: print ("[*] could not resolve symbol for address 0x%x" % addr)
def get_all_funcs(): """ Enumerate all function names defined in the IDB. """ return set(idaapi.get_func_name(ea) for ea in idautils.Functions())
#!/usr/bin/python """ Tree of Savior IDAPython Script Automatic rename of functions containing a debug message """ import re import idautils import idc import idaapi s = idautils.Strings(False) s.setup(strtypes=Strings.STR_UNICODE | Strings.STR_C) for i, v in enumerate(s): if v is None: print("Failed to retrieve string index %d" % i) else: matchObj = re.match( r'.*(?:\_\_.*?) (.*)\(.*\)', str(v), re.M|re.I) # Regex to get strings that contain a function name if matchObj and "<" not in matchObj.group(1) and ">" not in matchObj.group(1): sub1 = re.sub(r'<[^)]*>', '', matchObj.group(1)) sub2 = re.sub(r'\[[^)]*\]', '', sub1) print "Found function: " + sub2.strip() for xref in XrefsTo(v.ea, 0): # Get xrefs of the strings we find func = idaapi.get_func(xref.frm) # Get the function the xref is in if func is not None: print "Renaming " + idaapi.get_func_name(func.startEA) + " to " + sub2.strip() + " at " + hex(func.startEA), if MakeNameEx(func.startEA, sub2.strip(), SN_NOWARN): print " Success" else: print " Fail" print ""