Source code for angr.codenode

import logging
from typing import List

l = logging.getLogger(name=__name__)


[docs]def repr_addr(addr): if isinstance(addr, int): return hex(addr) return repr(addr)
[docs]class CodeNode: __slots__ = ["addr", "size", "_graph", "thumb", "_hash"]
[docs] def __init__(self, addr, size, graph=None, thumb=False): self.addr = addr self.size = size self.thumb = thumb self._graph = graph self._hash = None
def __len__(self): return self.size def __eq__(self, other): if type(other) is Block: # pylint: disable=unidiomatic-typecheck raise TypeError("You do not want to be comparing a CodeNode to a Block") return ( type(self) is type(other) and self.addr == other.addr and self.size == other.size and self.is_hook == other.is_hook and self.thumb == other.thumb ) def __ne__(self, other): return not self == other def __cmp__(self, other): raise TypeError("Comparison with a code node") def __hash__(self): if self._hash is None: self._hash = hash((self.addr, self.size)) return self._hash
[docs] def successors(self) -> List["CodeNode"]: if self._graph is None: raise ValueError("Cannot calculate successors for graphless node") return list(self._graph.successors(self))
[docs] def predecessors(self): if self._graph is None: raise ValueError("Cannot calculate predecessors for graphless node") return list(self._graph.predecessors(self))
def __getstate__(self): return (self.addr, self.size) def __setstate__(self, dat): self.__init__(*dat) is_hook = None
[docs]class BlockNode(CodeNode): __slots__ = ["bytestr"] is_hook = False
[docs] def __init__(self, addr, size, bytestr=None, **kwargs): super().__init__(addr, size, **kwargs) self.bytestr = bytestr
def __repr__(self): return "<BlockNode at %s (size %d)>" % (repr_addr(self.addr), self.size) def __getstate__(self): return (self.addr, self.size, self.bytestr, self.thumb) def __setstate__(self, dat): self.__init__(*dat[:-1], thumb=dat[-1])
[docs]class SootBlockNode(BlockNode): __slots__ = ["stmts"]
[docs] def __init__(self, addr, size, stmts, **kwargs): super().__init__(addr, size, **kwargs) self.stmts = stmts assert (stmts is None and size == 0) or (size == len(stmts))
def __repr__(self): return "<SootBlockNode at %s (%d statements)>" % (repr_addr(self.addr), self.size) def __getstate__(self): return self.addr, self.size, self.stmts def __setstate__(self, data): self.__init__(*data)
[docs]class HookNode(CodeNode): __slots__ = ["sim_procedure"] is_hook = True
[docs] def __init__(self, addr, size, sim_procedure, **kwargs): """ :param type sim_procedure: the the sim_procedure class """ super().__init__(addr, size, **kwargs) self.sim_procedure = sim_procedure
def __repr__(self): return f"<HookNode {self.sim_procedure!r} at {repr_addr(self.addr)} (size {self.size})>" def __hash__(self): return hash((self.addr, self.size, self.sim_procedure)) def __eq__(self, other): return super().__eq__(other) and self.sim_procedure == other.sim_procedure def __getstate__(self): return (self.addr, self.size, self.sim_procedure) def __setstate__(self, dat): self.__init__(*dat)
[docs]class SyscallNode(HookNode): is_hook = False def __repr__(self): return f"<SyscallNode {self.sim_procedure!r} at {self.addr:#x} (size {self.size})>"
from .block import Block