(self, sort, context_sensitivity_level, normalize=False, binary=None, force_segment=False,
                 base_state=None, resolve_indirect_jumps=True, indirect_jump_resolvers=None,
                 indirect_jump_target_limit=100000, detect_tail_calls=False, low_priority=False,
                 sp_tracking_track_memory=True, model=None,
                 )
:param str sort:                            'fast' or 'emulated'.
        :param int context_sensitivity_level:       The level of context-sensitivity of this CFG (see documentation for
                                                    further details). It ranges from 0 to infinity.
        :param bool normalize:                      Whether the CFG as well as all Function graphs should be normalized.
        :param cle.backends.Backend binary:         The binary to recover CFG on. By default the main binary is used.
        :param bool force_segment:                  Force CFGFast to rely on binary segments instead of sections.
        :param angr.SimState base_state:            A state to use as a backer for all memory loads.
        :param bool resolve_indirect_jumps:         Whether to try to resolve indirect jumps.
                                                    This is necessary to resolve jump targets from jump tables, etc.
        :param list indirect_jump_resolvers:        A custom list of indirect jump resolvers.
                                                    If this list is None or empty, default indirect jump resolvers
                                                    specific to this architecture and binary types will be loaded.
        :param int indirect_jump_target_limit:      Maximum indirect jump targets to be recovered.
        :param bool detect_tail_calls:              Aggressive tail-call optimization detection. This option is only
                                                    respected in make_functions().
        :param bool sp_tracking_track_memory:       Whether or not to track memory writes if tracking the stack pointer.
                                                    This increases the accuracy of stack pointer tracking,
                                                    especially for architectures without a base pointer.
                                                    Only used if detect_tail_calls is enabled.
        :param None or CFGModel model:              The CFGModel instance to write to. A new CFGModel instance will be
                                                    created and registered with the knowledge base if `model` is None.

        :return: None
:param str sort:                            'fast' or 'emulated'.
        :param int context_sensitivity_level:       The level of context-sensitivity of this CFG (see documentation for
                                                    further details). It ranges from 0 to infinity.
        :param bool normalize:                      Whether the CFG as well as all Function graphs should be normalized.
        :param cle.backends.Backend binary:         The binary to recover CFG on. By default the main binary is used.
        :param bool force_segment:                  Force CFGFast to rely on binary segments instead of sections.
        :param angr.SimState base_state:            A state to use as a backer for all memory loads.
        :param bool resolve_indirect_jumps:         Whether to try to resolve indirect jumps.
                                                    This is necessary to resolve jump targets from jump tables, etc.
        :param list indirect_jump_resolvers:        A custom list of indirect jump resolvers.
                                                    If this list is None or empty, default indirect jump resolvers
                                                    specific to this architecture and binary types will be loaded.
        :param int indirect_jump_target_limit:      Maximum indirect jump targets to be recovered.
        :param bool detect_tail_calls:              Aggressive tail-call optimization detection. This option is only
                                                    respected in make_functions().
        :param bool sp_tracking_track_memory:       Whether or not to track memory writes if tracking the stack pointer.
                                                    This increases the accuracy of stack pointer tracking,
                                                    especially for architectures without a base pointer.
                                                    Only used if detect_tail_calls is enabled.
        :param None or CFGModel model:              The CFGModel instance to write to. A new CFGModel instance will be
                                                    created and registered with the knowledge base if `model` is None.
: param str sort : fast or emulated . : param int context_sensitivity_level : The level of context - sensitivity of this CFG ( see documentation for further details ) . It ranges from 0 to infinity . : param bool normalize : Whether the CFG as well as all Function graphs should be normalized . : param cle . backends . Backend binary : The binary to recover CFG on . By default the main binary is used . : param bool force_segment : Force CFGFast to rely on binary segments instead of sections . : param angr . SimState base_state : A state to use as a backer for all memory loads . : param bool resolve_indirect_jumps : Whether to try to resolve indirect jumps . This is necessary to resolve jump targets from jump tables etc . : param list indirect_jump_resolvers : A custom list of indirect jump resolvers . If this list is None or empty default indirect jump resolvers specific to this architecture and binary types will be loaded . : param int indirect_jump_target_limit : Maximum indirect jump targets to be recovered . : param bool detect_tail_calls : Aggressive tail - call optimization detection . This option is only respected in make_functions () . : param bool sp_tracking_track_memory : Whether or not to track memory writes if tracking the stack pointer . This increases the accuracy of stack pointer tracking especially for architectures without a base pointer . Only used if detect_tail_calls is enabled . : param None or CFGModel model : The CFGModel instance to write to . A new CFGModel instance will be created and registered with the knowledge base if model is None .
def __init__(self, sort, context_sensitivity_level, normalize=False, binary=None, force_segment=False,
                 base_state=None, resolve_indirect_jumps=True, indirect_jump_resolvers=None,
                 indirect_jump_target_limit=100000, detect_tail_calls=False, low_priority=False,
                 sp_tracking_track_memory=True, model=None,
                 ):
        """
        :param str sort:                            'fast' or 'emulated'.
        :param int context_sensitivity_level:       The level of context-sensitivity of this CFG (see documentation for
                                                    further details). It ranges from 0 to infinity.
        :param bool normalize:                      Whether the CFG as well as all Function graphs should be normalized.
        :param cle.backends.Backend binary:         The binary to recover CFG on. By default the main binary is used.
        :param bool force_segment:                  Force CFGFast to rely on binary segments instead of sections.
        :param angr.SimState base_state:            A state to use as a backer for all memory loads.
        :param bool resolve_indirect_jumps:         Whether to try to resolve indirect jumps.
                                                    This is necessary to resolve jump targets from jump tables, etc.
        :param list indirect_jump_resolvers:        A custom list of indirect jump resolvers.
                                                    If this list is None or empty, default indirect jump resolvers
                                                    specific to this architecture and binary types will be loaded.
        :param int indirect_jump_target_limit:      Maximum indirect jump targets to be recovered.
        :param bool detect_tail_calls:              Aggressive tail-call optimization detection. This option is only
                                                    respected in make_functions().
        :param bool sp_tracking_track_memory:       Whether or not to track memory writes if tracking the stack pointer.
                                                    This increases the accuracy of stack pointer tracking,
                                                    especially for architectures without a base pointer.
                                                    Only used if detect_tail_calls is enabled.
        :param None or CFGModel model:              The CFGModel instance to write to. A new CFGModel instance will be
                                                    created and registered with the knowledge base if `model` is None.

        :return: None
        """

        self.sort = sort
        self._context_sensitivity_level=context_sensitivity_level

        # Sanity checks
        if context_sensitivity_level < 0:
            raise ValueError("Unsupported context sensitivity level %d" % context_sensitivity_level)

        self._binary = binary if binary is not None else self.project.loader.main_object
        self._force_segment = force_segment
        self._base_state = base_state
        self._detect_tail_calls = detect_tail_calls
        self._low_priority = low_priority

        # Initialization
        self._edge_map = None
        self._loop_back_edges = None
        self._overlapped_loop_headers = None
        self._thumb_addrs = set()
        self._tail_calls = set()

        # Store all the functions analyzed before the set is cleared
        # Used for performance optimization
        self._updated_nonreturning_functions = None

        self._normalize = normalize
        # Flag, whether the CFG has been normalized or not
        self._normalized = False

        # Flag, whether to track memory writes in stack pointer tracking
        self._sp_tracking_track_memory = sp_tracking_track_memory

        # IndirectJump object that describe all indirect exits found in the binary
        # stores as a map between addresses and IndirectJump objects
        self.indirect_jumps: Dict[int,IndirectJump] = {}
        self._indirect_jumps_to_resolve = set()

        # Indirect jump resolvers
        self._indirect_jump_target_limit = indirect_jump_target_limit
        self._resolve_indirect_jumps = resolve_indirect_jumps
        self.timeless_indirect_jump_resolvers = [ ]
        self.indirect_jump_resolvers = [ ]
        if not indirect_jump_resolvers:
            indirect_jump_resolvers = default_indirect_jump_resolvers(self._binary, self.project)
        if self._resolve_indirect_jumps and indirect_jump_resolvers:
            # split them into different groups for the sake of speed
            for ijr in indirect_jump_resolvers:
                if ijr.timeless:
                    self.timeless_indirect_jump_resolvers.append(ijr)
                else:
                    self.indirect_jump_resolvers.append(ijr)

        l.info("Loaded %d indirect jump resolvers (%d timeless, %d generic).",
               len(self.timeless_indirect_jump_resolvers) + len(self.indirect_jump_resolvers),
               len(self.timeless_indirect_jump_resolvers),
               len(self.indirect_jump_resolvers)
               )

        # Get all executable memory regions
        self._exec_mem_regions = self._executable_memory_regions(None, self._force_segment)
        self._exec_mem_region_size = sum([(end - start) for start, end in self._exec_mem_regions])

        # initialize UnresolvableJumpTarget and UnresolvableCallTarget SimProcedure
        # but we do not want to hook the same symbol multiple times
        ut_jump_addr = self.project.loader.extern_object.get_pseudo_addr('UnresolvableJumpTarget')
        if not self.project.is_hooked(ut_jump_addr):
            self.project.hook(ut_jump_addr, SIM_PROCEDURES['stubs']['UnresolvableJumpTarget']())
        self._unresolvable_jump_target_addr = ut_jump_addr
        ut_call_addr = self.project.loader.extern_object.get_pseudo_addr('UnresolvableCallTarget')
        if not self.project.is_hooked(ut_call_addr):
            self.project.hook(ut_call_addr, SIM_PROCEDURES['stubs']['UnresolvableCallTarget']())
        self._unresolvable_call_target_addr = ut_call_addr

        # partially and fully analyzed functions
        # this is implemented as a state machine: jobs (CFGJob instances) of each function are put into
        # _jobs_to_analyze_per_function, which essentially makes the keys of this dict being all partially analyzed
        # functions so far. And then when a function does not have any more job to analyze in the future, it will be
        # put in to _completed_functions.

        # a dict of mapping between function addresses and sets of jobs (include both future jobs and pending jobs)
        # a set is used to speed up the job removal procedure
        self._jobs_to_analyze_per_function = defaultdict(set)
        # addresses of functions that have been completely recovered (i.e. all of its blocks are identified) so far
        self._completed_functions = set()

        # TODO: A segment tree to speed up CFG node lookups
        self._node_lookup_index = None
        self._node_lookup_index_warned = False

        self._function_addresses_from_symbols = self._load_func_addrs_from_symbols()
        self._function_addresses_from_eh_frame = self._load_func_addrs_from_eh_frame()

        # Cache if an object has executable sections or not
        self._object_to_executable_sections = { }

        if model is not None:
            self._model = model
        else:
            self._model = self.kb.cfgs.new_model(self.tag)
def __init__ ( self , sort , context_sensitivity_level , normalize = False , binary = None , force_segment = False , base_state = None , resolve_indirect_jumps = True , indirect_jump_resolvers = None , indirect_jump_target_limit = 100000 , detect_tail_calls = False , low_priority = False , sp_tracking_track_memory = True , model = None , ) : self . sort = sort self . _context_sensitivity_level = context_sensitivity_level # Sanity checks if context_sensitivity_level < 0 : raise ValueError ( "Unsupported context sensitivity level %d" % context_sensitivity_level ) self . _binary = binary if binary is not None else self . project . loader . main_object self . _force_segment = force_segment self . _base_state = base_state self . _detect_tail_calls = detect_tail_calls self . _low_priority = low_priority # Initialization self . _edge_map = None self . _loop_back_edges = None self . _overlapped_loop_headers = None self . _thumb_addrs = set ( ) self . _tail_calls = set ( ) # Store all the functions analyzed before the set is cleared # Used for performance optimization self . _updated_nonreturning_functions = None self . _normalize = normalize # Flag, whether the CFG has been normalized or not self . _normalized = False # Flag, whether to track memory writes in stack pointer tracking self . _sp_tracking_track_memory = sp_tracking_track_memory # IndirectJump object that describe all indirect exits found in the binary # stores as a map between addresses and IndirectJump objects self . indirect_jumps : Dict [ int , IndirectJump ] = { } self . _indirect_jumps_to_resolve = set ( ) # Indirect jump resolvers self . _indirect_jump_target_limit = indirect_jump_target_limit self . _resolve_indirect_jumps = resolve_indirect_jumps self . timeless_indirect_jump_resolvers = [ ] self . indirect_jump_resolvers = [ ] if not indirect_jump_resolvers : indirect_jump_resolvers = default_indirect_jump_resolvers ( self . _binary , self . project ) if self . _resolve_indirect_jumps and indirect_jump_resolvers : # split them into different groups for the sake of speed for ijr in indirect_jump_resolvers : if ijr . timeless : self . timeless_indirect_jump_resolvers . append ( ijr ) else : self . indirect_jump_resolvers . append ( ijr ) l . info ( "Loaded %d indirect jump resolvers (%d timeless, %d generic)." , len ( self . timeless_indirect_jump_resolvers ) + len ( self . indirect_jump_resolvers ) , len ( self . timeless_indirect_jump_resolvers ) , len ( self . indirect_jump_resolvers ) ) # Get all executable memory regions self . _exec_mem_regions = self . _executable_memory_regions ( None , self . _force_segment ) self . _exec_mem_region_size = sum ( [ ( end - start ) for start , end in self . _exec_mem_regions ] ) # initialize UnresolvableJumpTarget and UnresolvableCallTarget SimProcedure # but we do not want to hook the same symbol multiple times ut_jump_addr = self . project . loader . extern_object . get_pseudo_addr ( 'UnresolvableJumpTarget' ) if not self . project . is_hooked ( ut_jump_addr ) : self . project . hook ( ut_jump_addr , SIM_PROCEDURES [ 'stubs' ] [ 'UnresolvableJumpTarget' ] ( ) ) self . _unresolvable_jump_target_addr = ut_jump_addr ut_call_addr = self . project . loader . extern_object . get_pseudo_addr ( 'UnresolvableCallTarget' ) if not self . project . is_hooked ( ut_call_addr ) : self . project . hook ( ut_call_addr , SIM_PROCEDURES [ 'stubs' ] [ 'UnresolvableCallTarget' ] ( ) ) self . _unresolvable_call_target_addr = ut_call_addr # partially and fully analyzed functions # this is implemented as a state machine: jobs (CFGJob instances) of each function are put into # _jobs_to_analyze_per_function, which essentially makes the keys of this dict being all partially analyzed # functions so far. And then when a function does not have any more job to analyze in the future, it will be # put in to _completed_functions. # a dict of mapping between function addresses and sets of jobs (include both future jobs and pending jobs) # a set is used to speed up the job removal procedure self . _jobs_to_analyze_per_function = defaultdict ( set ) # addresses of functions that have been completely recovered (i.e. all of its blocks are identified) so far self . _completed_functions = set ( ) # TODO: A segment tree to speed up CFG node lookups self . _node_lookup_index = None self . _node_lookup_index_warned = False self . _function_addresses_from_symbols = self . _load_func_addrs_from_symbols ( ) self . _function_addresses_from_eh_frame = self . _load_func_addrs_from_eh_frame ( ) # Cache if an object has executable sections or not self . _object_to_executable_sections = { } if model is not None : self . _model = model else : self . _model = self . kb . cfgs . new_model ( self . tag )