Source code for angr.analyses.data_dep.dep_nodes

from typing import Optional, Tuple, TYPE_CHECKING

if TYPE_CHECKING:
    from claripy.ast.bv import BV
    from angr.state_plugins import SimActionData


[docs]class DepNodeTypes: """ Enumeration of types of BaseDepNode supported by this analysis """ Memory = 1 Register = 2 Tmp = 3 Constant = 4
[docs]class BaseDepNode: """ Base class for all nodes in a data-dependency graph """
[docs] def __init__(self, type_: int, sim_act: "SimActionData"): self._type = type_ self._sim_act = sim_act self.ins_addr = sim_act.ins_addr self.stmt_idx = sim_act.stmt_idx self.action_id: int = sim_act.id self.value: Optional[int] = None self._value_ast: Optional["BV"] = None
[docs] def value_tuple(self) -> Tuple["BV", int]: """ :return: A tuple containing the node's value as a BV and as an evaluated integer """ return self.ast, self.value
@property def ast(self) -> "BV": return self._value_ast @ast.setter def ast(self, new_ast: "BV"): self._value_ast = new_ast @property def type(self) -> int: """ Getter :return: An integer defined in DepNodeTypes, represents the subclass type of this DepNode. """ return self._type def __repr__(self): raise NotImplementedError() def __eq__(self, other): return self.type == other.type and self.ins_addr == other.ins_addr and self.action_id == other.action_id def __hash__(self): return hash(self.type) ^ hash(self.ins_addr) ^ hash(self.stmt_idx) ^ hash(self.action_id)
[docs]class ConstantDepNode(BaseDepNode): """ Used to create a DepNode that will hold a constant, numeric value Uniquely identified by its value """
[docs] def __init__(self, sim_act: "SimActionData", value: int): super().__init__(DepNodeTypes.Constant, sim_act) self.value = value
def __str__(self): return f"Constant {hex(self.value)}" def __repr__(self): return f"Constant{hex(self.value)}" def __eq__(self, other): return self.value == other.value def __hash__(self): return hash(self.value)
[docs]class MemDepNode(BaseDepNode): """ Used to represent SimActions of type MEM """
[docs] def __init__(self, sim_act: "SimActionData", addr: int): super().__init__(DepNodeTypes.Memory, sim_act) self.addr = addr
@property def width(self) -> int: return self._sim_act.size.ast // 8 def __str__(self): return hex(self.addr) def __repr__(self): val_str = "None" if self.value is None else hex(self.value) return f"{hex(self.addr)}\n{hex(self.ins_addr)}:{self.stmt_idx}\n{val_str}" def __eq__(self, other): return super().__eq__(other) and self.addr == other.addr def __hash__(self): return super().__hash__() ^ hash(self.addr)
[docs] @classmethod def cast_to_mem(cls, base_dep_node: BaseDepNode): """Casts a BaseDepNode into a MemDepNode""" assert isinstance(base_dep_node, BaseDepNode) base_dep_node.__class__ = cls assert isinstance(base_dep_node, MemDepNode) return base_dep_node
[docs]class VarDepNode(BaseDepNode): """ Abstract class for representing SimActions of TYPE reg or tmp """
[docs] def __init__(self, type_: int, sim_act: "SimActionData", reg: int, arch_name: str = ""): super().__init__(type_, sim_act) self.reg = reg self.arch_name = arch_name
@property def display_name(self) -> str: return self.arch_name if self.arch_name else hex(self.reg) def __str__(self): return self.display_name def __repr__(self): val_str = "None" if self.value is None else hex(self.value) return f"{self.display_name}@{hex(self.ins_addr)}:{self.stmt_idx}\n{val_str}" def __eq__(self, other): return super().__eq__(other) and self.reg == other.reg def __hash__(self): return super().__hash__() ^ hash(self.reg)
[docs]class TmpDepNode(VarDepNode): """ Used to represent SimActions of type TMP """
[docs] def __init__(self, sim_act: "SimActionData", reg: int, arch_name: str = ""): super().__init__(DepNodeTypes.Tmp, sim_act, reg, arch_name)
[docs]class RegDepNode(VarDepNode): """ Base class for representing SimActions of TYPE reg """
[docs] def __init__(self, sim_act: "SimActionData", reg: int, arch_name: str = ""): super().__init__(DepNodeTypes.Register, sim_act, reg, arch_name)
@property def reg_size(self) -> int: return self._sim_act.size.ast // 8