Throw away all successors whose target doesn't make sense

        This method is called after we resolve an indirect jump using an unreliable method (like, not through one of
        the indirect jump resolvers, but through either pure concrete execution or backward slicing) to filter out the
        obviously incorrect successors.

        :param list successors: A collection of successors.
        :return:                A filtered list of successors
        :rtype:                 list

def _filter_insane_successors(self, successors):
        """
        Throw away all successors whose target doesn't make sense

        This method is called after we resolve an indirect jump using an unreliable method (like, not through one of
        the indirect jump resolvers, but through either pure concrete execution or backward slicing) to filter out the
        obviously incorrect successors.

        :param list successors: A collection of successors.
        :return:                A filtered list of successors
        :rtype:                 list
        """

        old_successors = successors[::]
        successors = [ ]
        for i, suc in enumerate(old_successors):
            if suc.solver.symbolic(suc.ip):
                # It's symbolic. Take it, and hopefully we can resolve it later
                successors.append(suc)

            else:
                ip_int = suc.solver.eval_one(suc.ip)

                if self._is_address_executable(ip_int) or \
                        self.project.is_hooked(ip_int) or \
                        self.project.simos.is_syscall_addr(ip_int):
                    successors.append(suc)
                else:
                    l.debug('An obviously incorrect successor %d/%d (%#x) is ditched',
                            i + 1,
                            len(old_successors),
                            ip_int
                            )

        return successors