def DumpExports(): invalidFormatNames = [] pe = peutils_t() baseaddr = pe.imagebase print "Listing module {} exports with base address {:x}".format(GetInputFile(),baseaddr) exportsList = list(idautils.Entries()) print "Found %d exports(s)..." % len(exportsList) inputFileBase = os.path.splitext(GetInputFile())[0] outfileName = GetInputFile() + ".exports.h" print "Dumping ordinals to " + outfileName outfile = file(outfileName,"w") print >> outfile, "// List of {} exports (base address {:x})\n\n".format(GetInputFile(),baseaddr) for exp_index, exp_ordinal, exp_ea, exp_name in list(idautils.Entries()): if exp_name == "DllEntryPoint": continue print >> outfile, "/// @ordinal {}".format(exp_ordinal) name = GetTrueNameEx(BADADDR,exp_ea); expectedNameStart = inputFileBase + "_" + str(exp_ordinal) if not name.startswith(expectedNameStart): normalizedName = tryNormalizeName(name,expectedNameStart) if normalizedName: print "replacing " + name + " by " + normalizedName MakeName(exp_ea, normalizedName) name = normalizedName else: invalidFormatNames.append(name + "(expected " + expectedNameStart + ")") if name != expectedNameStart: name = RemovePrefix(name, expectedNameStart) print >> outfile, "/// @name {}".format(name) print >> outfile, "/// @address {:x}".format(exp_ea) tinfo = GetTinfo(exp_ea) # Note: One way to force types not to be guessed could be to call MakeName ? if tinfo is not None: (type, fields) = tinfo print >> outfile,idaapi.idc_print_type(type, fields, name, 0) +";" else: guessedType = GuessType(exp_ea) if guessedType is not None: print >> outfile,"/// @guessedtype {}".format(guessedType) else: print >> outfile,"/// Failed to extract type" print >> outfile,"" print "All done..." if invalidFormatNames: print "Badly formated names:" for name in invalidFormatNames: print name
def isExport(self): entries = idautils.Entries() for entry in entries: if self.addr in entry: return True return False
def find_exported_eas(): """Find the address of all exported functions. Exported functions are entrypoints into this program that external code can execute.""" exported_eas = set() for index, ordinal, ea, name in idautils.Entries(): # Not sure how this happens, but IDA seemed to treat # `obstack_alloc_failed_handler` in `call cs:[obstack_alloc_failed_handler]` # as an entrypoint. num_data_refs = len(tuple(idautils.DataRefsTo(ea))) num_code_refs = len(tuple(idautils.CodeRefsTo(ea, True))) num_code_refs += len(tuple(idautils.CodeRefsTo(ea, True))) if num_data_refs and not num_code_refs: log.warning( "Ignoring entrypoint {:08x}, it's only referenced by data". format(ea)) continue if not has_segment_type(ea, idc.SEG_CODE): log.warning( "Ignoring entrypoint {:08x}, it is not in a code segment". format(ea)) continue if not idc.hasName(ea): old_name = name if name.startswith("."): name = idc.GetCommentEx(ea, 0) log.info("Renaming `{}` at {:08x} to `{}`".format( old_name, ea, name)) idc.MakeName(ea, name) return exported_eas
def main(): ea = idaapi.get_screen_ea() # export entry = tuple(index, ordinal, address, name) exports = {export[2]: export for export in idautils.Entries()} # list of tuple(xref_address, export_name, xref_offset) exported_xrefs = [] xrefs = [x.frm for x in idautils.XrefsTo(ea)] for xref in xrefs: func = idaapi.get_func(xref) if func and func.startEA in exports: exported_xrefs.append( (xref, exports[func.startEA][3], xref - func.startEA)) if exported_xrefs: delim = "=" * 80 print delim print "Dumping exported xrefs for: %s %s" % (idaapi.get_name( ea, ea), idahex(ea)) print delim for exported_xref in exported_xrefs: print "%s %s + 0x%X" % (idahex( exported_xref[0]), exported_xref[1], exported_xref[2]) else: print "%s %shas no exported xrefs." % (idahex(ea), idaapi.get_name(ea, ea) or "")
def generateDefFile(defname, eps): deffile = open(defname, 'wb') deffile.write("EXPORTS\n") entrypoints = idautils.Entries() for ep_tuple in entrypoints: (index, ordinal, ea, name) = ep_tuple if name not in eps: continue fwdname = isFwdExport(name, ea) if fwdname is not None: deffile.write("{0}={1}\n".format(name, fwdname)) else: args, conv, ret = getExportType(name, ea) if conv == cfg_pb2.ExternalFunction.CallerCleanup: decor_name = "_export_{0}".format(name) elif conv == cfg_pb2.ExternalFunction.CalleeCleanup: decor_name = "_export_{0}@{1}".format(name, args*4) elif conv == cfg_pb2.ExternalFunction.FastCall: decor_name = "@export_{0}@{1}".format(name, args*4) else: raise Exception("Unknown calling convention: " + str(conv)) deffile.write("{0}={1}\n".format(name, decor_name)) deffile.close()
def generateExportStub(cname, eps): cfile = open(cname, 'wb') entrypoints = idautils.Entries() for ep_tuple in entrypoints: (index, ordinal, ea, name) = ep_tuple if name not in eps: continue fwdname = isFwdExport(name, ea) if fwdname is not None: continue else: args, conv, ret = getExportType(name, ea) if conv == cfg_pb2.ExternalFunction.CallerCleanup: convstr = "__cdecl" elif conv == cfg_pb2.ExternalFunction.CalleeCleanup: convstr = "__stdcall" elif conv == cfg_pb2.ExternalFunction.FastCall: convstr = "__fastcall" else: raise Exception("Unknown calling convention") declargs = makeArgStr(name, declaration=True) callargs = makeArgStr(name, declaration=False) cfile.write("extern int {2} driver_{0}({1});\n".format(name, declargs, convstr)) cfile.write("int {3} export_{0}({1}) {{ return driver_{0}({2}); }} \n".format( name, declargs, callargs, convstr)) cfile.write("\n") cfile.close()
def exportsInner(self): """Create a collection / generator of all of the exported symbols (string names) in the program (will be called only once). Return Value: collection of all of the exported symbols in the program """ return map(lambda x: self._logic.funcNameInner(x[-1]), idautils.Entries())
def identify_program_entrypoints(func_eas): """Identify all entrypoints into the program. This is pretty much any externally visible function.""" DEBUG("Looking for entrypoints") DEBUG_PUSH() exclude = set([ "_start", "__libc_csu_fini", "__libc_csu_init", "main", "__data_start", "__dso_handle", "_IO_stdin_used" ]) exported_funcs = set() exported_vars = set() for index, ordinal, ea, name in idautils.Entries(): assert ea != idc.BADADDR if not is_external_segment(ea): sym_name = get_symbol_name(ea, allow_dummy=False) if not sym_name: DEBUG("WEIRD: Forcing entrypoint {:x} name to be {}".format( ea, name)) set_symbol_name(ea, name) if is_code(ea): func_eas.add(ea) if name not in exclude: exported_funcs.add(ea) else: if name not in exclude and not is_runtime_external_data_reference( ea): exported_vars.add(ea) DEBUG_POP() return exported_funcs, exported_vars
def search(self): exports = set([info[3] for info in idautils.Entries()]) comexports = set([ 'DllUnregisterServer', 'DllEntryPoint', 'DllGetClassObject', 'DllCanUnloadNow', 'DllRegisterServer' ]) dllpath = ida_nalt.get_input_file_path().decode('utf-8') if not comexports.issubset(exports): print('{} is not COM! exports mismatching'.format(dllpath)) return try: tlb = pythoncom.LoadTypeLib(dllpath) except: print('{} is not COM! LoadTypeLib fail'.format(dllpath)) return classes = {} values = [] for i in range(tlb.GetTypeInfoCount()): if tlb.GetTypeInfoType(i) == pythoncom.TKIND_COCLASS: ctypeinfo = tlb.GetTypeInfo(i) clsid = str(ctypeinfo.GetTypeAttr().iid) for j in range(ctypeinfo.GetTypeAttr().cImplTypes): typeinfo = ctypeinfo.GetRefTypeInfo( ctypeinfo.GetRefTypeOfImplType(j)) attr = typeinfo.GetTypeAttr() name = tlb.GetDocumentation(i)[0] iid = str(attr.iid) vas = self.get_com_vas( dllpath.encode(locale.getdefaultlocale()[1]), clsid, iid, str(attr.cFuncs)) if isinstance(vas, str): print(vas) else: for findex in range(attr.cFuncs): fundesc = typeinfo.GetFuncDesc(findex) funnames = typeinfo.GetNames(fundesc.memid) funname_ext = "{}_{}_{}".format( name, funnames[0], invokekinds[fundesc.invkind]) typ, flags, default = fundesc.rettype desc = '' if fundesc.invkind == pythoncom.INVOKE_FUNC: desc += vartypes.get(typ, 'UNKNOWN') + ' (' argi = 1 for argdesc in fundesc.args: typ, flags, default = argdesc desc += '{} {}'.format( vartypes.get(typ, 'UNKNOWN'), funnames[argi]) if default is not None: desc += '={}'.format(default) desc += ' ,' argi += 1 desc += ')' idaapi.set_name(vas[findex], funname_ext) values.append( [vas[findex], funname_ext, name, desc]) ComHelperResultChooser("Comhelper", values).show()
def get_export_list(): """Returns a set of the exported function addresses""" exports = set() for i, ordn, ea, name in idautils.Entries(): exports.add(ea) return exports
def getAllExports() : entrypoints = idautils.Entries() to_recover = set() # recover every entry point for ep_tuple in entrypoints: (index, ordinal, ea, name) = ep_tuple to_recover.add(name) return to_recover
def setBpOnEntries(): #List of tuples (index, ordinal, ea, name) entries = list(idautils.Entries()) if (len(entries) == 0): print "No entry points!" else: for entry in entries: ea = entry[2] idc.AddBpt(ea) print "Bp on %s(0x%08x) set " % (entry[3], ea)
def obtain_export_by_name(export_name): """ Iterate the entry points to identify the location of an export by name :param export_name: Target export :return: Location of target export or idc.BADADDR """ for (i, ordinal, ea, name) in idautils.Entries(): if name == export_name: return ea return idc.BADADDR
def get_exports(): ''' enumerate the exports of the currently loaded module. Yields: Tuple[int, int, str]: - address of exported function - export ordinal - name of exported function ''' for index, ordinal, ea, name in idautils.Entries(): yield ea, ordinal, name
def entries_iter(cls): """ Get an generator on the functions which are entry points of the binary. This should be faster than :meth:`~BipFunction.entries` . :return: A generator on :class:`BipFunction` which are entry points of the binary currently analyzed. """ for elt in idautils.Entries(): try: yield cls(elt[2]) except ValueError: # case where we are not in a function, but data continue # we just ignore that case
def __init__(self): self.exports_by_addr = collections.defaultdict(list) self.exports_by_name = {} self.export_by_ordinal = {} for index, ordinal, addr, name in idautils.Entries(): x = IDAExport(addr, ordinal, name) self.exports_by_addr[addr].append(x) self.exports_by_name[name] = x self.export_by_ordinal[ordinal] = x #Entry point : doesnt works for ELF.. # TODO: find real entry point method if addr == ordinal: self.entry_point = x # disable default dict at this point to prevent error self.exports_by_addr.default_factory = None
def run(self): """Run.""" exports = list(idautils.Entries()) new_exports = [] for exp_i, exp_ord, exp_ea, exp_name in exports: orig_exp_name = exp_name if not exp_name: exp_name = idc.GetFunctionName(exp_ea) if not exp_name: exp_name = '(error: unable to resolve)' if exp_ea == exp_ord: exp_ord = '[main entry]' new_exports.append([self.demangle(exp_name), "%08X" % exp_ea, "%s" % exp_ord, orig_exp_name]) ExportChooser("Exports+", new_exports).Show() return
def getAllExports() : entrypoints = idautils.Entries() to_recover = set() # recover every entry point for ep_tuple in entrypoints: (index, ordinal, ea, name) = ep_tuple to_recover.add(name) ### add it by wmh on 2015.3.30 #funcs = Functions(); #for f in funcs: # ea = idc.LocByName(Name(f).strip()) # if ea == idc.BADADDR: # continue # to_recover.add(Name(f).strip()); ### end add it by wmh return to_recover
def Auto_Name_Function_Wrapper(): ea = idc.ScreenEA() segStartEA = idc.SegStart(ea) segEndEA = idc.SegEnd(ea) print '=' * 100 print 'aan_Auto_Name_Function Starting' excludeList = [entry[3] for entry in idautils.Entries()] excludeList.extend([ 'WinMain', 'WinMain@12', 'WinMain@16', 'wWinMain', 'wWinMain@12', 'wWinMain@16', '_wWinMain@12', '_wWinMain@16', 'main', '_main', 'StartAddress' ]) funcList = [] for funcEa in idautils.Functions(segStartEA, segEndEA): flags = idc.GetFunctionFlags(funcEa) if ((flags & idc.FUNC_LIB) != idc.FUNC_LIB) and ( (flags & idc.FUNC_THUNK) != idc.FUNC_THUNK) and ( idc.GetFunctionName(funcEa) not in excludeList): funcList.append(funcEa) parentNodes = set() for funcEa in funcList: for refEA in idautils.CodeRefsTo(funcEa, 0): if idc.GetFunctionAttr(refEA, idc.FUNCATTR_START) != funcEa: parentNodes.add(idc.GetFunctionAttr(refEA, idc.FUNCATTR_START)) leafNodes = [] for funcEa in funcList: if funcEa not in parentNodes: leafNodes.append(funcEa) threadRootsList = Get_Thread_Roots() threadRootsList = [ threadEa for threadEa in threadRootsList[:] if idc.GetFunctionName(threadEa) not in excludeList ] for funcEa in threadRootsList: if idc.GetFunctionFlags(funcEa) == -1: pass else: Rename(funcEa, CUSTOM_MANUAL_FUNC_PREFIX + 'TS') while True: funcRenamedCount = 0 nodesTraversed = set() curNodes = leafNodes[:] while True: for funcEa in curNodes: if idc.GetFunctionName(funcEa).startsWith( CUSTOM_MANUAL_FUNC_PREFIX): continue oldFuncName = idc.GetFunctionName(funcEa) newFuncNameProposed = Build_New_Func_Name(funcEa) Rename(funcEa, newFuncNameProposed) newFuncNameActual = idc.GetFunctionName(funcEa) if oldFuncName != newFuncNameActual: funcRenamedCount += 1 nodesTraversed.update(curNodes) parentNodes = set() for funcEa in curNodes: for refEA in idautils.CodeRefsTo(funcEa, 0): flags = idc.GetFunctionFlags(refEA) if ((flags & idc.FUNC_LIB) != idc.FUNC_LIB) and ( idc.GetFunctionName(refEA) not in excludeList): if idc.GetFunctionAttr( refEA, idc.FUNCATTR_START) not in nodesTraversed: parentNodes.add( idc.GetFunctionAttr(refEA, idc.FUNCATTR_START)) if len(parentNodes) == 0: break curNodes = parentNodes.copy() if funcRenamedCount == 0: break print 'aan_Auto_Name_Function completed' print '=' * 100 Refresh()
def recover_rtti(): for index, ordinal, ea, name in idautils.Entries(): if get_stripped_name(name) in typeinfo_names: get_typeinfo_refs(name, ea)
def save_export_renames(dest): exports = {} for i, ord, addr, name in idautils.Entries(): exports[name] = idc.GetFunctionName(addr) with open(path.expanduser(dest), 'w') as f: json.dump(exports, f)
def recoverCfg(to_recover, outf, exports_are_apis=False): M = cfg_pb2.Module() M.module_name = idc.GetInputFile() DEBUG("PROCESSING: {0}\n".format(M.module_name)) our_entries = [] entrypoints = idautils.Entries() exports = {} for index,ordinal,exp_ea, exp_name in entrypoints: exports[exp_name] = exp_ea new_eas = set() add_result_from_IDA(new_eas) processDataSegments(M, new_eas) for name in to_recover: if name in exports: ea = exports[name] else: ea = idc.LocByName(name) if ea == idc.BADADDR: raise Exception("Could not locate entry symbol: {0}".format(name)) fwdname = isFwdExport(name, ea) if fwdname is not None: sys.stdout.write("Skipping fwd export {0} : {1}\n".format(name, fwdname)) continue if not isInternalCode(ea): sys.stdout.write("Export {0} does not point to code; skipping\n".format(name)) continue our_entries.append( (name, ea) ) recovered_fns = 0 # process main entry points for fname, fea in our_entries: sys.stdout.write("Recovering: {0}\n".format(fname)) F = entryPointHandler(M, fea, fname, exports_are_apis) RECOVERED_EAS.add(fea) recoverFunction(M, F, fea, new_eas) recovered_fns += 1 # process subfunctions new_eas.difference_update(RECOVERED_EAS) while len(new_eas) > 0: cur_ea = new_eas.pop() if cur_ea in RECOVERED_EAS: continue if not isInternalCode(cur_ea): raise Exception("Function EA not code: {0:x}".format(cur_ea)) F = addFunction(M, cur_ea) sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea))) RECOVERED_EAS.add(cur_ea) recoverFunction(M, F, cur_ea, new_eas) recovered_fns += 1 if recovered_fns == 0: sys.stderr.write("COULD NOT RECOVER ANY FUNCTIONS\n") return probably_fn_pointers = set() map(lambda (s,e): scanDataForCodePointers(s,e,probably_fn_pointers), DATA_SEGMENTS); # add functions found by scanning data section while len(probably_fn_pointers) > 0: cur_ea = probably_fn_pointers.pop() if not isInternalCode(cur_ea): raise Exception("Function EA not code: {0:x}".format(cur_ea)) F = addFunction(M, cur_ea) sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea))) RECOVERED_EAS.add(cur_ea) recoverFunction(M, F, cur_ea, probably_fn_pointers) recovered_fns += 1 # if FUNCTIONS_NEED_TRAMPOLINE is true it means # there is some indirect calls and we need to set # trampolines for those functions we think may be # targets # XXX: for the moment every function is a target if FUNCTIONS_NEED_TRAMPOLINE: for f in M.internal_funcs: f.need_trampoline = True mypath = path.dirname(__file__) processExternals(M) outf.write(M.SerializeToString()) outf.close() sys.stdout.write("Recovered {0} functions.\n".format(recovered_fns)) sys.stdout.write("Saving to: {0}\n".format(outf.name))
if info.is_be(): data['info']['endian'] = "big" #get program_class data['info']['program_class'] = class_map[info.filetype] #get imports and dlls nimps = idaapi.get_import_module_qty() for i in xrange(0, nimps): dllname = idaapi.get_import_module_name(i) if dllname != None: data['libs'].append({"name": dllname}) idaapi.enum_import_names(i, imp_cb) #get exports for exp in list(idautils.Entries()): e = { 'name': exp[3], 'offset': exp[1], 'size': 0 #Hardcoded to 0 until we figure out what the 'size' info actually means } data['exports'].append(e) #iterate through functions for func in idautils.Functions(): #if func from library skip flags = idc.GetFunctionFlags(func) if flags & FUNC_LIB or flags & FUNC_THUNK or flags & FUNC_HIDDEN: continue
def idenLib(): global func_sigs global mainSigs # function sigs from the current binary func_bytes_addr = {} for addr, size in getFuncRanges(): f_bytes = getOpcodes(addr, size) func_bytes_addr[f_bytes] = addr # load sigs if not os.path.isdir(symEx_dir): print("[idenLib - FAILED] There is no {} directory".format(symEx_dir)) return if os.path.isfile(idenLibCache): func_sigs = pickle.load(open(idenLibCache, "rb")) if os.path.isfile(idenLibCacheMain): mainSigs = pickle.load(open(idenLibCacheMain, "rb")) else: idenLibProcessSignatures() # apply sigs counter = 0 mainDetected = False for sig_opcodes, addr in func_bytes_addr.items(): if func_sigs.has_key(sig_opcodes): func_name = func_sigs[sig_opcodes] current_name = ida_funcs.get_func_name(addr) if (current_name != func_name): digit = 1 while func_name in getNames(): func_name = func_name + str(digit) digit = digit + 1 ida_name.set_name(addr, func_name, ida_name.SN_NOCHECK) print("{}: {}".format(hex(addr), func_name)) counter = counter + 1 if mainSigs.has_key(sig_opcodes): # "main" sig callInstr = mainSigs[sig_opcodes][1] + addr if ida_ua.print_insn_mnem(callInstr) == "call": call_target = idc.get_operand_value(callInstr, 0) current_name = ida_funcs.get_func_name(call_target) func_name = mainSigs[sig_opcodes][0] if (current_name != func_name): ida_name.set_name(call_target, func_name, ida_name.SN_NOCHECK) print("{}: {}".format(hex(call_target), func_name)) counter = counter + 1 mainDetected = True if not mainDetected: for entry in idautils.Entries(): for sig_opcodes, name_funcRva_EntryRva in mainSigs.items(): callInstr = name_funcRva_EntryRva[2] + entry[2] # from EP if ida_ua.print_insn_mnem(callInstr) == "call": fromFunc = name_funcRva_EntryRva[1] func_start = callInstr - fromFunc func_opcodes = getOpcodes(func_start, MAX_FUNC_SIZE) if func_opcodes.startswith(sig_opcodes): call_target = idc.get_operand_value(callInstr, 0) current_name = ida_funcs.get_func_name(call_target) func_name = mainSigs[sig_opcodes][0] if (current_name != func_name): ida_name.set_name(call_target, func_name, ida_name.SN_NOCHECK) print("{}: {}".format(hex(call_target), func_name)) counter = counter + 1 mainDetected = True break print("[idenLib] Applied to {} function(s)".format(counter))
def is_driver(): exports = set(x[3] for x in idautils.Entries()) return 'DriverEntry' in exports
def idenLib(): global g_func_sigs global g_main_sigs new_sigs = False cached = False if os.path.isfile(idenLibCache): try: with open(idenLibCache, "rb") as f: g_func_sigs = pickle.load(f) if os.path.isfile(idenLibCacheMain): with open(idenLibCacheMain, "rb") as f: g_main_sigs = pickle.load(f) cached = True except Exception as e: # continue with new sigs after excption print("[idenLib] load cache files error: %s" % str(e)) if cached: ret = idaapi.ask_yn(idaapi.ASKBTN_YES, "Do you want to select another signatures than current cached ?") if ret == idaapi.ASKBTN_CANCEL: print("[idenLib] user cancelled") return new_sigs = ret == idaapi.ASKBTN_YES else: new_sigs = True idaapi.msg_clear() if new_sigs: if not idenLibProcessSignatures(): return idaapi.show_wait_box("Please wait scan and apply signatures...") # function sigs from the current binary func_bytes_addr = {} for addr, size in getFuncRanges(): f_bytes = getOpcodes(addr, size) func_bytes_addr[f_bytes] = addr # apply sigs counter = 0 mainDetected = False for sig_opcodes, addr in func_bytes_addr.items(): if g_func_sigs.has_key(sig_opcodes): set_func_library(addr) func_name = g_func_sigs[sig_opcodes][0] current_name = idc.get_func_name(addr) if current_name != func_name: idc.set_name(addr, func_name, idaapi.SN_FORCE) print("{}: {}".format(hex(addr).rstrip("L"), func_name)) counter = counter + 1 if g_main_sigs.has_key(sig_opcodes): # "main" sig callInstr = g_main_sigs[sig_opcodes][1] + addr if idaapi.print_insn_mnem(callInstr) == "call": call_target = idc.get_operand_value(callInstr, 0) set_func_library(call_target) func_name = g_main_sigs[sig_opcodes][0] current_name = idc.get_func_name(call_target) if current_name != func_name: idaapi.set_name(call_target, func_name, idaapi.SN_FORCE) print("{}: {}".format(hex(call_target).rstrip("L"), func_name)) counter = counter + 1 mainDetected = True if not mainDetected: for entry in idautils.Entries(): for sig_opcodes, name_funcRva_EntryRva in g_main_sigs.items(): callInstr = name_funcRva_EntryRva[2] + entry[2] # from EP if idaapi.print_insn_mnem(callInstr) == "call": fromFunc = name_funcRva_EntryRva[1] func_start = callInstr - fromFunc func_opcodes = getOpcodes(func_start, MAX_FUNC_SIZE) if func_opcodes.startswith(sig_opcodes): call_target = idc.get_operand_value(callInstr, 0) set_func_library(call_target) current_name = idc.get_func_name(call_target) func_name = g_main_sigs[sig_opcodes][0] if current_name != func_name: idaapi.set_name(call_target, func_name, idaapi.SN_FORCE) print("{}: {}".format(hex(call_target).rstrip("L"), func_name)) counter = counter + 1 mainDetected = True break idaapi.hide_wait_box() print("[idenLib] Applied to {} function(s)".format(counter))
def BuildExports(self): return list(idautils.Entries())
def activate(self, ctx): if self.menu_title == MenuAskEntryId: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") else: if self.outer_self.mixto.entry_id is None: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") if self.menu_title == MenuAllFunc: all_func = "" # Get count of all functions in the binary count = idaapi.get_func_qty() for i in range(count): fn = idaapi.getn_func(i) # Function should not have dummy name such as sub_* # and should not start with underscore (possible library functions) if not idaapi.has_dummy_name(get_flags_at( start_ea_of(fn))) and not idaapi.get_func_name( start_ea_of(fn)).startswith("_"): all_func += "{} @ 0x{:x}\n".format( idaapi.get_func_name(start_ea_of(fn)), start_ea_of(fn)) self.outer_self.mixto.AddCommit(all_func, self.outer_self.mixto.entry_id, "(IDA) All Functions") elif self.menu_title == MenuImports: global AllImports AllImports = "" # Get count of all import modules in the binary count = idaapi.get_import_module_qty() for i in range(count): module_name = idaapi.get_import_module_name(i) AllImports += "{}:\n".format(module_name) idaapi.enum_import_names(i, imports_cb) self.outer_self.mixto.AddCommit(AllImports, self.outer_self.mixto.entry_id, "(IDA) All Imports") elif self.menu_title == MenuDecFunc: addr_current = idc.get_screen_ea() addr_func = idaapi.get_func(addr_current) if not addr_func: idaapi.msg("Place cursor inside a function!") return False else: err = None out = str(idaapi.decompile(addr_func)) # print(out) self.outer_self.mixto.AddCommit( str(out), self.outer_self.mixto.entry_id, "(IDA) Function Decompilation {}".format( idc.GetFunctionName(addr_func.startEA)), ) elif self.menu_title == MenuExports: all_exports = "" for entry in idautils.Entries(): _, ord, ea, name = entry if not name: all_exports += "0x{:x}: ord#{}\n".format(ea, ord) else: all_exports += "0x{:x}: {} ord#{}\n".format( ea, name, ord) self.outer_self.mixto.AddCommit(all_exports, self.outer_self.mixto.entry_id, "(IDA) All Exports") elif self.menu_title == MenuAllComments: addr_current = idc.get_screen_ea() addr_func = idaapi.get_func(addr_current) uniq_comments = {} comments = [] for ea in range(addr_func.startEA, addr_func.endEA): comment = idaapi.get_cmt(ea, 0) if comment is not None: # hacky way to make sure only uniq comments are added if uniq_comments.get(comment) == 1: pass else: print(uniq_comments) comments.append("{offset} {value}".format( offset=hex(ea), value=comment)) print("here") uniq_comments[comment] = 1 if len(comments) > 0: out = "\n".join(comments) self.outer_self.mixto.AddCommit( str(out), self.outer_self.mixto.entry_id, "(IDA) Function Comments {}".format( idc.GetFunctionName(addr_func.startEA)), ) else: raise TypeError("No comments found") return True
def extract_file_export_names(): """extract function exports""" for (_, _, ea, name) in idautils.Entries(): yield Export(name), ea
def recoverCfg(to_recover, outf, exports_are_apis=False): M = CFG_pb2.Module() M.module_name = idc.GetInputFile() DEBUG("PROCESSING: {0}\n".format(M.module_name)) our_entries = [] entrypoints = idautils.Entries() exports = {} for index, ordinal, exp_ea, exp_name in entrypoints: exports[exp_name] = exp_ea new_eas = set() processDataSegments(M, new_eas) for name in to_recover: if name in exports: ea = exports[name] else: ea = idc.LocByName(name) if ea == idc.BADADDR: raise Exception( "Could not locate entry symbol: {0}".format(name)) fwdname = isFwdExport(name, ea) if fwdname is not None: sys.stdout.write("Skipping fwd export {0} : {1}\n".format( name, fwdname)) continue if not isInternalCode(ea): sys.stdout.write( "Export {0} does not point to code; skipping\n".format(name)) continue our_entries.append((name, ea)) recovered_fns = 0 # process main entry points for fname, fea in our_entries: sys.stdout.write("Recovering: {0}\n".format(fname)) F = entryPointHandler(M, fea, fname, exports_are_apis) RECOVERED_EAS.add(fea) recoverFunction(M, F, fea, new_eas) recovered_fns += 1 # process subfunctions new_eas.difference_update(RECOVERED_EAS) while len(new_eas) > 0: cur_ea = new_eas.pop() if not isInternalCode(cur_ea): raise Exception("Function EA not code: {0:x}".format(cur_ea)) F = addFunction(M, cur_ea) sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea))) RECOVERED_EAS.add(cur_ea) recoverFunction(M, F, cur_ea, new_eas) recovered_fns += 1 if recovered_fns == 0: sys.stderr.write("COULD NOT RECOVER ANY FUNCTIONS\n") return mypath = path.dirname(__file__) processExternals(M) outf.write(M.SerializeToString()) outf.close() sys.stdout.write("Recovered {0} functions.\n".format(recovered_fns)) sys.stdout.write("Saving to: {0}\n".format(outf.name))