(self, g, starts, callback, blockaddr_to_function, known_functions, traversed_cfg_nodes=None)
A customized control flow graph BFS implementation with the following rules:
        - Call edges are not followed.
        - Syscall edges are not followed.

        :param networkx.DiGraph g: The graph.
        :param list starts: A collection of beginning nodes to start graph traversal.
        :param func callback: Callback function for each edge and node.
        :param dict blockaddr_to_function: A mapping between block addresses to Function instances.
        :param angr.knowledge_plugins.FunctionManager known_functions: Already recovered functions.
        :param set traversed_cfg_nodes: A set of CFGNodes that are traversed before.
        :return: None
A customized control flow graph BFS implementation with the following rules:
        - Call edges are not followed.
        - Syscall edges are not followed.
A customized control flow graph BFS implementation with the following rules : - Call edges are not followed . - Syscall edges are not followed .
def _graph_bfs_custom(self, g, starts, callback, blockaddr_to_function, known_functions, traversed_cfg_nodes=None):
        """
        A customized control flow graph BFS implementation with the following rules:
        - Call edges are not followed.
        - Syscall edges are not followed.

        :param networkx.DiGraph g: The graph.
        :param list starts: A collection of beginning nodes to start graph traversal.
        :param func callback: Callback function for each edge and node.
        :param dict blockaddr_to_function: A mapping between block addresses to Function instances.
        :param angr.knowledge_plugins.FunctionManager known_functions: Already recovered functions.
        :param set traversed_cfg_nodes: A set of CFGNodes that are traversed before.
        :return: None
        """

        stack = OrderedSet(starts)
        traversed = set() if traversed_cfg_nodes is None else traversed_cfg_nodes

        while stack:
            n = stack.pop(last=False)  # type: CFGNode

            if n in traversed:
                continue

            traversed.add(n)

            if n.has_return:
                callback(g, n, None, {'jumpkind': 'Ijk_Ret'}, blockaddr_to_function, known_functions, None)
            # NOTE: A block that has_return CAN have successors that aren't the return.
            # This is particularly the case for ARM conditional instructions.  Yes, conditional rets are a thing.

            if g.out_degree(n) == 0:
                # it's a single node
                callback(g, n, None, None, blockaddr_to_function, known_functions, None)

            else:
                all_out_edges = g.out_edges(n, data=True)
                for src, dst, data in all_out_edges:
                    callback(g, src, dst, data, blockaddr_to_function, known_functions, all_out_edges)

                    jumpkind = data.get('jumpkind', "")
                    if not (jumpkind == 'Ijk_Call' or jumpkind.startswith('Ijk_Sys')):
                        # Only follow none call edges
                        if dst not in stack and dst not in traversed:
                            stack.add(dst)
def _graph_bfs_custom ( self , g , starts , callback , blockaddr_to_function , known_functions , traversed_cfg_nodes = None ) : stack = OrderedSet ( starts ) traversed = set ( ) if traversed_cfg_nodes is None else traversed_cfg_nodes while stack : n = stack . pop ( last = False ) # type: CFGNode if n in traversed : continue traversed . add ( n ) if n . has_return : callback ( g , n , None , { 'jumpkind' : 'Ijk_Ret' } , blockaddr_to_function , known_functions , None ) # NOTE: A block that has_return CAN have successors that aren't the return. # This is particularly the case for ARM conditional instructions.  Yes, conditional rets are a thing. if g . out_degree ( n ) == 0 : # it's a single node callback ( g , n , None , None , blockaddr_to_function , known_functions , None ) else : all_out_edges = g . out_edges ( n , data = True ) for src , dst , data in all_out_edges : callback ( g , src , dst , data , blockaddr_to_function , known_functions , all_out_edges ) jumpkind = data . get ( 'jumpkind' , "" ) if not ( jumpkind == 'Ijk_Call' or jumpkind . startswith ( 'Ijk_Sys' ) ) : # Only follow none call edges if dst not in stack and dst not in traversed : stack . add ( dst )