summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/binaryview.py2
-rw-r--r--python/callingconvention.py16
-rw-r--r--python/downloadprovider.py2
-rw-r--r--python/function.py14
-rw-r--r--python/highlevelil.py2
-rw-r--r--python/lowlevelil.py18
-rw-r--r--python/mediumlevelil.py16
-rw-r--r--python/variable.py292
8 files changed, 153 insertions, 209 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index 93230056..4266e8a5 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -2074,7 +2074,7 @@ class BinaryView(object):
def global_pointer_value(self):
"""Discovered value of the global pointer register, if the binary uses one (read-only)"""
result = core.BNGetGlobalPointerValue(self.handle)
- return variable.RegisterValue(self.arch, result.value, confidence = result.confidence)
+ return variable.RegisterValue.from_BNRegisterValue(result, self.arch)
@property
def parameters_for_analysis(self):
diff --git a/python/callingconvention.py b/python/callingconvention.py
index 44573503..60aa3f84 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -351,7 +351,7 @@ class CallingConvention(object):
api_obj = self.perform_get_incoming_reg_value(reg_name, func_obj)._to_api_object()
except:
log.log_error(traceback.format_exc())
- api_obj = variable.RegisterValue()._to_api_object()
+ api_obj = variable.Undetermined()._to_api_object()
result[0].state = api_obj.state
result[0].value = api_obj.value
@@ -362,7 +362,7 @@ class CallingConvention(object):
api_obj = self.perform_get_incoming_flag_value(reg_name, func_obj)._to_api_object()
except:
log.log_error(traceback.format_exc())
- api_obj = variable.RegisterValue()._to_api_object()
+ api_obj = variable.Undetermined()._to_api_object()
result[0].state = api_obj.state
result[0].value = api_obj.value
@@ -400,12 +400,12 @@ class CallingConvention(object):
result[0].index = in_var[0].index
result[0].storage = in_var[0].storage
- def perform_get_incoming_reg_value(self, reg, func):
+ def perform_get_incoming_reg_value(self, reg:'architecture.RegisterName', func:'function.Function'):
reg_stack = self.arch.get_reg_stack_for_reg(reg)
if reg_stack is not None:
if reg == self.arch.reg_stacks[reg_stack].stack_top_reg:
- return variable.RegisterValue.constant(0)
- return variable.RegisterValue()
+ return variable.ConstantRegisterValue(0)
+ return variable.Undetermined()
def perform_get_incoming_flag_value(self, reg, func):
return variable.Undetermined()
@@ -424,19 +424,19 @@ class CallingConvention(object):
return CallingConvention(self.arch, handle = core.BNNewCallingConventionReference(self.handle),
confidence = confidence)
- def get_incoming_reg_value(self, reg, func):
+ def get_incoming_reg_value(self, reg:'architecture.RegisterType', func):
reg_num = self.arch.get_reg_index(reg)
func_handle = None
if func is not None:
func_handle = func.handle
- return variable.RegisterValue(self.arch, core.BNGetIncomingRegisterValue(self.handle, reg_num, func_handle))
+ return variable.RegisterValue.from_BNRegisterValue(core.BNGetIncomingRegisterValue(self.handle, reg_num, func_handle), self.arch)
def get_incoming_flag_value(self, flag, func):
reg_num = self.arch.get_flag_index(flag)
func_handle = None
if func is not None:
func_handle = func.handle
- return variable.RegisterValue(self.arch, core.BNGetIncomingFlagValue(self.handle, reg_num, func_handle))
+ return variable.RegisterValue.from_BNRegisterValue(core.BNGetIncomingFlagValue(self.handle, reg_num, func_handle), self.arch)
def get_incoming_var_for_parameter_var(self, in_var:'variable.CoreVariable', func:'function.Function'):
in_buf = in_var.to_BNVariable()
diff --git a/python/downloadprovider.py b/python/downloadprovider.py
index e5f3cb3c..3104b08d 100644
--- a/python/downloadprovider.py
+++ b/python/downloadprovider.py
@@ -397,7 +397,7 @@ try:
if b"Content-Length" in headers:
del headers[b"Content-Length"]
- r = requests.request(pyNativeStr(method), pyNativeStr(url), headers=headers, data=data_generator, proxies=proxies, stream=True)
+ r = requests.request(method.decode('utf8'), url.decode('utf8'), headers=headers, data=data_generator, proxies=proxies, stream=True)
total_size = 0
for (key, value) in r.headers.items():
diff --git a/python/function.py b/python/function.py
index 64d54327..68e9ceda 100644
--- a/python/function.py
+++ b/python/function.py
@@ -1155,7 +1155,7 @@ class Function(object):
def global_pointer_value(self) -> variable.RegisterValue:
"""Discovered value of the global pointer register, if the function uses one (read-only)"""
result = core.BNGetFunctionGlobalPointerValue(self.handle)
- return variable.RegisterValue(self.arch, result.value, confidence = result.confidence)
+ return variable.RegisterValue.from_BNRegisterValue(result, self.arch)
@property
def comment(self) -> str:
@@ -1525,7 +1525,7 @@ class Function(object):
arch = self.arch
reg = arch.get_reg_index(reg)
value = core.BNGetRegisterValueAtInstruction(self.handle, arch.handle, addr, reg)
- result = variable.RegisterValue(arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, arch)
return result
@property
@@ -1590,7 +1590,7 @@ class Function(object):
arch = self.arch
reg = arch.get_reg_index(reg)
value = core.BNGetRegisterValueAfterInstruction(self.handle, arch.handle, addr, reg)
- result = variable.RegisterValue(arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, arch)
return result
def get_auto_address_tags_at(self, addr, arch=None):
@@ -1819,7 +1819,7 @@ class Function(object):
raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
arch = self.arch
value = core.BNGetStackContentsAtInstruction(self.handle, arch.handle, addr, offset, size)
- result = variable.RegisterValue(arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, arch)
return result
def get_stack_contents_after(self, addr:int, offset:int, size:int,
@@ -1829,7 +1829,7 @@ class Function(object):
raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
arch = self.arch
value = core.BNGetStackContentsAfterInstruction(self.handle, arch.handle, addr, offset, size)
- result = variable.RegisterValue(arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, arch)
return result
def get_parameter_at(self, addr:int, func_type:Optional['types.Type'], i:int,
@@ -1843,7 +1843,7 @@ class Function(object):
if func_type is not None:
_func_type = func_type.handle
value = core.BNGetParameterValueAtInstruction(self.handle, arch.handle, addr, _func_type, i)
- result = variable.RegisterValue(arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, arch)
return result
def remove_user_address_tags_of_type(self, addr, tag_type, arch=None):
@@ -1868,7 +1868,7 @@ class Function(object):
if func_type is not None:
_func_type = func_type.handle
value = core.BNGetParameterValueAtLowLevelILInstruction(self.handle, instr, _func_type, i)
- result = variable.RegisterValue(self.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self.arch)
return result
def get_regs_read_by(self, addr:int, arch:Optional['architecture.Architecture']=None) -> List['architecture.RegisterName']:
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 831d232d..26ad5045 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -590,7 +590,7 @@ class HighLevelILInstruction(object):
"""Value of expression if constant or a known value (read-only)"""
mlil = self.mlil
if mlil is None:
- return variable.RegisterValue()
+ return variable.Undetermined()
return mlil.value
@property
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 3cde2135..483f88e5 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -954,7 +954,7 @@ class LowLevelILInstruction(object):
def value(self) -> 'variable.RegisterValue':
"""Value of expression if constant or a known value (read-only)"""
value = core.BNGetLowLevelILExprValue(self._function.handle, self.expr_index)
- return variable.RegisterValue(self._function.arch, value)
+ return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
@property
def possible_values(self) -> 'variable.PossibleValueSet':
@@ -1005,14 +1005,14 @@ class LowLevelILInstruction(object):
raise Exception("Can not call get_reg_value on function with Architecture set to None")
reg = self._function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAtInstruction(self._function.handle, reg, self._instr_index)
- return variable.RegisterValue(self._function.arch, value)
+ return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
def get_reg_value_after(self, reg:'architecture.RegisterType') -> variable.RegisterValue:
if self._function.arch is None:
raise Exception("Can not call get_reg_value_after on function with Architecture set to None")
reg = self._function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAfterInstruction(self._function.handle, reg, self._instr_index)
- return variable.RegisterValue(self._function.arch, value)
+ return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
def get_possible_reg_values(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
if self._function.arch is None:
@@ -1049,7 +1049,7 @@ class LowLevelILInstruction(object):
raise Exception("Can not call get_flag_value on function with Architecture set to None")
flag = self._function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAtInstruction(self._function.handle, flag, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_flag_value_after(self, flag:'architecture.FlagType') -> 'variable.RegisterValue':
@@ -1057,7 +1057,7 @@ class LowLevelILInstruction(object):
raise Exception("Can not call get_flag_value_after on function with Architecture set to None")
flag = self._function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAfterInstruction(self._function.handle, flag, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_possible_flag_values(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
@@ -1092,12 +1092,12 @@ class LowLevelILInstruction(object):
def get_stack_contents(self, offset:int, size:int) -> 'variable.RegisterValue':
value = core.BNGetLowLevelILStackContentsAtInstruction(self._function.handle, offset, size, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_stack_contents_after(self, offset:int, size:int) -> 'variable.RegisterValue':
value = core.BNGetLowLevelILStackContentsAfterInstruction(self._function.handle, offset, size, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_possible_stack_contents(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet:
@@ -3076,13 +3076,13 @@ class LowLevelILFunction(object):
def get_ssa_reg_value(self, reg_ssa:SSARegister) -> 'variable.RegisterValue':
reg = self.arch.get_reg_index(reg_ssa.reg)
value = core.BNGetLowLevelILSSARegisterValue(self.handle, reg, reg_ssa.version)
- result = variable.RegisterValue(self._arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._arch)
return result
def get_ssa_flag_value(self, flag_ssa:SSAFlag) -> 'variable.RegisterValue':
flag = self.arch.get_flag_index(flag_ssa.flag)
value = core.BNGetLowLevelILSSAFlagValue(self.handle, flag, flag_ssa.version)
- result = variable.RegisterValue(self._arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._arch)
return result
def get_medium_level_il_instruction_index(self, instr:InstructionIndex) -> Optional['mediumlevelil.InstructionIndex']:
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 53b5619e..61cc420f 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -454,7 +454,7 @@ class MediumLevelILInstruction(object):
def value(self) -> variable.RegisterValue:
"""Value of expression if constant or a known value (read-only)"""
value = core.BNGetMediumLevelILExprValue(self._function.handle, self._expr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
@property
@@ -662,13 +662,13 @@ class MediumLevelILInstruction(object):
def get_reg_value(self, reg:'architecture.RegisterType') -> 'variable.RegisterValue':
reg = self._function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAtInstruction(self._function.handle, reg, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_reg_value_after(self, reg:'architecture.RegisterType') -> 'variable.RegisterValue':
reg = self._function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self._function.handle, reg, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_possible_reg_values(self, reg:'architecture.RegisterType',
@@ -702,13 +702,13 @@ class MediumLevelILInstruction(object):
def get_flag_value(self, flag:'architecture.FlagType') -> 'variable.RegisterValue':
flag = self._function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAtInstruction(self._function.handle, flag, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_flag_value_after(self, flag:'architecture.FlagType') -> 'variable.RegisterValue':
flag = self._function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAfterInstruction(self._function.handle, flag, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_possible_flag_values(self, flag:'architecture.FlagType',
@@ -741,12 +741,12 @@ class MediumLevelILInstruction(object):
def get_stack_contents(self, offset:int, size:int) -> 'variable.RegisterValue':
value = core.BNGetMediumLevelILStackContentsAtInstruction(self._function.handle, offset, size, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_stack_contents_after(self, offset:int, size:int) -> 'variable.RegisterValue':
value = core.BNGetMediumLevelILStackContentsAfterInstruction(self._function.handle, offset, size, self._instr_index)
- result = variable.RegisterValue(self._function.arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch)
return result
def get_possible_stack_contents(self, offset:int, size:int,
@@ -1185,7 +1185,7 @@ class MediumLevelILFunction(object):
def get_ssa_var_value(self, ssa_var:SSAVariable) -> 'variable.RegisterValue':
var_data = ssa_var.var.to_BNVariable()
value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, ssa_var.version)
- result = variable.RegisterValue(self._arch, value)
+ result = variable.RegisterValue.from_BNRegisterValue(value, self._arch)
return result
def get_low_level_il_instruction_index(self, instr:InstructionIndex) -> Optional['lowlevelil.InstructionIndex']:
diff --git a/python/variable.py b/python/variable.py
index 011402d8..0b793c15 100644
--- a/python/variable.py
+++ b/python/variable.py
@@ -21,217 +21,161 @@
import ctypes
from typing import List, Generator, Optional, Union, Set, Mapping
+from dataclasses import dataclass
import binaryninja
from . import _binaryninjacore as core
from . import decorators
from .enums import RegisterValueType, VariableSourceType, DeadStoreElimination
-
-@decorators.passive
+@dataclass(frozen=True)
class LookupTableEntry(object):
- def __init__(self, from_values:List[int], to_value):
- self._from_values = from_values
- self._to_value = to_value
+ from_values:List[int]
+ to_value:int
def __repr__(self):
return f"[{', '.join([f'{i:#x}' for i in self.from_values])}] -> {self.to_value:#x}"
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return (self._from_values, self._to_value) == (other._from_values, other._to_value)
+ def type(self):
+ return RegisterValueType.LookupTableValue
- def __ne__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return not (self == other)
+@dataclass(frozen=True)
+class Confidence:
+ confidence:int=core.max_confidence
- def __hash__(self):
- return hash((self._from_values, self._to_value))
+@dataclass(frozen=True)
+class RegisterValue:
+ value:int
+ offset:int
+ type:RegisterValueType = RegisterValueType.UndeterminedValue
+ confidence:int=core.max_confidence
- @property
- def from_values(self):
- return self._from_values
+ def _to_api_object(self):
+ result = core.BNRegisterValue()
+ result.type = self.type
+ result._value = self.value
+ result.offset = self.offset
+ return result
- @property
- def to_value(self):
- return self._to_value
+ def _to_api_object_with_confidence(self):
+ result = core.BNRegisterValue()
+ result.type = self.type
+ result._value = self.value
+ result.offset = self.offset
+ result.confidence = self.confidence
+ return result
+ def __bool__(self):
+ return self.value != 0
-@decorators.passive
-class RegisterValue(object):
- def __init__(self, arch:Optional['binaryninja.architecture.Architecture']=None,
- value:core.BNRegisterValue=None, confidence:int=core.max_confidence):
- self._is_constant = False
- self._value = None
- self._arch = None
- # self._reg:Optional[Union[binaryninja.architecture.RegisterName, binaryninja.architecture.RegisterIndex]] = None
- self._is_constant = False
- self._offset = None
- if value is None:
- self._type = RegisterValueType.UndeterminedValue
- else:
- assert isinstance(value.value, int), "BNRegisterValue.value isn't an integer"
- self._type = RegisterValueType(value.state)
- if value.state == RegisterValueType.EntryValue:
- self._arch = arch
- if arch is not None:
- self._value = arch.get_reg_name(binaryninja.architecture.RegisterIndex(value.value))
- else:
- self._value = value.value
- elif (value.state == RegisterValueType.ConstantValue) or (value.state == RegisterValueType.ConstantPointerValue):
- self._value = value.value
- self._is_constant = True
- elif value.state == RegisterValueType.StackFrameOffset:
- self._offset = value.value
- elif value.state == RegisterValueType.ImportedAddressValue:
- self._value = value.value
- self._confidence = confidence
+ def __int__(self):
+ return self.value
- def __repr__(self):
- if self._type == RegisterValueType.EntryValue:
- return f"<entry {self._value:s}>"
- if self._type == RegisterValueType.ConstantValue:
- return f"<const {self._value:#x}>"
- if self._type == RegisterValueType.ConstantPointerValue:
- return f"<const ptr {self._value:#x}>"
- if self._type == RegisterValueType.StackFrameOffset:
- return f"<stack frame offset {self._offset:#x}>"
- if self._type == RegisterValueType.ReturnAddressValue:
- return "<return address>"
- if self._type == RegisterValueType.ImportedAddressValue:
- return f"<imported address from entry {self._value:#x}>"
- return "<undetermined>"
+ def __eq__(self, other):
+ if isinstance(other, int):
+ return int(self) == other
+ elif isinstance(other, bool):
+ return bool(self) == other
+ elif isinstance(other, self.__class__):
+ return (self.type, self.offset, self.type, self.confidence) == \
+ (other.type, other.offset, other.type, other.confidence)
+ assert False, f"no comparison for types {repr(self)} and {repr(other)}"
- def __hash__(self):
- if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue, RegisterValueType.EntryValue]:
- return hash(self._value)
- elif self._type == RegisterValueType.StackFrameOffset:
- return hash(self._offset)
+ @classmethod
+ def from_BNRegisterValue(cls, reg_value:Union[core.BNRegisterValue, core.BNRegisterValueWithConfidence],
+ arch:Optional['binaryninja.architecture.Architecture']=None) -> 'RegisterValue':
+ confidence = core.max_confidence
+ if isinstance(reg_value, core.BNRegisterValueWithConfidence):
+ confidence = reg_value.confidence
+ if reg_value.state == RegisterValueType.EntryValue:
+ reg = None
+ if arch is not None:
+ reg = arch.get_reg_name(binaryninja.architecture.RegisterIndex(reg_value.value))
+ return EntryRegisterValue(reg_value.value, reg=reg, confidence=confidence)
+ elif reg_value.state == RegisterValueType.ConstantValue:
+ return ConstantRegisterValue(reg_value.value, confidence=confidence)
+ elif reg_value.state == RegisterValueType.ConstantValue:
+ return ConstantPointerRegisterValue(reg_value.value, confidence=confidence)
+ elif reg_value.state == RegisterValueType.StackFrameOffset:
+ return StackFrameOffsetRegisterValue(reg_value.value, reg_value.offset, confidence=confidence)
+ elif reg_value.state == RegisterValueType.ImportedAddressValue:
+ return ImportedAddressRegisterValue(reg_value.value, confidence=confidence)
+ elif reg_value.state == RegisterValueType.UndeterminedValue:
+ return Undetermined()
+ assert False, f"RegisterValueType {reg_value.state} not handled"
- def __eq__(self, other):
- if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and isinstance(other, int):
- return self._value == other
- elif self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and hasattr(other, 'type') and other.type == self._type:
- return self._value == other.value
- elif self._type == RegisterValueType.EntryValue and hasattr(other, "type") and other.type == self._type:
- return self._value == other.reg
- elif self._type == RegisterValueType.StackFrameOffset and hasattr(other, 'type') and other.type == self._type:
- return self._offset == other.offset
- elif self._type == RegisterValueType.StackFrameOffset and isinstance(other, int):
- return self._offset == other
- return NotImplemented
- def __ne__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return not (self == other)
+@dataclass(frozen=True, eq=False)
+class Undetermined(RegisterValue):
+ value:int = 0
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.UndeterminedValue
- def _to_api_object(self):
- result = core.BNRegisterValue()
- result.type = self._type
- result._value = 0
- if self._type == RegisterValueType.EntryValue:
- if isinstance(self._value, binaryninja.architecture.RegisterName):
- if self._arch is None:
- raise Exception("Can not convert Variable to API object without an Architecture set")
- result._value = self._arch.get_reg_index(self._value)
- else:
- result._value = self._value
- elif (self._type == RegisterValueType.ConstantValue) or (self._type == RegisterValueType.ConstantPointerValue):
- result._value = self._value
- elif self._type == RegisterValueType.StackFrameOffset:
- result._value = self._offset
- elif self._type == RegisterValueType.ImportedAddressValue:
- result._value = self._value
- return result
- @classmethod
- def undetermined(cls):
- return RegisterValue()
+@dataclass(frozen=True, eq=False)
+class ConstantRegisterValue(RegisterValue):
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.ConstantValue
- @classmethod
- def entry_value(cls, arch:'binaryninja.architecture.Architecture', reg:'binaryninja.architecture.RegisterName') -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.EntryValue
- result._arch = arch
- result._value = reg
- return result
+ def __repr__(self):
+ return f"<const {self.value:#x}>"
- @staticmethod
- def constant(value:int) -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.ConstantValue
- result._value = value
- result._is_constant = True
- return result
- @staticmethod
- def constant_ptr(value:int) -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.ConstantPointerValue
- result._value = value
- result._is_constant = True
- return result
+@dataclass(frozen=True, eq=False)
+class ConstantPointerRegisterValue(RegisterValue):
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.ConstantPointerValue
- @staticmethod
- def stack_frame_offset(offset:int) -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.StackFrameOffset
- result._offset = offset
- return result
+ def __repr__(self):
+ return f"<const ptr {self.value:#x}>"
- @staticmethod
- def imported_address(value) -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.ImportedAddressValue
- result._value = value
- return result
- @staticmethod
- def return_address() -> 'RegisterValue':
- result = RegisterValue()
- result._type = RegisterValueType.ReturnAddressValue
- return result
+@dataclass(frozen=True, eq=False)
+class ImportedAddressRegisterValue(RegisterValue):
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.ImportedAddressValue
- @property
- def is_constant(self) -> bool:
- """Boolean for whether the RegisterValue is known to be constant (read-only)"""
- return self._is_constant
+ def __repr__(self):
+ return f"<imported address from entry {self.value:#x}>"
- @property
- def type(self) -> RegisterValueType:
- """:class:`~enums.RegisterValueType` (read-only)"""
- return self._type
- @property
- def arch(self) -> Optional['binaryninja.architecture.Architecture']:
- """Architecture where it exists, None otherwise (read-only)"""
- return self._arch
+@dataclass(frozen=True, eq=False)
+class ReturnAddressRegisterValue(RegisterValue):
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.ReturnAddressValue
- @property
- def reg(self) -> 'binaryninja.architecture.RegisterName':
- """Register Name where the Architecture exists raises exception otherwise (read-only)"""
- if not isinstance(self._value, binaryninja.architecture.RegisterName):
- raise Exception("Attempting to access register when property doesn't exist")
- return self._value
+ def __repr__(self):
+ return "<return address>"
- @property
- def value(self) -> Optional[Union[int, 'binaryninja.architecture.RegisterName']]:
- """Value where it exists, None otherwise (read-only)"""
- return self._value
- @property
- def offset(self) -> Optional[int]:
- """Offset where it exists, None otherwise (read-only)"""
- return self._offset
+@dataclass(frozen=True, eq=False)
+class EntryRegisterValue(RegisterValue):
+ value:int = 0
+ offset:int = 0
+ type:RegisterValueType = RegisterValueType.EntryValue
+ reg:Optional['binaryninja.architecture.RegisterName'] = None
+
+ def __repr__(self):
+ return f"<entry {self.value}>"
+
+ @classmethod
+ def from_BNRegisterValue(cls, value:core.BNRegisterValue):
+ cls(value.state, value.value, value.offset)
- @property
- def confidence(self) -> Optional[int]:
- """Confidence where it exists, None otherwise (read-only)"""
- return self._confidence
+@dataclass(frozen=True, eq=False)
+class StackFrameOffsetRegisterValue(RegisterValue):
+ type:RegisterValueType = RegisterValueType.StackFrameOffset
+
+ def __repr__(self):
+ return f"<stack frame offset {self.offset:#x}>"
+
+@dataclass(frozen=True, eq=False)
+class ExternalPointerRegisterValue(RegisterValue):
+ type:RegisterValueType = RegisterValueType.ExternalPointerValue
+
+ def __repr__(self):
+ return f"<external {self.value:#x} + offset {self.offset:#x}>"
@decorators.passive
class ValueRange(object):