def _resolve_indirect_jumps(self, simrun, cfg_node, func_addr, successors, error_occurred, simrun_info_collection):
        """

        :return:
        """

        # Try to resolve indirect jumps with advanced backward slicing (if enabled)
        if isinstance(simrun, simuvex.SimIRSB) and \
                self._is_indirect_jump(cfg_node, simrun):
            l.debug('IRSB 0x%x has an indirect jump as its default exit', simrun.addr)

            # Throw away all current paths whose target doesn't make sense
            old_successors = successors[::]
            successors = []
            for i, suc in enumerate(old_successors):

                if suc.se.symbolic(suc.ip):
                    # It's symbolic. Take it, and hopefully we can resolve it later
                    successors.append(suc)

                else:
                    # It's concrete. Does it make sense?
                    ip_int = suc.se.exactly_int(suc.ip)

                    if self._is_address_executable(ip_int) or \
                            self.project.is_hooked(ip_int):
                        successors.append(suc)

                    else:
                        l.info('%s: an obviously incorrect successor %d/%d (%#x) is ditched',
                               cfg_node,
                               i + 1, len(old_successors),
                               ip_int)

            # We need input states to perform backward slicing
            if self._advanced_backward_slicing and self._keep_state:

                # Optimization: make sure we only try to resolve an indirect jump if any of the following criteria holds
                # - It's a jump (Ijk_Boring), and its target is either fully symbolic, or its resolved target is within
                #   the current binary
                # - It's a call (Ijk_Call), and its target is fully symbolic
                # TODO: This is very hackish, please refactor this part of code later
                should_resolve = True
                legit_successors = [suc for suc in successors if suc.scratch.jumpkind in ('Ijk_Boring', 'Ijk_Call')]
                if legit_successors:
                    legit_successor = legit_successors[0]
                    if legit_successor.ip.symbolic:
                        if not legit_successor.scratch.jumpkind == 'Ijk_Call':
                            should_resolve = False
                    else:
                        if legit_successor.scratch.jumpkind == 'Ijk_Call':
                            should_resolve = False
                        else:
                            concrete_target = legit_successor.se.any_int(legit_successor.ip)
                            if not self.project.loader.addr_belongs_to_object(
                                    concrete_target) is self.project.loader.main_bin:
                                should_resolve = False

                else:
                    # No interesting successors... skip
                    should_resolve = False

                # TODO: Handle those successors
                if not should_resolve:
                    l.debug("This might not be an indirect jump that has multiple targets. Skipped.")

                else:
                    more_successors = self._resolve_indirect_jump(cfg_node, simrun, func_addr)

                    if len(more_successors):
                        # Remove the symbolic successor
                        # TODO: Now we are removing all symbolic successors. Is it possible
                        # TODO: that there is more than one symbolic successor?
                        all_successors = [suc for suc in successors if not suc.se.symbolic(suc.ip)]
                        # Insert new successors
                        # We insert new successors in the beginning of all_successors list so that we don't break the
                        # assumption that Ijk_FakeRet is always the last element in the list
                        for suc_addr in more_successors:
                            a = simrun.default_exit.copy()
                            a.ip = suc_addr
                            all_successors.insert(0, a)

                        l.debug('The indirect jump is successfully resolved.')

                        self.kb._resolved_indirect_jumps.add(simrun.addr)

                    else:
                        l.debug('We failed to resolve the indirect jump.')
                        self.kb._unresolved_indirect_jumps.add(simrun.addr)

            else:
                if not successors:
                    l.debug('We cannot resolve the indirect jump without advanced backward slicing enabled: %s',
                            cfg_node)

        # Try to find more successors if we failed to resolve the indirect jump before
        if not error_occurred and (cfg_node.is_simprocedure or self._is_indirect_jump(cfg_node, simrun)):
            has_call_jumps = any([suc_state.scratch.jumpkind == 'Ijk_Call' for suc_state in successors])
            if has_call_jumps:
                concrete_successors = [suc_state for suc_state in successors if
                                       suc_state.scratch.jumpkind != 'Ijk_FakeRet' and not suc_state.se.symbolic(
                                           suc_state.ip)]
            else:
                concrete_successors = [suc_state for suc_state in successors if
                                       not suc_state.se.symbolic(suc_state.ip)]
            symbolic_successors = [suc_state for suc_state in successors if suc_state.se.symbolic(suc_state.ip)]

            resolved = len(symbolic_successors) == 0
            if len(symbolic_successors) > 0:
                for suc in symbolic_successors:
                    if suc.options in simuvex.o.SYMBOLIC:
                        targets = suc.se.any_n_int(suc.ip, 32)
                        if len(targets) < 32:
                            all_successors = []
                            resolved = True
                            for t in targets:
                                new_ex = suc.copy()
                                new_ex.ip = suc.se.BVV(t, suc.ip.size())
                                all_successors.append(new_ex)
                        else:
                            break

            if not resolved and (
                        (len(symbolic_successors) > 0 and len(concrete_successors) == 0) or
                        (not cfg_node.is_simprocedure and self._is_indirect_jump(cfg_node, simrun))
            ):
                l.debug("%s has an indirect jump. See what we can do about it.", cfg_node)

                if isinstance(simrun, simuvex.SimProcedure) and \
                        simrun.ADDS_EXITS:
                    # Skip those SimProcedures that don't create new SimExits
                    l.debug('We got a SimProcedure %s in fastpath mode that creates new exits.', simrun)
                    if self._enable_symbolic_back_traversal:
                        successors = self._symbolically_back_traverse(simrun, simrun_info_collection, cfg_node)
                        # mark jump as resolved if we got successors
                        if len(successors):
                            self.kb._resolved_indirect_jumps.add(simrun.addr)
                        else:
                            self.kb._unresolved_indirect_jumps.add(simrun.addr)
                        l.debug("Got %d concrete exits in symbolic mode.", len(successors))
                    else:
                        self.kb._unresolved_indirect_jumps.add(simrun.addr)
                        # keep fake_rets
                        successors = [s for s in successors if s.scratch.jumpkind == "Ijk_FakeRet"]

                elif isinstance(simrun, simuvex.SimIRSB) and \
                        any([ex.scratch.jumpkind != 'Ijk_Ret' for ex in successors]):
                    # We cannot properly handle Return as that requires us start execution from the caller...
                    l.debug("Try traversal backwards in symbolic mode on %s.", cfg_node)
                    if self._enable_symbolic_back_traversal:
                        successors = self._symbolically_back_traverse(simrun, simrun_info_collection, cfg_node)

                        # Remove successors whose IP doesn't make sense
                        successors = [suc for suc in successors
                                          if self._is_address_executable(suc.se.exactly_int(suc.ip))]

                        # mark jump as resolved if we got successors
                        if len(successors):
                            self.kb._resolved_indirect_jumps.add(simrun.addr)
                        else:
                            self.kb._unresolved_indirect_jumps.add(simrun.addr)
                        l.debug('Got %d concrete exits in symbolic mode', len(successors))
                    else:
                        self.kb._unresolved_indirect_jumps.add(simrun.addr)
                        successors = []

                elif len(successors) > 0 and all([ex.scratch.jumpkind == 'Ijk_Ret' for ex in successors]):
                    l.debug('All exits are returns (Ijk_Ret). It will be handled by pending exits.')

                else:
                    l.warning('It seems that we cannot resolve this indirect jump: %s', cfg_node)
                    self.kb._unresolved_indirect_jumps.add(simrun.addr)

        return successors
dataset/ETHPy150Open angr/angr/angr/analyses/cfg_accurate.py/CFGAccurate._resolve_indirect_jumps/swapped operands of `in`