我们从Python开源项目中,提取了以下29个代码示例,用于说明如何使用idautils.Functions()。
def dump_function_delta(self): """ Dump the computed function delta. """ lmsg("Functions added:") lmsg(hex_list(self.functions_added)) lmsg("Functions removed:") lmsg(hex_list(self.functions_removed)) lmsg("Functions modified:") lmsg(hex_list(self.functions_modified)) #-------------------------------------------------------------------------- # Async Metadata Helpers #--------------------------------------------------------------------------
def find_dispatch_by_struct_index(): """Attempts to locate the dispatch function based off it being loaded in a structure at offset 70h, based off of https://github.com/kbandla/ImmunityDebugger/blob/master/1.73/Libs/driverlib.py """ out = set() for function_ea in idautils.Functions(): flags = GetFunctionFlags(function_ea) # skip library functions if flags & FUNC_LIB: continue func = idaapi.get_func(function_ea) addr = func.startEA while addr < func.endEA: if GetMnem(addr) == 'mov': if '+70h' in GetOpnd(addr, 0) and idc.GetOpType(addr, 1) == 5: out.add(GetOpnd(addr, 1)) addr = idc.NextHead(addr) return out
def get_w32syscalls(): syscalls = set() # def get_syscall_start(): # for m, n in idautils.Names(): # if n == '_W32pServiceTable': # return m # ea = get_syscall_start() ea = idaapi.str2ea('_W32pServiceTable') f = idaapi.get_full_long(ea) functions = set(idautils.Functions()) while f in functions: fname = GetFunctionName(f) syscalls.add(fname) ea += 4 f = idaapi.get_full_long(ea) print 'win32k system call' , len(syscalls) return syscalls
def _rename_functions(self): '''Rename functions.''' print "IPL: Started to rename functions..." failed = 0 total = 0 for function in idautils.Functions(): total += 1 pdb_mangled_name = self.PDBLookup.lookup(function, True) if not pdb_mangled_name: failed += 1 print "IPL: Failed to find symbol for function: 0x{:08x}".format(function) continue _, mangled_function_name = pdb_mangled_name.split('!') # https://www.hex-rays.com/products/ida/support/idadoc/203.shtml idc.MakeNameEx(function, mangled_function_name, idc.SN_AUTO | idc.SN_NOCHECK) print "IPL: Total {} functions, {} failed to rename.".format(total, failed)
def output_symbols(out): """Dump symbols.""" try: from idaapi import get_func_name2 as get_func_name # Since get_func_name is deprecated (at least from IDA 6.9) except ImportError: from idaapi import get_func_name # Older versions of IDA don't have get_func_name2 # so we just use the older name get_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 # Fallback to non-propagated name for weird times that IDA gives # a 0 length name, or finds a longer import name for ea in idautils.Segments(): fs = idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)) for f in fs: out.write('("%s" 0x%x 0x%x)\n' % ( func_name_propagate_thunk(f), idc.GetFunctionAttr(f, idc.FUNCATTR_START), idc.GetFunctionAttr(f, idc.FUNCATTR_END)))
def prototypes(): types = set() for ea in idautils.Functions(): proto = idaapi.print_type(ea, True) if proto: types.append(proto + ';') return list(types)
def bulk_prefix(): """ Prefix the Functions window selection with a user defined string. """ # 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 # # loop through all the functions selected in the 'Functions window' and # apply the user defined prefix tag to each one. # for func_name in get_selected_funcs(): # ignore functions that already have the specified prefix applied if func_name.startswith(tag): continue # apply the user defined prefix to the function (rename it) new_name = '%s%s%s' % (str(tag), PREFIX_SEPARATOR, func_name) func_addr = idaapi.get_name_ea(idaapi.BADADDR, func_name) idaapi.set_name(func_addr, new_name, idaapi.SN_NOWARN) # refresh the IDA views refresh_views()
def clear_prefix(): """ Clear user defined prefixes from the selected functions in the Functions window. """ # # loop through all the functions selected in the 'Functions window' and # clear any user defined prefixes applied to them. # for func_name in get_selected_funcs(): # # locate the last (rfind) prefix separator in the function name as # we will want to keep everything that comes after it # i = func_name.rfind(PREFIX_SEPARATOR) # if there is no prefix (separator), there is nothing to trim if i == -1: continue # trim the prefix off the original function name and discard it new_name = func_name[i+1:] func_addr = idaapi.get_name_ea(idaapi.BADADDR, func_name) idaapi.set_name(func_addr, new_name, idaapi.SN_NOWARN) # refresh the IDA views refresh_views() #------------------------------------------------------------------------------ # IDA Util #------------------------------------------------------------------------------
def get_all_funcs(): """ Enumerate all function names defined in the IDB. """ return set(idaapi.get_func_name(ea) for ea in idautils.Functions())
def match_funcs(qt_funcs): """ Convert function names scraped from Qt to their *actual* representation. The function names we scrape from the Functions window Qt table actually use the underscore character ('_') as a substitute for a variety of different characters. For example, a function named foo%bar in the IDB will appears as foo_bar in the Functions window table. This function takes a list of names as they appear in the Functions window table such as the following: ['foo_bar'] And applies a best effort lookup to return a list of the 'true' function names as they are stored in the IDB. ['foo%bar'] TODO: rewrite this to be more efficient for larger idbs TODO: takes first matching function, may want to change it to make the requirements more strict """ res = set() ida_funcs = get_all_funcs() for f in qt_funcs: for f2 in ida_funcs: if len(f) == len(f2): i = 0 while i < len(f) and (f[i] == f2[i] or f[i] == '_'): i += 1 if i == len(f): res.add(f2) break return list(res)
def get_user_functions(): user_functions = [] for fva in idautils.Functions(): f_attr = idc.GetFunctionAttr(fva, idc.FUNCATTR_FLAGS) if not f_attr & idc.FUNC_LIB and not f_attr & idc.FUNC_THUNK: user_functions.append(fva) return user_functions
def get_functions(): ''' enumerate the functions in the currently loaded module. Yields: int: address of the function. ''' startea = idc.BeginEA() for fva in idautils.Functions(idc.SegStart(startea), idc.SegEnd(startea)): yield fva
def functions_iter(): functions = set() exports = get_export_list() for func_ea in idautils.Functions(): if func_ea in functions: continue # functions with chunks appear once for each of them.. functions.add(func_ea) code, blocks = get_code_and_blocks(func_ea) crefs_to = get_func_code_refs_to(func_ea) crefs_from = get_func_code_refs_from(func_ea, code.iterkeys()) f = func.Function(func_ea, code, blocks, crefs_to, crefs_from) f.ftype = idc.GetType(func_ea) f.name = idc.GetFunctionName(func_ea) if func_ea in exports: f.exported = True yield f typed_imports = get_typed_imports() for imp_ea, ftype in typed_imports: crefs_to = get_func_code_refs_to(imp_ea) f = func.Function(imp_ea, None, None, crefs_to, None) f.ftype = ftype f.level = -1 # special level for imported functions yield f
def _get_blocks_codes_per_func_iter(): """ Iterative function to generate all blocks and opcodes :return: N/A """ all_blocks = {} all_codes = {} all_opcodes = [] for func in idautils.Functions(): # blocks_in_func contains # <idaapi.BasicBlock object at 0x0545F3F0>, ... blocks_in_func = idaapi.FlowChart(idaapi.get_func(func)) blocks = [] for block in blocks_in_func: # IDA BUG! block.startEA == block.endEA?? # Should be in the range "block.startEA <= block < block.endEA" if block.startEA != block.endEA: blocks.append((block.startEA, block.endEA)) for head in idautils.Heads(block.startEA, block.endEA): ibytes = idc.GetManyBytes(head, idc.ItemEnd(head) - head) spd = idc.GetSpd(head) all_codes[head] = insn.Instruction(head, ibytes, spd) # IDA BUG! all_codes[head].bytes == 0?? # The size of the code should be positive if all_codes[head].bytes != 0: all_opcodes.append((all_codes[head].addr, all_codes[head].addr + len(all_codes[head].bytes))) all_blocks[func] = blocks yield (all_blocks, all_opcodes)
def sample_source(): global full_hash full_hash = "" c = 0 for addr in idautils.Functions(idc.MinEA(),idc.MaxEA()): fname = idc.GetFunctionName(addr) full_hash += normalize_fname(fname)+":"+calc_hash(addr)+":"+shexst(addr)+"|" c = c+1 if c > 1000: print "Too many subs. Plz run:" print "SRC SAMPLE : open('lame_ipc.txt','wb').write(full_hash)" print "DST SAMPLE : src_data = open('lame_ipc.txt','rb').read(full_hash)" else: print 'src_data = "' + full_hash + '"' return
def sample_dest(): global src_data if src_data is None: print "run the src_data = ... first" return src_hashes = {} for i in src_data.split("|"): z = i.split(":") if len(z) < 2: continue if src_hashes.has_key(z[1]): src_hashes[z[1]] = "baadf00d" else: src_hashes[z[1]] = z[0] dst_hashes = {} for addr in idautils.Functions(idc.MinEA(),idc.MaxEA()): fname = idc.GetFunctionName(addr) z = calc_hash(addr) if dst_hashes.has_key(z): dst_hashes[z] = "baadf00d" else: dst_hashes[z] = addr c = 0 for tmp in dst_hashes: if dst_hashes[tmp] == "baadf00d": continue if src_hashes.has_key(tmp): if src_hashes[tmp] != "baadf00d": idc.MakeNameEx(dst_hashes[tmp],"SHARED_"+src_hashes[tmp], SN_NOWARN) c = c+1 print "%d subs have been renamed" % (c) return
def get_functions(): return (IdaLocation(f) for f in idautils.Functions())
def get_list_of_functions(self): '''Get all functions list.''' seg_ea = idc.BeginEA() functions_list = {} for func_ea in idautils.Functions(idc.SegStart(seg_ea), idc.SegEnd(seg_ea)): function_name = self.maybe_demangle(idc.GetFunctionName(func_ea)) functions_list[function_name] = func_ea return functions_list
def __init__(self): super(FunctionsPlus, self).__init__() if idc.GetLongPrm(idc.INF_PROCNAME).lower() != 'metapc': print "Functions+ warning: not tested in this configuration" self.cols = Cols()
def Show(self): '''Creates the form is not created or focuses it if it was.''' return PluginForm.Show(self, "Functions+", options=PluginForm.FORM_PERSIST)
def update_mapping(self): pass self.fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in idautils.Functions()} self.seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()}
def process_program(self): funs = list(idautils.Functions()) nb = len(funs) for i, fun in zip(xrange(nb), funs): self.process_routine(fun, rtn_i=i+1, total_rtn=nb) if self.STOP: return
def set_start_stop(self, ftype): assert_ida_available() import idc import idaapi import idautils fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in idautils.Functions()} start = idc.BeginEA() stop = 0 if ftype == PE: start, stop = fun_mapping["start"] else: if not idc.isCode(idc.GetFlags(start)): if idc.MakeCode(start) == 0: print "Fail to decode instr !" idaapi.autoWait() if idc.GetFunctionName(start) == "": if idc.MakeFunction(start) == 0: print "Fail to create function !" idaapi.autoWait() fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in idautils.Functions()} if "main" in fun_mapping: start, stop = fun_mapping["main"] elif "start" in fun_mapping: if "__libc_start_main" in fun_mapping: instrs = list(idautils.FuncItems(fun_mapping["start"][0])) instrs.reverse() for inst in instrs: arg1 = idc.GetOperandValue(inst, 0) if idc.GetMnem(inst) == "push": start, stop = arg1, fun_mapping["start"][1] break else: start, stop = fun_mapping["start"] self.config.start, self.config.stop = start, stop
def find_dispatch_by_cfg(): """ Finds the functions in the binary which are not directly called anywhere and counts how many other functions they call, returing all functions which call > 0 other functions but are not called themselves. As a dispatch function is not normally directly called but will normally many other functions this is a fairly good way to guess which function it is. """ out = [] called = set() caller = dict() # Loop through all the functions in the binary for function_ea in idautils.Functions(): flags = GetFunctionFlags(function_ea) # skip library functions if flags & FUNC_LIB: continue f_name = GetFunctionName(function_ea) # For each of the incoming references for ref_ea in CodeRefsTo(function_ea, 0): called.add(f_name) # Get the name of the referring function caller_name = GetFunctionName(ref_ea) if caller_name not in caller.keys(): caller[caller_name] = 1 else: caller[caller_name] += 1 while True: if len(caller.keys()) == 0: break potential = max(caller, key=caller.get) if potential not in called: out.append(potential) del caller[potential] return out
def get_ntsyscalls(): syscalls = set() ea = idaapi.str2ea('_KiServiceTable') f = idaapi.get_full_long(ea) functions = set(idautils.Functions()) while f in functions: fname = GetFunctionName(f) syscalls.add(fname) ea += 4 f = idaapi.get_full_long(ea) print 'ntos system call' , len(syscalls) return syscalls
def get_all_funcs(): return set(idaapi.get_func_name(ea) for ea in idautils.Functions())
def get_selected_funcs(): tform = idaapi.find_tform("Functions window") if not tform: idc.Warning("Unable to find 'Functions window'") return widget = idaapi.PluginForm.FormToPySideWidget(tform) table = widget.findChild(QtWidgets.QTableView) selected_funcs = [str(s.data()) for s in table.selectionModel().selectedRows()] return match_funcs(selected_funcs)
def get_selected_funcs(): """ Return the list of function names selected in the Functions window. """ # NOTE / COMPAT: if using_ida7api: import sip twidget = idaapi.find_widget("Functions window") widget = sip.wrapinstance(long(twidget), QtWidgets.QWidget) # NOTE: LOL else: tform = idaapi.find_tform("Functions window") if using_pyqt5: widget = idaapi.PluginForm.FormToPyQtWidget(tform) else: widget = idaapi.PluginForm.FormToPySideWidget(tform) # TODO: test this if not widget: idaapi.warning("Unable to find 'Functions window'") return # # locate the table widget within the Functions window that actually holds # all the visible function metadata # table = widget.findChild(QtWidgets.QTableView) # # scrape the selected function names from the Functions window table # selected_funcs = [str(s.data()) for s in table.selectionModel().selectedRows()] # # re-map the scraped names as they appear in the function table, to their true # names as they are saved in the IDB. See the match_funcs(...) function # comment for more details # return match_funcs(selected_funcs)
def metadata_progress(completed, total): """ Handler for metadata collection callback, updates progress dialog. """ idaapi.replace_wait_box("Collected metadata for %u/%u Functions" % (completed, total)) #-------------------------------------------------------------------------- # Event Hooks #--------------------------------------------------------------------------