(self, cfg_job, current_func_addr)
return entries
Checks the hooking procedure for this address searching for new static
        exit points to add to successors (generating entries for them)
        if this address has not been traced before. Updates previous CFG nodes
        with edges.

        :param CFGJob cfg_job:      The CFGJob instance.
        :param int current_func_addr: Address of the current function.
        :return: List of successors
        :rtype: list
Checks the hooking procedure for this address searching for new static
        exit points to add to successors (generating entries for them)
        if this address has not been traced before. Updates previous CFG nodes
        with edges.
Checks the hooking procedure for this address searching for new static exit points to add to successors ( generating entries for them ) if this address has not been traced before . Updates previous CFG nodes with edges .
def _scan_procedure(self, cfg_job, current_func_addr):
        """
        Checks the hooking procedure for this address searching for new static
        exit points to add to successors (generating entries for them)
        if this address has not been traced before. Updates previous CFG nodes
        with edges.

        :param CFGJob cfg_job:      The CFGJob instance.
        :param int current_func_addr: Address of the current function.
        :return: List of successors
        :rtype: list
        """

        addr = cfg_job.addr

        try:
            if self.project.is_hooked(addr):
                procedure = self.project.hooked_by(addr)
                name = procedure.display_name
            else:
                procedure = self.project.simos.syscall_from_addr(addr)
                name = procedure.display_name

            if addr not in self._nodes:
                cfg_node = CFGNode(addr, 0, self.model,
                                   function_address=current_func_addr,
                                   simprocedure_name=name,
                                   no_ret=procedure.NO_RET,
                                   block_id=addr,
                                   )
                self._model.add_node(addr, cfg_node)

            else:
                cfg_node = self._nodes[addr]

        except (SimMemoryError, SimEngineError):
            return [ ]

        self._graph_add_edge(cfg_node, cfg_job.src_node, cfg_job.jumpkind, cfg_job.src_ins_addr,
                             cfg_job.src_stmt_idx
                             )
        self._function_add_node(cfg_node, current_func_addr)

        # Add edges going to this node in function graphs
        cfg_job.apply_function_edges(self, clear=True)

        # If we have traced it before, don't trace it anymore
        if addr in self._traced_addresses:
            return [ ]
        else:
            # Mark the address as traced
            self._traced_addresses.add(addr)

        entries = [ ]

        if procedure.ADDS_EXITS:
            # Get two blocks ahead
            if cfg_job.src_node is None:
                l.warning("%s is supposed to yield new exits, but it fails to do so.", name)
                return []
            grandparent_nodes = list(self.graph.predecessors(cfg_job.src_node))
            grandparent_node = grandparent_nodes[0] if grandparent_nodes else None
            blocks_ahead = [ ]
            if grandparent_node is not None:
                blocks_ahead.append(self._lift(grandparent_node.addr).vex)
            blocks_ahead.append(self._lift(cfg_job.src_node.addr).vex)
            procedure.project = self.project
            procedure.arch = self.project.arch
            new_exits = procedure.static_exits(blocks_ahead)

            for new_exit in new_exits:
                addr_ = new_exit['address']
                jumpkind = new_exit['jumpkind']
                namehint = new_exit.get('namehint', None)
                if isinstance(addr_, claripy.ast.BV) and not addr_.symbolic:  # pylint:disable=isinstance-second-argument-not-valid-type
                    addr_ = addr_._model_concrete.value
                if not isinstance(addr_, int):
                    continue
                entries += self._create_jobs(addr_, jumpkind, current_func_addr, None, addr_, cfg_node, None,
                                             None,
                                             )
                if namehint and addr_ not in self.kb.labels:
                    unique_label = self.kb.labels.get_unique_label(namehint)
                    self.kb.labels[addr_] = unique_label

        if not procedure.NO_RET:
            # it returns
            cfg_node.has_return = True
            self._function_exits[current_func_addr].add(addr)
            self._function_add_return_site(addr, current_func_addr)
        else:
            # the procedure does not return
            self._updated_nonreturning_functions.add(current_func_addr)

        return entries
def _scan_procedure ( self , cfg_job , current_func_addr ) : addr = cfg_job . addr try : if self . project . is_hooked ( addr ) : procedure = self . project . hooked_by ( addr ) name = procedure . display_name else : procedure = self . project . simos . syscall_from_addr ( addr ) name = procedure . display_name if addr not in self . _nodes : cfg_node = CFGNode ( addr , 0 , self . model , function_address = current_func_addr , simprocedure_name = name , no_ret = procedure . NO_RET , block_id = addr , ) self . _model . add_node ( addr , cfg_node ) else : cfg_node = self . _nodes [ addr ] except ( SimMemoryError , SimEngineError ) : return [ ] self . _graph_add_edge ( cfg_node , cfg_job . src_node , cfg_job . jumpkind , cfg_job . src_ins_addr , cfg_job . src_stmt_idx ) self . _function_add_node ( cfg_node , current_func_addr ) # Add edges going to this node in function graphs cfg_job . apply_function_edges ( self , clear = True ) # If we have traced it before, don't trace it anymore if addr in self . _traced_addresses : return [ ] else : # Mark the address as traced self . _traced_addresses . add ( addr ) entries = [ ] if procedure . ADDS_EXITS : # Get two blocks ahead if cfg_job . src_node is None : l . warning ( "%s is supposed to yield new exits, but it fails to do so." , name ) return [ ] grandparent_nodes = list ( self . graph . predecessors ( cfg_job . src_node ) ) grandparent_node = grandparent_nodes [ 0 ] if grandparent_nodes else None blocks_ahead = [ ] if grandparent_node is not None : blocks_ahead . append ( self . _lift ( grandparent_node . addr ) . vex ) blocks_ahead . append ( self . _lift ( cfg_job . src_node . addr ) . vex ) procedure . project = self . project procedure . arch = self . project . arch new_exits = procedure . static_exits ( blocks_ahead ) for new_exit in new_exits : addr_ = new_exit [ 'address' ] jumpkind = new_exit [ 'jumpkind' ] namehint = new_exit . get ( 'namehint' , None ) if isinstance ( addr_ , claripy . ast . BV ) and not addr_ . symbolic : # pylint:disable=isinstance-second-argument-not-valid-type addr_ = addr_ . _model_concrete . value if not isinstance ( addr_ , int ) : continue entries += self . _create_jobs ( addr_ , jumpkind , current_func_addr , None , addr_ , cfg_node , None , None , ) if namehint and addr_ not in self . kb . labels : unique_label = self . kb . labels . get_unique_label ( namehint ) self . kb . labels [ addr_ ] = unique_label if not procedure . NO_RET : # it returns cfg_node . has_return = True self . _function_exits [ current_func_addr ] . add ( addr ) self . _function_add_return_site ( addr , current_func_addr ) else : # the procedure does not return self . _updated_nonreturning_functions . add ( current_func_addr ) return entries