(self, sim_successors, cfg_node, func_addr, successors, exception_info, artifacts)
return successors
Resolve indirect jumps specified by sim_successors.addr.

        :param SimSuccessors sim_successors: The SimSuccessors instance.
        :param CFGNode cfg_node:                     The CFGNode instance.
        :param int func_addr:                        Current function address.
        :param list successors:                      A list of successors.
        :param tuple exception_info:                 The sys.exc_info() of the exception or None if none occurred.
        :param artifacts:                            A container of collected information.
        :return:                                     Resolved successors
        :rtype:                                      list
Resolve indirect jumps specified by sim_successors.addr.
Resolve indirect jumps specified by sim_successors . addr .
def _try_resolving_indirect_jumps(self, sim_successors, cfg_node, func_addr, successors, exception_info, artifacts):
        """
        Resolve indirect jumps specified by sim_successors.addr.

        :param SimSuccessors sim_successors: The SimSuccessors instance.
        :param CFGNode cfg_node:                     The CFGNode instance.
        :param int func_addr:                        Current function address.
        :param list successors:                      A list of successors.
        :param tuple exception_info:                 The sys.exc_info() of the exception or None if none occurred.
        :param artifacts:                            A container of collected information.
        :return:                                     Resolved successors
        :rtype:                                      list
        """

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

            # 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.history.jumpkind in ('Ijk_Boring', 'Ijk_InvalICache', 'Ijk_Call')]
                if legit_successors:
                    legit_successor = legit_successors[0]
                    if legit_successor.ip.symbolic:
                        if not legit_successor.history.jumpkind == 'Ijk_Call':
                            should_resolve = False
                    else:
                        if legit_successor.history.jumpkind == 'Ijk_Call':
                            should_resolve = False
                        else:
                            concrete_target = legit_successor.solver.eval(legit_successor.ip)
                            if not self.project.loader.find_object_containing(
                                    concrete_target) is self.project.loader.main_object:
                                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.")
                    self.kb.unresolved_indirect_jumps.add(cfg_node.addr)

                else:
                    more_successors = self._backward_slice_indirect(cfg_node, sim_successors, func_addr)

                    if 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.solver.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 = sim_successors.all_successors[0].copy()
                            a.ip = suc_addr
                            all_successors.insert(0, a)

                        l.debug('The indirect jump is successfully resolved.')
                        self.kb.indirect_jumps.update_resolved_addrs(cfg_node.addr, more_successors)

                    else:
                        l.debug('Failed to resolve the indirect jump.')
                        self.kb.unresolved_indirect_jumps.add(cfg_node.addr)

            else:
                if not successors:
                    l.debug('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 exception_info is None and (cfg_node.is_simprocedure or self._is_indirect_jump(cfg_node, sim_successors)):
            has_call_jumps = any(suc_state.history.jumpkind == 'Ijk_Call' for suc_state in successors)
            if has_call_jumps:
                concrete_successors = [suc_state for suc_state in successors if
                                       suc_state.history.jumpkind != 'Ijk_FakeRet' and not suc_state.solver.symbolic(
                                           suc_state.ip)]
            else:
                concrete_successors = [suc_state for suc_state in successors if
                                       not suc_state.solver.symbolic(suc_state.ip)]
            symbolic_successors = [suc_state for suc_state in successors if suc_state.solver.symbolic(suc_state.ip)]

            resolved = True if not symbolic_successors else False
            if symbolic_successors:
                for suc in symbolic_successors:
                    if o.SYMBOLIC in suc.options:
                        targets = suc.solver.eval_upto(suc.ip, 32)
                        if len(targets) < 32:
                            all_successors = []
                            resolved = True
                            for t in targets:
                                new_ex = suc.copy()
                                new_ex.ip = suc.solver.BVV(t, suc.ip.size())
                                all_successors.append(new_ex)
                        else:
                            break

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

                if sim_successors.sort == 'SimProcedure' and \
                        sim_successors.artifacts['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.', sim_successors.description)
                    if self._enable_symbolic_back_traversal:
                        successors = self._symbolically_back_traverse(sim_successors, artifacts, cfg_node)
                        # mark jump as resolved if we got successors
                        if successors:
                            succ_addrs = [s.addr for s in successors]
                            self.kb.indirect_jumps.update_resolved_addrs(cfg_node.addr, succ_addrs)
                        else:
                            self.kb.unresolved_indirect_jumps.add(cfg_node.addr)
                        l.debug("Got %d concrete exits in symbolic mode.", len(successors))
                    else:
                        self.kb.unresolved_indirect_jumps.add(cfg_node.addr)
                        # keep fake_rets
                        successors = [s for s in successors if s.history.jumpkind == "Ijk_FakeRet"]

                elif sim_successors.sort == 'IRSB'and \
                        any([ex.history.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(sim_successors, artifacts, cfg_node)

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

                        # mark jump as resolved if we got successors
                        if successors:
                            succ_addrs = [s.addr for s in successors]
                            self.kb.indirect_jumps.update_resolved_addrs(cfg_node.addr, succ_addrs)
                        else:
                            self.kb.unresolved_indirect_jumps.add(cfg_node.addr)
                        l.debug('Got %d concrete exits in symbolic mode', len(successors))
                    else:
                        self.kb.unresolved_indirect_jumps.add(cfg_node.addr)
                        successors = []

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

                else:
                    l.debug('Cannot resolve this indirect jump: %s', cfg_node)
                    self.kb.unresolved_indirect_jumps.add(cfg_node.addr)

        return successors
def _try_resolving_indirect_jumps ( self , sim_successors , cfg_node , func_addr , successors , exception_info , artifacts ) : # Try to resolve indirect jumps with advanced backward slicing (if enabled) if sim_successors . sort == 'IRSB' and self . _is_indirect_jump ( cfg_node , sim_successors ) : l . debug ( 'IRSB %#x has an indirect jump as its default exit' , cfg_node . addr ) # 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 . history . jumpkind in ( 'Ijk_Boring' , 'Ijk_InvalICache' , 'Ijk_Call' ) ] if legit_successors : legit_successor = legit_successors [ 0 ] if legit_successor . ip . symbolic : if not legit_successor . history . jumpkind == 'Ijk_Call' : should_resolve = False else : if legit_successor . history . jumpkind == 'Ijk_Call' : should_resolve = False else : concrete_target = legit_successor . solver . eval ( legit_successor . ip ) if not self . project . loader . find_object_containing ( concrete_target ) is self . project . loader . main_object : 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." ) self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) else : more_successors = self . _backward_slice_indirect ( cfg_node , sim_successors , func_addr ) if 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 . solver . 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 = sim_successors . all_successors [ 0 ] . copy ( ) a . ip = suc_addr all_successors . insert ( 0 , a ) l . debug ( 'The indirect jump is successfully resolved.' ) self . kb . indirect_jumps . update_resolved_addrs ( cfg_node . addr , more_successors ) else : l . debug ( 'Failed to resolve the indirect jump.' ) self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) else : if not successors : l . debug ( '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 exception_info is None and ( cfg_node . is_simprocedure or self . _is_indirect_jump ( cfg_node , sim_successors ) ) : has_call_jumps = any ( suc_state . history . jumpkind == 'Ijk_Call' for suc_state in successors ) if has_call_jumps : concrete_successors = [ suc_state for suc_state in successors if suc_state . history . jumpkind != 'Ijk_FakeRet' and not suc_state . solver . symbolic ( suc_state . ip ) ] else : concrete_successors = [ suc_state for suc_state in successors if not suc_state . solver . symbolic ( suc_state . ip ) ] symbolic_successors = [ suc_state for suc_state in successors if suc_state . solver . symbolic ( suc_state . ip ) ] resolved = True if not symbolic_successors else False if symbolic_successors : for suc in symbolic_successors : if o . SYMBOLIC in suc . options : targets = suc . solver . eval_upto ( suc . ip , 32 ) if len ( targets ) < 32 : all_successors = [ ] resolved = True for t in targets : new_ex = suc . copy ( ) new_ex . ip = suc . solver . BVV ( t , suc . ip . size ( ) ) all_successors . append ( new_ex ) else : break if not resolved and ( ( symbolic_successors and not concrete_successors ) or ( not cfg_node . is_simprocedure and self . _is_indirect_jump ( cfg_node , sim_successors ) ) ) : l . debug ( "%s has an indirect jump. See what we can do about it." , cfg_node ) if sim_successors . sort == 'SimProcedure' and sim_successors . artifacts [ '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.' , sim_successors . description ) if self . _enable_symbolic_back_traversal : successors = self . _symbolically_back_traverse ( sim_successors , artifacts , cfg_node ) # mark jump as resolved if we got successors if successors : succ_addrs = [ s . addr for s in successors ] self . kb . indirect_jumps . update_resolved_addrs ( cfg_node . addr , succ_addrs ) else : self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) l . debug ( "Got %d concrete exits in symbolic mode." , len ( successors ) ) else : self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) # keep fake_rets successors = [ s for s in successors if s . history . jumpkind == "Ijk_FakeRet" ] elif sim_successors . sort == 'IRSB' and any ( [ ex . history . 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 ( sim_successors , artifacts , cfg_node ) # Remove successors whose IP doesn't make sense successors = [ suc for suc in successors if self . _is_address_executable ( suc . solver . eval_one ( suc . ip ) ) ] # mark jump as resolved if we got successors if successors : succ_addrs = [ s . addr for s in successors ] self . kb . indirect_jumps . update_resolved_addrs ( cfg_node . addr , succ_addrs ) else : self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) l . debug ( 'Got %d concrete exits in symbolic mode' , len ( successors ) ) else : self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) successors = [ ] elif successors and all ( [ ex . history . jumpkind == 'Ijk_Ret' for ex in successors ] ) : l . debug ( 'All exits are returns (Ijk_Ret). It will be handled by pending exits.' ) else : l . debug ( 'Cannot resolve this indirect jump: %s' , cfg_node ) self . kb . unresolved_indirect_jumps . add ( cfg_node . addr ) return successors