def listUpdatedSymbols(elfPath, symTable): """ Searches through the symtable in the elfPath, and computes a list of name_eas, and their new names :param elfPath: path of the elf file to process :param symTable: use instead of recalculating from elf :return: list of (name_ea, new_name) """ output = [] if not symTable: symTable = getSymTable(elfPath) # compute all names in RAM and ROM names = [] for seg_ea in idautils.Segments(): # skip BIOS if seg_ea == 0: continue for head in idautils.Heads(seg_ea, idc_bc695.SegEnd(seg_ea)): if idc.Name(head): names.append((head, idc.Name(head))) for ea, name in names: eaInSymTable = ea in symTable if eaInSymTable or ea + 1 in symTable: # increment by 1 for thumb function symbols if ea + 1 in symTable and idc.isCode(idc.GetFlags(ea)): name_ea = ea + 1 else: name_ea = ea # check if the name exists in the symTable nameInSymTable = False globalSymbol = '' for symName, isLocal in symTable[name_ea]: if name == symName: nameInSymTable = True if not isLocal: globalSymbol = symName if nameInSymTable: continue # At this point, a name must have changed. if globalSymbol: output.append((ea, globalSymbol)) else: output.append((ea, symTable[name_ea][0][0])) return output
def testNoUnknowns(self): for seg_ea in idautils.Segments(): prevHead = seg_ea-1 for head in idautils.Heads(seg_ea, idc_bc695.SegEnd(seg_ea)): # confirm not unknown f = idc.GetFlags(head) if idc.isUnknown(f): Test.fail("Detected Unknown @ %08X" % head) # make sure that the next head is always 1 byte before the previous Test.assertEquals(head, prevHead+1, "Non-continuous heads: %08X -> %08X" % (prevHead, head)) # remember curr state for next iteration prevHead = head
def findMostUsedFunctions(count, notModified=False, disp=True): # type: (int, bool, bool) -> list[int] """ Returns the functions with the highest count of xrefsTo. if notModified, only those that are in the format *_xxxxxxx are returned. if disp, the output is formatted and printed as well :param count: the number of the most used functions to find :param notModified: only functions with names ending in func_ea, or all functions :param disp: print the output :return: list of function linear addresses to the most used functions """ funcXrefs = [] if count <= 0: count = 1 for i in range(count): funcXrefs.append((0, 0)) for seg_ea in idautils.Segments(): for func_ea in idautils.Functions(seg_ea, idc_bc695.SegEnd(seg_ea)): if notModified: name = Function.Function(func_ea).getName() if not ('_' in name and name[name.rindex('_'):] == ('_%X' % func_ea)): continue xrefs = Function.Function(func_ea).getXRefsTo() numXrefs = len(xrefs[0]) + len(xrefs[1]) # add if more than least in the list and sort if numXrefs > funcXrefs[0][1]: funcXrefs[0] = (func_ea, numXrefs) funcXrefs = sorted(funcXrefs, key=lambda tup: tup[1]) # reverse to display most common first funcXrefs = sorted(funcXrefs, key=lambda tup: tup[1], reverse=True) if disp: for func_ea, xrefCount in funcXrefs: print('%07x <%s::%s>: %d' % (func_ea, mtcomm.ea2gf(func_ea), Function.Function(func_ea).getName(), xrefCount)) output = [] for func_ea, xrefCount in funcXrefs: output.append(func_ea) return output
def getModuleFunctions(self): """ This traverses all segments, and all defined modules to retrieve all functions with that module name. :return: a list of Functions that are in this module, saved in the database. """ output = [] for seg_ea in idautils.Segments(): for func_ea in idautils.Functions(idc_bc695.SegStart(seg_ea), idc_bc695.SegEnd(seg_ea)): func = Function.Function(func_ea) # if the function starts with '<moduleName>'... funcName = func.getName() inModel = len(funcName) >= len( self.name) + 1 and funcName[0:len(self.name) + 1] == self.name + '_' if inModel: output.append(func) return output
def _listUpdatedSymbols(elfPath): """ Searches through the symtable in the elfPath, and computes a list of name_eas, and their new names :param elfPath: path of the elf file to process :return: list of (name_ea, [(new_name, isLocal)]) """ # TODO [DESIGN]: function exists in Srch too. Remove redundancy output = [] symTable = _getSymTable(elfPath) # compute all names in RAM and ROM names = [] for seg_ea in idautils.Segments(): # skip BIOS if seg_ea == 0: continue for head in idautils.Heads(seg_ea, idc_bc695.SegEnd(seg_ea)): if idc.Name(head): names.append((head, idc.Name(head))) for ea, name in names: if ea in symTable or ea+1 in symTable: # increment by 1 for thumb function symbols if ea+1 in symTable and idc.isCode(idc.GetFlags(ea)): name_ea = ea+1 else: name_ea = ea # check if the name exists in the symTable nameInSymTable = False for symName, isLocal in symTable[name_ea]: if name == symName: nameInSymTable = True # a name change was detected if not nameInSymTable: output.append((ea, symTable[name_ea])) return output
def scan_for_known_functions(self): """ This will scan the binary using ALL defined functions in the ROM SEGMENT in the IDA Database agaisnt the binary. Dictionary for each match: Key Description Name The name of the function in the IDA Database ROM_Addr The ROM Address. This is absolute to the architecture in question, and the seg addr is added to it Bin_Addr The Address in the binary file. This is relative to the binary file. :return: A list of Dictionaries according to the definition above, or an empty list if no matches. """ output = [] for func_ea in idautils.Functions( idc_bc695.SegStart(self.ROM_start_addr), idc_bc695.SegEnd(self.ROM_start_addr)): binEA = self.find_function(func_ea) if binEA: matchDict = {} matchDict['Name'] = idc_bc695.GetFunctionName(func_ea) matchDict['ROM_Addr'] = func_ea matchDict['Bin_Addr'] = binEA output.append(matchDict) return output