def _handle_successor_multitargets(self, job, successor, all_successors):
        """
        Generate new jobs for all possible successor targets when there are more than one possible concrete value for
        successor.ip

        :param VFGJob job: The VFGJob instance.
        :param SimState successor: The succeeding state.
        :param list all_successors: All succeeding states from the same VFGJob.
        :return: A list of new succeeding jobs
        :rtype: list
        """

        new_jobs = [ ]

        # Currently we assume a legit jumping target cannot have more than 256 concrete values
        # TODO: make it a setting on VFG
        MAX_NUMBER_OF_CONCRETE_VALUES = 256

        all_possible_ips = successor.solver.eval_upto(successor.ip, MAX_NUMBER_OF_CONCRETE_VALUES + 1)

        if len(all_possible_ips) > MAX_NUMBER_OF_CONCRETE_VALUES:
            l.warning("IP can be concretized to more than %d values, which means it might be corrupted.",
                      MAX_NUMBER_OF_CONCRETE_VALUES)
            return [ ]

        # Call this function to generate a successor for each possible IP
        for ip in all_possible_ips:
            concrete_successor = successor.copy()
            concrete_successor.ip = ip

            concrete_jobs = self._handle_successor(job, concrete_successor, all_successors)

            if job.is_call_jump:  # TODO: take care of syscalls
                for new_job in concrete_jobs:
                    # TODO: correctly fill the return address. The return address can be found from the
                    # TODO: fakeret successor in the `successors` list
                    function_analysis_task = FunctionAnalysis(new_job.addr, None)
                    # log the new job
                    function_analysis_task.jobs.append(new_job)
                    # put it onto the stack
                    self._task_stack.append(function_analysis_task)
                    # log it in the call_task
                    job.call_task.register_function_analysis(function_analysis_task)

            new_jobs.extend(concrete_jobs)

        return new_jobs
def _handle_successor_multitargets ( self , job , successor , all_successors ) : new_jobs = [ ] MAX_NUMBER_OF_CONCRETE_VALUES = 256 all_possible_ips = successor . solver . eval_upto ( successor . ip , MAX_NUMBER_OF_CONCRETE_VALUES + 1 ) if len ( all_possible_ips ) > MAX_NUMBER_OF_CONCRETE_VALUES : l . warning ( "IP can be concretized to more than %d values, which means it might be corrupted." , MAX_NUMBER_OF_CONCRETE_VALUES ) return [ ] for ip in all_possible_ips : concrete_successor = successor . copy ( ) concrete_successor . ip = ip concrete_jobs = self . _handle_successor ( job , concrete_successor , all_successors ) if job . is_call_jump : for new_job in concrete_jobs : function_analysis_task = FunctionAnalysis ( new_job . addr , None ) function_analysis_task . jobs . append ( new_job ) self . _task_stack . append ( function_analysis_task ) job . call_task . register_function_analysis ( function_analysis_task ) new_jobs . extend ( concrete_jobs ) return new_jobs
Generate new jobs for all possible successor targets when there are more than one possible concrete value for
        successor.ip

        :param VFGJob job: The VFGJob instance.
        :param SimState successor: The succeeding state.
        :param list all_successors: All succeeding states from the same VFGJob.
        :return: A list of new succeeding jobs
        :rtype: list