def Chunks(start): """ Get a list of function chunks @param start: address of the function @return: list of funcion chunks (tuples of the form (start_ea, end_ea)) belonging to the function """ func_iter = ida_funcs.func_tail_iterator_t( ida_funcs.get_func( start ) ) status = func_iter.main() while status: chunk = func_iter.chunk() yield (chunk.start_ea, chunk.end_ea) status = next(func_iter)
def visit(self, program, is_definition): if not is_definition: return memory = program.memory() seg = [None] ref_eas = set() # Map the continuous range of bytes associated with the main body of the # function. We might get a bit beyond that, as our function bounds stuff # looks for previous and next function locations. ea, max_ea = _get_function_bounds(self._pfn, seg) while ea < max_ea: if not _try_map_byte(memory, ea, seg): break _collect_xrefs_from_func(self._pfn, ea, ref_eas) ea += 1 # Map the bytes of function chunks. These are discontinuous parts of a # function, e.g. cold code put off the critical path to reduce icache # pressure. fti = ida_funcs.func_tail_iterator_t(self._pfn) ok = fti.first() while ok: chunk = fti.chunk() ea = chunk.start_ea max_ea = chunk.end_ea while ea < max_ea: if not _try_map_byte(memory, ea, seg): break _collect_xrefs_from_func(self._pfn, ea, ref_eas) ea += 1 ok = fti.next() # Now go and inspect cross-referenced date/code, and add it to the program. for ref_ea in ref_eas: try: program.add_function_declaration(ref_ea) except InvalidFunctionException: program.add_variable_declaration(ref_ea)