diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/binaryview.py | 2 | ||||
| -rw-r--r-- | python/callingconvention.py | 16 | ||||
| -rw-r--r-- | python/downloadprovider.py | 2 | ||||
| -rw-r--r-- | python/function.py | 14 | ||||
| -rw-r--r-- | python/highlevelil.py | 2 | ||||
| -rw-r--r-- | python/lowlevelil.py | 18 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 16 | ||||
| -rw-r--r-- | python/variable.py | 292 |
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): |
