angr.knowledge_plugins.variables.variable_access 源代码

# pylint:disable=arguments-differ,no-member
from __future__ import annotations
from typing import TYPE_CHECKING

from angr.code_location import CodeLocation
from angr.serializable import Serializable
from angr.protos import variables_pb2

if TYPE_CHECKING:
    from angr.sim_variable import SimVariable


[文档] class VariableAccessSort: """ Provides enums for variable access types. """ WRITE = 0 READ = 1 REFERENCE = 2
[文档] class VariableAccess(Serializable): """ Describes a variable access. """ __slots__ = ( "access_type", "atom_hash", "location", "offset", "variable", )
[文档] def __init__(self, variable, access_type, location, offset, atom_hash=None): self.variable: SimVariable = variable self.access_type: int = access_type self.location: CodeLocation = location self.offset: int | None = offset self.atom_hash: int | None = atom_hash
def __repr__(self): access_type = { VariableAccessSort.WRITE: "write", VariableAccessSort.READ: "read", VariableAccessSort.REFERENCE: "reference", }[self.access_type] return f"{access_type} {self.variable} @ {self.location} (offset {self.offset})" def __eq__(self, other): return ( type(other) is VariableAccess and self.variable == other.variable and self.access_type == other.access_type and self.location == other.location and self.offset == other.offset ) def __hash__(self): return hash((VariableAccess, self.variable, self.access_type, self.location, self.offset)) @classmethod def _get_cmsg(cls): return variables_pb2.VariableAccess()
[文档] def serialize_to_cmessage(self): # pylint:disable=no-member cmsg = self._get_cmsg() cmsg.ident = self.variable.ident cmsg.block_addr = self.location.block_addr cmsg.stmt_idx = self.location.stmt_idx cmsg.ins_addr = self.location.ins_addr if self.offset is not None and isinstance(self.offset, int): cmsg.offset = self.offset if self.atom_hash is not None: cmsg.atom_hash = self.atom_hash if self.access_type == VariableAccessSort.READ: cmsg.access_type = variables_pb2.VariableAccess.READ elif self.access_type == VariableAccessSort.WRITE: cmsg.access_type = variables_pb2.VariableAccess.WRITE elif self.access_type == VariableAccessSort.REFERENCE: cmsg.access_type = variables_pb2.VariableAccess.REFERENCE else: raise NotImplementedError return cmsg
[文档] @classmethod def parse_from_cmessage( cls, cmsg, variable_by_ident: dict[str, SimVariable] | None = None, **kwargs ) -> VariableAccess: assert variable_by_ident is not None variable = variable_by_ident[cmsg.ident] location = CodeLocation(cmsg.block_addr, cmsg.stmt_idx, ins_addr=cmsg.ins_addr) if cmsg.access_type == variables_pb2.VariableAccess.READ: access_type = VariableAccessSort.READ elif cmsg.access_type == variables_pb2.VariableAccess.WRITE: access_type = VariableAccessSort.WRITE elif cmsg.access_type == variables_pb2.VariableAccess.REFERENCE: access_type = VariableAccessSort.REFERENCE else: raise NotImplementedError return VariableAccess( variable, access_type, location, cmsg.offset if cmsg.HasField("offset") else None, atom_hash=cmsg.atom_hash if cmsg.HasField("atom_hash") else None, )