示例#1
0
 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
示例#2
0
    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)
示例#3
0
    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])
示例#4
0
    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)
示例#5
0
    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
示例#6
0
 def _current_function(self):
     function = idaapi.get_func(ida_shims.get_screen_ea())
     return ida_shims.start_ea(function)