[docs]classCFGSliceToSink:""" The representation of a slice of a CFG. """
[docs]def__init__(self,target,transitions=None):""" :param angr.knowledge_plugins.functions.function.Function target: The targeted sink, to which every path in the slice leads. :param Dict[int,List[int]] transitions: A mapping representing transitions in the graph. Indexes are source addresses and values a list of destination addresses, for which there exists a transition in the slice from source to destination. """self._target=targetself._transitions=transitionsor{}
@propertydeftransitions(self):""" :return Dict[int,List[int]]: The transitions in the slice. """returnself._transitions@propertydeftransitions_as_tuples(self):""" :return List[Tuple[int,int]]: The list of transitions as pairs of (source, destination). """returnreduce(lambdaacc,source:acc+[(source,destination)fordestinationinself._transitions[source]],self._transitions.keys(),[],)@propertydeftarget(self):""" :return angr.knowledge_plugins.functions.function.Function: The targeted sink function, from which the slice is constructed. """returnself._target@propertydef_origins(self):returnset(self._transitions.keys())@propertydef_destinations(self):returnset(reduce(lambdaacc,destinations:acc+destinations,self._transitions.values(),[]))@propertydefnodes(self)->List[int]:""" :return: The complete list of addresses present in the slice. """returnlist(self._origins|self._destinations)@propertydefentrypoints(self):""" Entrypoints are all source addresses that are not the destination address of any transition. :return List[int]: The list of entrypoints addresses. """returnsorted(list(self._origins-self._destinations))
[docs]defadd_transitions(self,transitions):""" Add the given transitions to the current slice. :param Dict[int,List[int]] transitions: The list of transitions to be added to `self.transitions`. :return Dict[int,List[int]]: Return the updated list of transitions. """self._transitions=merge_transitions(transitions,self._transitions)returnself._transitions
[docs]defis_empty(self):""" Test if a given slice does not contain any transition. :return bool: True if the <CFGSliceToSink> instance does not contain any transitions. False otherwise. """returnnotbool(self._transitions)
[docs]defpath_between(self,source:int,destination:int,visited:Optional[Set[Any]]=None)->bool:""" Check the existence of a path in the slice between two given node adresses. :param source: The source address. :param destination: The destination address. :param visited: Used to avoid infinite recursion if loops are present in the slice. :return: True if there is a path between the source and the destination in the CFG, False if not, or if we have been unable to decide (because of loops). """_visited=set()ifvisitedisNoneelsevisitedifsourcenotinself._transitionsorsourcein_visited:returnFalse_visited.add(source)direct_successors=self._transitions[source]ifdestinationindirect_successors:returnTrueelse:returnany(map(lambdas:self.path_between(s,destination,_visited),direct_successors))