def analyse_subroutines(): """Goes through all the subroutines that IDA's initial auto analysis discovers.""" log.info("Analysing subroutines") exported_eas = find_exported_eas() log.info("IDA identified {} exported functions".format(len(exported_eas))) subs = set() sub_eas = set() # Work list. sub_eas.update(exported_eas) # Get all subroutines that IDA recognised. for seg_ea in idautils.Segments(): min_ea, max_ea = idc.SegStart(seg_ea), idc.SegEnd(seg_ea) sub_eas.update(idautils.Functions(min_ea, max_ea)) log.info("IDA identified {} functions".format(len(sub_eas))) bad_sub_eas = set() for sub_ea in sub_eas: if has_segment_type(sub_ea, idc.SEG_CODE): sub = program.get_subroutine(sub_ea) # Mark `ea` as a subroutine. # Iteratively analyse the blocks in subroutines. This may discover new # subroutines because our block analysis can be more aggressive than what # IDA finds. while len(sub_eas): sub_ea = sub_eas.pop() if not has_segment_type(sub_ea, idc.SEG_CODE): log.warning( "Not analysing subroutine at non-code address {:08x}".format( sub_ea)) continue sub = program.get_subroutine(sub_ea) if sub in subs: log.debug("Skipping {:08x}; already analysed.".format(sub_ea)) continue subs.add(sub) if idc.hasName(sub_ea): sub.name = idc.GetFunctionName(sub_ea) # Mark this subroutine as exported. if sub_ea in exported_eas: sub.visibility = program.Subroutine.VISIBILITY_EXPORTED analyse_subroutine(sub) sub_eas.update(get_called_subroutines(sub)) return subs
def analyse_subroutines(): """Goes through all the subroutines that IDA's initial auto analysis discovers.""" log.info("Analysing subroutines") exported_eas = find_exported_eas() log.info("IDA identified {} exported functions".format(len(exported_eas))) subs = set() sub_eas = set() # Work list. sub_eas.update(exported_eas) # Get all subroutines that IDA recognised. for seg_ea in idautils.Segments(): min_ea, max_ea = idc.SegStart(seg_ea), idc.SegEnd(seg_ea) sub_eas.update(idautils.Functions(min_ea, max_ea)) log.info("IDA identified {} functions".format(len(sub_eas))) bad_sub_eas = set() for sub_ea in sub_eas: if is_code(sub_ea): sub = program.get_subroutine(sub_ea) # Mark `ea` as a subroutine. # Iteratively analyse the blocks in subroutines. This may discover new # subroutines because our block analysis can be more aggressive than what # IDA finds. while len(sub_eas): sub_ea = sub_eas.pop() if not is_code(sub_ea): log.warning( "Not analysing subroutine at non-code address {:08x}".format(sub_ea)) continue sub = program.get_subroutine(sub_ea) if sub in subs: log.debug("Skipping {:08x}; already analysed.".format(sub_ea)) continue subs.add(sub) if idc.hasName(sub_ea): sub.name = idc.GetFunctionName(sub_ea) # Mark this subroutine as exported. if sub_ea in exported_eas: sub.visibility = program.Subroutine.VISIBILITY_EXPORTED analyse_subroutine(sub) sub_eas.update(get_called_subroutines(sub)) return subs
def find_imported_subroutines(): """Find the address of all imported functions.""" # Collect addresses of imported code. imported_eas = set() num_imports = idaapi.get_import_module_qty() for i in xrange(num_imports): idaapi.enum_import_names(i, lambda ea, name, ord: imported_eas.add(ea)) # Mark IDA-identified stuff imported stuff as imported. for ea in imported_eas: if not program.has_subroutine(ea): log.error( "No subroutine associated with import {:08x}.".format(ea)) continue sub = program.get_subroutine(ea) sub.visibility = program.Subroutine.VISIBILITY_IMPORTED # Mark functions in code sections marked as external as being imported. for sub in program.subroutines(): if program.Subroutine.VISIBILITY_INTERNAL != sub.visibility: continue if has_segment_type(sub.ea, idc.SEG_XTRN): log.debug("Subroutine {:08x} is imported".format(sub.ea)) sub.visibility = program.Subroutine.VISIBILITY_IMPORTED if sub.name: log.info("Found imported subroutine {} at {:08x}".format( sub.name, sub.ea))
def find_imported_subroutines(): """Find the address of all imported functions.""" # Collect addresses of imported code. imported_eas = set() num_imports = idaapi.get_import_module_qty() for i in xrange(num_imports): idaapi.enum_import_names(i, lambda ea, name, ord: imported_eas.add(ea)) # Mark IDA-identified stuff imported stuff as imported. for ea in imported_eas: if not program.has_subroutine(ea): log.error("No subroutine associated with import {:08x}.".format(ea)) continue sub = program.get_subroutine(ea) sub.visibility = program.Subroutine.VISIBILITY_IMPORTED # Mark functions in code sections marked as external as being imported. for sub in program.subroutines(): if program.Subroutine.VISIBILITY_INTERNAL != sub.visibility: continue if has_segment_type(sub.ea, idc.SEG_XTRN): log.debug("Subroutine {:08x} is imported".format(sub.ea)) sub.visibility = program.Subroutine.VISIBILITY_IMPORTED if sub.name: log.info("Found imported subroutine {} at {:08x}".format( sub.name, sub.ea))
def find_exported_subroutines(): """Find the functions that are exported to other binaries.""" exported_eas = find_exported_eas() for ea in exported_eas: if not program.has_subroutine(ea): continue sub = program.get_subroutine(ea) if program.Subroutine.VISIBILITY_INTERNAL != sub.visibility: continue sub.visibility = program.Subroutine.VISIBILITY_EXPORTED if sub.name: log.info("Found exported subroutine {} at {:08x}".format( sub.name, sub.ea)) mark_entry_block_address_taken(sub)