(self, target_node)
return new_taints
Based on control dependence graph, pick all exits (statements) that lead to the target.

        :param target_node: A CFGNode instance.
        :returns:           A set of new tainted code locations.
Based on control dependence graph, pick all exits (statements) that lead to the target.
Based on control dependence graph pick all exits ( statements ) that lead to the target .
def _handle_control_dependence(self, target_node):
        """
        Based on control dependence graph, pick all exits (statements) that lead to the target.

        :param target_node: A CFGNode instance.
        :returns:           A set of new tainted code locations.
        """

        new_taints = set()

        # Query the CDG and figure out all control flow transitions to reach this target
        cdg_guardians = self._cdg.get_guardians(target_node)
        if not cdg_guardians:
            # this block is directly reachable from the entry point
            pass

        else:
            # For each predecessor on CDG, find the correct exit to take, and continue slicing from those exits
            for predecessor in cdg_guardians:
                exits = self._find_exits(predecessor, target_node)

                for stmt_idx, target_addresses in exits.items():
                    if stmt_idx is not None:
                        # If it's an exit statement, mark it as picked
                        self._pick_statement(predecessor.addr,
                                             self._normalize_stmt_idx(predecessor.addr, stmt_idx)
                                             )
                        # If it's the default statement, we should also pick other conditional exit statements
                        if stmt_idx == DEFAULT_STATEMENT:
                            conditional_exits = self._conditional_exits(predecessor.addr)
                            for conditional_exit_stmt_id in conditional_exits:
                                cl = CodeLocation(predecessor.addr,
                                                  self._normalize_stmt_idx(predecessor.addr, conditional_exit_stmt_id)
                                                  )
                                new_taints.add(cl)

                                self._pick_statement(predecessor.addr,
                                                     self._normalize_stmt_idx(predecessor.addr, conditional_exit_stmt_id)
                                                     )

                    if target_addresses is not None:

                        if stmt_idx is not None:
                            # If it's an exit statement, we create a new tainted code location
                            cl = CodeLocation(predecessor.addr,
                                              self._normalize_stmt_idx(predecessor.addr, stmt_idx)
                                              )
                            new_taints.add(cl)

                        # Mark those exits as picked
                        for target_address in target_addresses:
                            self._pick_exit(predecessor.addr, stmt_idx, target_address)

                    # On CFG, pick default exits of all nodes between predecessor and our target node
                    # Usually this is not required if basic blocks strictly end at control flow transitions. But this is
                    # not always the case for some architectures
                    all_simple_paths = list(networkx.all_simple_paths(self._cfg.graph, predecessor, target_node, cutoff=3))

                    previous_node = None
                    for path in all_simple_paths:
                        for node in path:
                            self._pick_statement(node.addr,
                                                 self._normalize_stmt_idx(node.addr, DEFAULT_STATEMENT))
                            if previous_node is not None:
                                self._pick_exit(previous_node.addr, DEFAULT_STATEMENT, node.addr)

        return new_taints
def _handle_control_dependence ( self , target_node ) : new_taints = set ( ) # Query the CDG and figure out all control flow transitions to reach this target cdg_guardians = self . _cdg . get_guardians ( target_node ) if not cdg_guardians : # this block is directly reachable from the entry point pass else : # For each predecessor on CDG, find the correct exit to take, and continue slicing from those exits for predecessor in cdg_guardians : exits = self . _find_exits ( predecessor , target_node ) for stmt_idx , target_addresses in exits . items ( ) : if stmt_idx is not None : # If it's an exit statement, mark it as picked self . _pick_statement ( predecessor . addr , self . _normalize_stmt_idx ( predecessor . addr , stmt_idx ) ) # If it's the default statement, we should also pick other conditional exit statements if stmt_idx == DEFAULT_STATEMENT : conditional_exits = self . _conditional_exits ( predecessor . addr ) for conditional_exit_stmt_id in conditional_exits : cl = CodeLocation ( predecessor . addr , self . _normalize_stmt_idx ( predecessor . addr , conditional_exit_stmt_id ) ) new_taints . add ( cl ) self . _pick_statement ( predecessor . addr , self . _normalize_stmt_idx ( predecessor . addr , conditional_exit_stmt_id ) ) if target_addresses is not None : if stmt_idx is not None : # If it's an exit statement, we create a new tainted code location cl = CodeLocation ( predecessor . addr , self . _normalize_stmt_idx ( predecessor . addr , stmt_idx ) ) new_taints . add ( cl ) # Mark those exits as picked for target_address in target_addresses : self . _pick_exit ( predecessor . addr , stmt_idx , target_address ) # On CFG, pick default exits of all nodes between predecessor and our target node # Usually this is not required if basic blocks strictly end at control flow transitions. But this is # not always the case for some architectures all_simple_paths = list ( networkx . all_simple_paths ( self . _cfg . graph , predecessor , target_node , cutoff = 3 ) ) previous_node = None for path in all_simple_paths : for node in path : self . _pick_statement ( node . addr , self . _normalize_stmt_idx ( node . addr , DEFAULT_STATEMENT ) ) if previous_node is not None : self . _pick_exit ( previous_node . addr , DEFAULT_STATEMENT , node . addr ) return new_taints