def _get_code_block(self, ea): for block in self.blocks: start_ea = ida_shims.start_ea(block) end_ea = ida_shims.end_ea(block) if start_ea <= ea and end_ea > ea: return block return None
def __init__(self, start_ea, end_ea, quiet=False): # We work backwards via xrefs, so we start at the end and end at the start try: func = idaapi.get_func(end_ea) start = ida_shims.start_ea(func) except: raise AlleyCatException("Address 0x%X is not part of a function!" % end_ea) try: func = idaapi.get_func(start_ea) end = ida_shims.start_ea(func) except: end = idc.BADADDR super(AlleyCatFunctionPaths, self).__init__(start, end, quiet)
def _build_paths(self, start, end=idc.BADADDR): partial_paths = [[start]] # Loop while there are still unresolve paths and while all path sizes # have not exceeded ALLEYCAT_LIMIT while partial_paths and \ len(self.paths) < self.limit and \ len(partial_paths) < self.limit: callers = set() # Callee is the last entry of the first path in partial paths. # The first path list will change as paths are completed and # popped from the list. callee = partial_paths[0][-1] # Find all unique functions that reference the callee, assuming this # path has not exceeded ALLEYCAT_LIMIT. if len(partial_paths[0]) < self.limit: for xref in idautils.XrefsTo(callee): caller = self._get_code_block(xref.frm) if caller: start_ea = ida_shims.start_ea(caller) if start_ea not in callers: callers.add(start_ea) # If there are callers to the callee, remove the callee's current # path and insert new ones with the new callers appended. if callers: base_path = partial_paths.pop(0) for caller in callers: # Don't want to loop back on ourselves in the same path if caller in base_path: continue # If we've reached the desired end node, don't go any # further down this path if caller == end: self._add_path((base_path + [caller])[::-1]) else: partial_paths.append(base_path + [caller]) # Else, our end node is not in this path, so don't include it in the # finished path list. elif end not in partial_paths[0]: partial_paths.pop(0) # If there were no callers then this path has been exhausted and # should be popped from the partial path list into the finished path list. elif end in partial_paths[0]: # Paths start with the end function and end with the start # function; reverse it. self._add_path(partial_paths.pop(0)[::-1])
def __init__(self, start_ea, end_ea, quiet=False): end_func = idaapi.get_func(end_ea) start_func = idaapi.get_func(start_ea) if not start_func: raise AlleyCatException("Address 0x%X is not part of a function!" % start_ea) if not end_func: raise AlleyCatException("Address 0x%X is not part of a function!" % end_ea) start_func_ea = ida_shims.start_ea(start_func) end_func_ea = ida_shims.start_ea(end_func) # end_func_ea = ida_shims.end_ea(end_func) if start_func_ea != end_func_ea: raise AlleyCatException("The start and end addresses are not part " "of the same function!") self.func = start_func self.blocks = [block for block in idaapi.FlowChart(self.func)] # We work backwards via xrefs, so we start at the end and end at the start end_block = self._get_code_block(start_ea) start_block = self._get_code_block(end_ea) if not end_block: raise AlleyCatException("Failed to find the code block associated " "with address 0x%X" % start_ea) if not start_block: raise AlleyCatException("Failed to find the code block associated " "with address 0x%X" % end_ea) start_block_ea = ida_shims.start_ea(start_block) end_block_ea = ida_shims.start_ea(end_block) super(AlleyCatCodePaths, self).__init__(start_block_ea, end_block_ea, quiet)
def colorize_node(self, ea, color): # Colorizes an entire code block func = idaapi.get_func(ea) if func: for block in idaapi.FlowChart(func): block_start_ea = ida_shims.start_ea(block) block_end_ea = ida_shims.end_ea(block) if block_start_ea <= ea and block_end_ea > ea: ea = block_start_ea while ea < block_end_ea: idaapi.set_item_color(ea, color) ea = ida_shims.next_head(ea) break
def _current_function(self): function = idaapi.get_func(ida_shims.get_screen_ea()) return ida_shims.start_ea(function)