def _recurse(self, ea, path, depth): if depth + 1 >= self.mr: self.paths[path] = [("[...]", BADADDR)] return # for all callers of ea... i = 0 for ref in idautils.CodeRefsTo(ea, False): if i + 1 >= self.mf: self.paths[path].append(("...", BADADDR)) break cea = ref func = ida_funcs.get_func(cea) if func: cea = func.start_ea loc_name = ida_name.get_short_name(cea) if not len(loc_name): loc_name = "unkn_%x" % cea elem = (loc_name, cea) # if path doesn't exist yet if path not in self.paths: self.paths[path] = [elem] # if caller doesn't exist yet if elem not in self.paths[path]: self.paths[path].append(elem) i += 1 newpath = "%s/%s" % (path, loc_name) self._recurse(cea, newpath, depth + 1) return
def _recurse(self, ea, path, depth): if depth >= self.mr: self.paths[path] = [("[...]", BADADDR)] return # for all callees of ea... i = 0 for cea in Callees(ea): if i + 1 >= self.mf: self.paths[path].append(("...", BADADDR)) break loc_name = ida_name.get_short_name(cea) if not len(loc_name): loc_name = "unkn_%x" % cea elem = (loc_name, cea) # if path doesn't exist yet if path not in self.paths: self.paths[path] = [elem] # if caller doesn't exist yet if elem not in self.paths[path]: self.paths[path].append(elem) i += 1 newpath = "%s/%s" % (path, loc_name) self._recurse(cea, newpath, depth + 1) return
def __init__(self, start_ea, max_recursion=MAX_DEPTH, max_func=MAX_FUNC): self.ea = start_ea name = ida_name.get_short_name(self.ea) if not len(name): name = "unkn_%x" % self.ea self.base_path = "parents [%s]" % name self.mr = max_recursion self.mf = max_func self.paths = {} self._recurse(self.ea, self.base_path, 0)
def print_stats(ext2func): """ Print stats about the scraped instructions. """ print("-" * 60) func_size_cache = {} all_funcs = set() print("\nFUNC USES -- UNSUPPORTED INSTR (%u types)\n" % len(ext2func)) for key in sorted(ext2func, key=lambda key: len(ext2func[key]), reverse=True): function_addresses = ext2func[key] all_funcs |= function_addresses # print the unsupported instruction op, and how many funcs use it print(" - USES: %d - OP: %s" % (len(function_addresses), key)) # compute the size of all the funcs that use this op.. func_sizes = [] for address in function_addresses: # try to grab the func size if we cached it already func_size = func_size_cache.get(address, None) if func_size: func_sizes.append((func_size, address)) continue # compute the size oe the function func = ida_funcs.get_func(address) func_size = ida_funcs.calc_func_size(func) func_sizes.append((func_size, address)) # cache the func size for future use func_size_cache[address] = func_size # print a few small functions that use this unsupported op.. func_sizes.sort() for size, address in func_sizes[:5]: print(" -- SAMPLE FUNC 0x%08X (%u bytes)" % (address, size)) print("\n" + "-" * 60 + "\n") print("AFFLICTED FUNCTIONS (%u funcs)\n" % len(all_funcs)) all_funcs = sorted(all_funcs) for ea in all_funcs: function_name = ida_name.get_short_name(ea) print("0x%08X: %s" % (ea, function_name))
def get_function_name_at(self, address): return ida_name.get_short_name(address)