summaryrefslogtreecommitdiff
path: root/python/architecture.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/architecture.py')
-rw-r--r--python/architecture.py1452
1 files changed, 689 insertions, 763 deletions
diff --git a/python/architecture.py b/python/architecture.py
index 2206f50e..51b1ae00 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -20,66 +20,323 @@
import traceback
import ctypes
-import abc
+from typing import Generator, Union, List, Optional, Mapping, Tuple, NewType
# Binary Ninja components
-from binaryninja import _binaryninjacore as core
-from binaryninja.enums import (Endianness, ImplicitRegisterExtend, BranchType,
- InstructionTextTokenType, LowLevelILFlagCondition, FlagRole)
import binaryninja
-from binaryninja import log
-from binaryninja import lowlevelil
-from binaryninja import types
-from binaryninja import databuffer
-from binaryninja import platform
-from binaryninja import callingconvention
+from . import _binaryninjacore as core
+from .enums import (Endianness, ImplicitRegisterExtend, BranchType,
+ LowLevelILFlagCondition, FlagRole, LowLevelILOperation)
+from . import log
+from . import lowlevelil
+from . import types
+from . import databuffer
+from . import platform
+from . import callingconvention
+from . import typelibrary
+from . import function
+from . import binaryview
-# 2-3 compatibility
-from binaryninja import range
-from binaryninja import with_metaclass
-import numbers
+RegisterIndex = NewType('RegisterIndex', int)
+RegisterStackIndex = NewType('RegisterStackIndex', int)
+FlagIndex = NewType('FlagIndex', int)
+SemanticClassIndex = NewType('SemanticClassIndex', int)
+SemanticGroupIndex = NewType('SemanticGroupIndex', int)
+IntrinsicIndex = NewType('IntrinsicIndex', int)
+FlagWriteTypeIndex = NewType('FlagWriteTypeIndex', int)
+RegisterName = NewType('RegisterName', str)
+RegisterStackName = NewType('RegisterStackName', str)
+FlagName = NewType('FlagName', str)
+SemanticClassName = NewType('SemanticClassName', str)
+SemanticGroupName = NewType('SemanticGroupName', str)
+IntrinsicName = NewType('IntrinsicName', str)
+FlagWriteTypeName = NewType('FlagWriteTypeName', str)
-class _ArchitectureMetaClass(type):
+RegisterType = Union[RegisterName, 'lowlevelil.ILRegister', RegisterIndex]
+FlagType = Union[FlagName, 'lowlevelil.ILFlag', FlagIndex]
+RegisterStackType = Union[RegisterStackName, 'lowlevelil.ILRegisterStack', RegisterStackIndex]
+SemanticClassType = Union[SemanticClassName, 'lowlevelil.ILSemanticFlagClass', SemanticClassIndex]
+SemanticGroupType = Union[SemanticGroupName, 'lowlevelil.ILSemanticFlagGroup', SemanticGroupIndex]
+IntrinsicType = Union[IntrinsicName, 'lowlevelil.ILIntrinsic', IntrinsicIndex]
+
+
+
+class RegisterInfo(object):
+ def __init__(self, full_width_reg:RegisterName, size:int, offset:int=0,
+ extend:ImplicitRegisterExtend=ImplicitRegisterExtend.NoExtend, index:RegisterIndex=None):
+ self._full_width_reg = full_width_reg
+ self._offset = offset
+ self._size = size
+ self._extend = extend
+ self._index = index
+
+ def __repr__(self):
+ if self._extend == ImplicitRegisterExtend.ZeroExtendToFullWidth:
+ extend = ", zero extend"
+ elif self._extend == ImplicitRegisterExtend.SignExtendToFullWidth:
+ extend = ", sign extend"
+ else:
+ extend = ""
+ return "<reg: size %d, offset %d in %s%s>" % (self._size, self._offset, self._full_width_reg, extend)
@property
- def list(self):
- binaryninja._init_plugins()
- count = ctypes.c_ulonglong()
- archs = core.BNGetArchitectureList(count)
- result = []
- for i in range(0, count.value):
- result.append(CoreArchitecture._from_cache(archs[i]))
- core.BNFreeArchitectureList(archs)
- return result
+ def full_width_reg(self) -> RegisterName:
+ return self._full_width_reg
+
+ @full_width_reg.setter
+ def full_width_reg(self, value:RegisterName) -> None:
+ self._full_width_reg = value
+
+ @property
+ def offset(self) -> int:
+ return self._offset
+
+ @offset.setter
+ def offset(self, value:int) -> None:
+ self._offset = value
+
+ @property
+ def size(self) -> int:
+ return self._size
+
+ @size.setter
+ def size(self, value:int) -> None:
+ self._size = value
+
+ @property
+ def extend(self) -> ImplicitRegisterExtend:
+ return self._extend
+
+ @extend.setter
+ def extend(self, value:ImplicitRegisterExtend) -> None:
+ self._extend = value
+
+ @property
+ def index(self) -> Optional[RegisterIndex]:
+ return self._index
+
+ @index.setter
+ def index(self, value:RegisterIndex) -> None:
+ self._index = value
+
+
+class RegisterStackInfo(object):
+ def __init__(self, storage_regs:List[RegisterName], top_relative_regs:List[RegisterName],
+ stack_top_reg:RegisterName, index:RegisterStackIndex=None):
+ self._storage_regs = storage_regs
+ self._top_relative_regs = top_relative_regs
+ self._stack_top_reg = stack_top_reg
+ self._index = index
+
+ def __repr__(self):
+ return "<reg stack: %d regs, stack top in %s>" % (len(self._storage_regs), self._stack_top_reg)
+
+ @property
+ def storage_regs(self) -> List[RegisterName]:
+ return self._storage_regs
+
+ @storage_regs.setter
+ def storage_regs(self, value:List[RegisterName]) -> None:
+ self._storage_regs = value
+
+ @property
+ def top_relative_regs(self) -> List[RegisterName]:
+ return self._top_relative_regs
+
+ @top_relative_regs.setter
+ def top_relative_regs(self, value:List[RegisterName]) -> None:
+ self._top_relative_regs = value
+
+ @property
+ def stack_top_reg(self) -> RegisterName:
+ return self._stack_top_reg
+
+ @stack_top_reg.setter
+ def stack_top_reg(self, value:RegisterName) -> None:
+ self._stack_top_reg = value
+
+ @property
+ def index(self) -> Optional[RegisterStackIndex]:
+ return self._index
+
+ @index.setter
+ def index(self, value:RegisterStackIndex) -> None:
+ self._index = value
+
+
+class IntrinsicInput(object):
+ def __init__(self, type_obj, name=""):
+ self._name = name
+ self._type = type_obj
+
+ def __repr__(self):
+ if len(self._name) == 0:
+ return "<input: %s>" % str(self._type)
+ return "<input: %s %s>" % (str(self._type), self._name)
+
+ @property
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ self._name = value
+
+ @property
+ def type(self):
+ return self._type
- def __iter__(self):
+ @type.setter
+ def type(self, value):
+ self._type = value
+
+
+class IntrinsicInfo(object):
+ def __init__(self, inputs, outputs, index=None):
+ self._inputs = inputs
+ self._outputs = outputs
+ self._index = index
+
+ def __repr__(self):
+ return "<intrinsic: %s -> %s>" % (repr(self._inputs), repr(self._outputs))
+
+ @property
+ def inputs(self):
+ return self._inputs
+
+ @inputs.setter
+ def inputs(self, value):
+ self._inputs = value
+
+ @property
+ def outputs(self):
+ return self._outputs
+
+ @outputs.setter
+ def outputs(self, value):
+ self._outputs = value
+
+ @property
+ def index(self):
+ return self._index
+
+ @index.setter
+ def index(self, value):
+ self._index = value
+
+
+class InstructionBranch(object):
+ def __init__(self, branch_type, target = 0, arch = None):
+ self._type = branch_type
+ self._target = target
+ self._arch = arch
+
+ def __repr__(self):
+ branch_type = self._type
+ if self._arch is not None:
+ return "<%s: %s@%#x>" % (branch_type.name, self._arch.name, self._target)
+ return "<%s: %#x>" % (branch_type, self._target)
+
+ @property
+ def type(self):
+ return self._type
+
+ @type.setter
+ def type(self, value):
+ self._type = value
+
+ @property
+ def target(self):
+ return self._target
+
+ @target.setter
+ def target(self, value):
+ self._target = value
+
+ @property
+ def arch(self):
+ return self._arch
+
+ @arch.setter
+ def arch(self, value):
+ self._arch = value
+
+
+class InstructionInfo(object):
+ def __init__(self):
+ self.length = 0
+ self.arch_transition_by_target_addr = False
+ self.branch_delay = False
+ self.branches = []
+
+ def add_branch(self, branch_type, target = 0, arch = None):
+ self._branches.append(InstructionBranch(branch_type, target, arch))
+
+ def __len__(self):
+ return self._length
+
+ def __repr__(self):
+ branch_delay = ""
+ if self._branch_delay:
+ branch_delay = ", delay slot"
+ return "<instr: %d bytes%s, %s>" % (self._length, branch_delay, repr(self._branches))
+
+ @property
+ def length(self):
+ return self._length
+
+ @length.setter
+ def length(self, value):
+ self._length = value
+
+ @property
+ def arch_transition_by_target_addr(self):
+ return self._arch_transition_by_target_addr
+
+ @arch_transition_by_target_addr.setter
+ def arch_transition_by_target_addr(self, value):
+ self._arch_transition_by_target_addr = value
+
+ @property
+ def branch_delay(self):
+ return self._branch_delay
+
+ @branch_delay.setter
+ def branch_delay(self, value):
+ self._branch_delay = value
+
+ @property
+ def branches(self):
+ return self._branches
+
+ @branches.setter
+ def branches(self, value):
+ self._branches = value
+
+
+class _ArchitectureMetaClass(type):
+ def __iter__(self) -> Generator['Architecture', None, None]:
binaryninja._init_plugins()
count = ctypes.c_ulonglong()
archs = core.BNGetArchitectureList(count)
+ if archs is None:
+ return
try:
for i in range(0, count.value):
yield CoreArchitecture._from_cache(archs[i])
finally:
core.BNFreeArchitectureList(archs)
- def __getitem__(cls, name):
+ def __getitem__(cls:'_ArchitectureMetaClass', name:str) -> 'Architecture':
binaryninja._init_plugins()
arch = core.BNGetArchitectureByName(name)
if arch is None:
raise KeyError("'%s' is not a valid architecture" % str(name))
return CoreArchitecture._from_cache(arch)
- def register(cls):
- binaryninja._init_plugins()
- if cls.name is None:
- raise ValueError("architecture 'name' is not defined")
- arch = cls()
- cls._registered_cb = arch._cb
- arch.handle = core.BNRegisterArchitecture(cls.name, arch._cb)
-
-class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
+class Architecture(metaclass=_ArchitectureMetaClass):
"""
``class Architecture`` is the parent class for all CPU architectures. Subclasses of Architecture implement assembly,
disassembly, IL lifting, and patching.
@@ -120,7 +377,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
global_regs = []
system_regs = []
flags = []
- flag_write_types = []
+ flag_write_types:List[FlagWriteTypeName] = []
semantic_flag_classes = []
semantic_flag_groups = []
flag_roles = {}
@@ -217,119 +474,117 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
self._cb.invertBranch = self._cb.invertBranch.__class__(self._invert_branch)
self._cb.skipAndReturnValue = self._cb.skipAndReturnValue.__class__(self._skip_and_return_value)
- self.__dict__["endianness"] = self.__class__.endianness
- self.__dict__["address_size"] = self.__class__.address_size
- self.__dict__["default_int_size"] = self.__class__.default_int_size
- self.__dict__["instr_alignment"] = self.__class__.instr_alignment
- self.__dict__["max_instr_length"] = self.__class__.max_instr_length
- self.__dict__["opcode_display_length"] = self.__class__.opcode_display_length
- self.__dict__["stack_pointer"] = self.__class__.stack_pointer
- self.__dict__["link_reg"] = self.__class__.link_reg
+ self.__dict__['endianness'] = self.__class__.endianness
+ self.__dict__['address_size'] = self.__class__.address_size
+ self.__dict__['default_int_size'] = self.__class__.default_int_size
+ self.__dict__['instr_alignment'] = self.__class__.instr_alignment
+ self.__dict__['max_instr_length'] = self.__class__.max_instr_length
+ self.__dict__['opcode_display_length'] = self.__class__.opcode_display_length
+ self.__dict__['stack_pointer'] = self.__class__.stack_pointer
+ self.__dict__['link_reg'] = self.__class__.link_reg
- self._all_regs = {}
- self._full_width_regs = {}
- self._regs_by_index = {}
- self.__dict__["regs"] = self.__class__.regs
- reg_index = 0
+ self._all_regs:Mapping[RegisterName, RegisterIndex] = {}
+ self._full_width_regs:Mapping[RegisterName, RegisterIndex] = {}
+ self._regs_by_index:Mapping[RegisterIndex, RegisterName] = {}
+ self.regs:Mapping[RegisterName, RegisterInfo] = self.__class__.regs
+ reg_index = RegisterIndex(0)
# Registers used for storage in register stacks must be sequential, so allocate these in order first
- self._all_reg_stacks = {}
- self._reg_stacks_by_index = {}
- self.__dict__["reg_stacks"] = self.__class__.reg_stacks
- reg_stack_index = 0
- for reg_stack in self.reg_stacks:
- info = self.reg_stacks[reg_stack]
+ self._all_reg_stacks:Mapping[RegisterStackName, RegisterStackIndex] = {}
+ self._reg_stacks_by_index:Mapping[RegisterStackIndex, RegisterStackName] = {}
+ self.reg_stacks:Mapping[RegisterStackName, RegisterStackInfo] = self.__class__.reg_stacks
+ reg_stack_index = RegisterStackIndex(0)
+ for reg_stack, info in self.reg_stacks.items():
for reg in info.storage_regs:
self._all_regs[reg] = reg_index
self._regs_by_index[reg_index] = reg
self.regs[reg].index = reg_index
- reg_index += 1
+ reg_index = RegisterIndex(reg_index + 1)
for reg in info.top_relative_regs:
self._all_regs[reg] = reg_index
self._regs_by_index[reg_index] = reg
self.regs[reg].index = reg_index
- reg_index += 1
+ reg_index = RegisterIndex(reg_index + 1)
if reg_stack not in self._all_reg_stacks:
self._all_reg_stacks[reg_stack] = reg_stack_index
self._reg_stacks_by_index[reg_stack_index] = reg_stack
self.reg_stacks[reg_stack].index = reg_stack_index
- reg_stack_index += 1
+ reg_stack_index = RegisterStackIndex(reg_stack_index + 1)
- for reg in self.regs:
- info = self.regs[reg]
+ for reg, info in self.regs.items():
if reg not in self._all_regs:
self._all_regs[reg] = reg_index
self._regs_by_index[reg_index] = reg
self.regs[reg].index = reg_index
- reg_index += 1
+ reg_index = RegisterIndex(reg_index + 1)
if info.full_width_reg not in self._all_regs:
self._all_regs[info.full_width_reg] = reg_index
self._regs_by_index[reg_index] = info.full_width_reg
self.regs[info.full_width_reg].index = reg_index
- reg_index += 1
+ reg_index = RegisterIndex(reg_index + 1)
if info.full_width_reg not in self._full_width_regs:
self._full_width_regs[info.full_width_reg] = self._all_regs[info.full_width_reg]
- self._flags = {}
- self._flags_by_index = {}
- self.__dict__["flags"] = self.__class__.flags
- flag_index = 0
+ self._flags:Mapping[FlagName, FlagIndex] = {}
+ self._flags_by_index:Mapping[FlagIndex, FlagName] = {}
+ self.flags:List[FlagName] = self.__class__.flags
+ flag_index = FlagIndex(0)
for flag in self.__class__.flags:
if flag not in self._flags:
self._flags[flag] = flag_index
self._flags_by_index[flag_index] = flag
- flag_index += 1
+ flag_index = FlagIndex(flag_index + 1)
- self._flag_write_types = {}
- self._flag_write_types_by_index = {}
- self.__dict__["flag_write_types"] = self.__class__.flag_write_types
- write_type_index = 1
+ self._flag_write_types:Mapping[FlagWriteTypeName, FlagWriteTypeIndex] = {}
+ self._flag_write_types_by_index:Mapping[FlagWriteTypeIndex, FlagWriteTypeName] = {}
+ self.flag_write_types:List[FlagWriteTypeName] = self.__class__.flag_write_types
+ write_type_index = FlagWriteTypeIndex(1)
for write_type in self.__class__.flag_write_types:
if write_type not in self._flag_write_types:
self._flag_write_types[write_type] = write_type_index
self._flag_write_types_by_index[write_type_index] = write_type
- write_type_index += 1
+ write_type_index = FlagWriteTypeIndex(write_type_index + 1)
- self._semantic_flag_classes = {}
- self._semantic_flag_classes_by_index = {}
- self.__dict__["semantic_flag_classes"] = self.__class__.semantic_flag_classes
- semantic_class_index = 1
+ self._semantic_flag_classes:Mapping[SemanticClassName, SemanticClassIndex] = {}
+ self._semantic_flag_classes_by_index:Mapping[SemanticClassIndex, SemanticClassName] = {}
+ self.semantic_flag_classes:List[SemanticClassName] = self.__class__.semantic_flag_classes
+ semantic_class_index = SemanticClassIndex(1)
for sem_class in self.__class__.semantic_flag_classes:
if sem_class not in self._semantic_flag_classes:
self._semantic_flag_classes[sem_class] = semantic_class_index
self._semantic_flag_classes_by_index[semantic_class_index] = sem_class
- semantic_class_index += 1
+ semantic_class_index = SemanticClassIndex(semantic_class_index + 1)
- self._semantic_flag_groups = {}
- self._semantic_flag_groups_by_index = {}
- self.__dict__["semantic_flag_groups"] = self.__class__.semantic_flag_groups
- semantic_group_index = 0
+ self._semantic_flag_groups:Mapping[SemanticGroupName, SemanticGroupIndex] = {}
+ self._semantic_flag_groups_by_index:Mapping[SemanticGroupIndex, SemanticGroupName] = {}
+ self.semantic_flag_groups:List[SemanticGroupName] = self.__class__.semantic_flag_groups
+ semantic_group_index = SemanticGroupIndex(0)
for sem_group in self.__class__.semantic_flag_groups:
if sem_group not in self._semantic_flag_groups:
self._semantic_flag_groups[sem_group] = semantic_group_index
self._semantic_flag_groups_by_index[semantic_group_index] = sem_group
- semantic_group_index += 1
+ semantic_group_index = SemanticGroupIndex(semantic_group_index + 1)
- self._flag_roles = {}
- self.__dict__["flag_roles"] = self.__class__.flag_roles
+ self._flag_roles:Mapping[FlagIndex, FlagRole] = {}
+ self.flag_roles:Mapping[FlagName, FlagRole] = self.__class__.flag_roles
for flag in self.__class__.flag_roles:
role = self.__class__.flag_roles[flag]
if isinstance(role, str):
role = FlagRole[role]
self._flag_roles[self._flags[flag]] = role
- self.__dict__["flags_required_for_flag_condition"] = self.__class__.flags_required_for_flag_condition
+ self.flags_required_for_flag_condition:Mapping['lowlevelil.LowLevelILFlagCondition', List[FlagName]] = self.__class__.flags_required_for_flag_condition
- self._flags_required_by_semantic_flag_group = {}
- self.__dict__["flags_required_for_semantic_flag_group"] = self.__class__.flags_required_for_semantic_flag_group
+ self._flags_required_by_semantic_flag_group:Mapping[SemanticGroupIndex, List[FlagIndex]] = {}
+ self.flags_required_for_semantic_flag_group:Mapping[SemanticGroupName, List[FlagName]] = self.__class__.flags_required_for_semantic_flag_group
for group in self.__class__.flags_required_for_semantic_flag_group:
- flags = []
+ flags:List[FlagIndex] = []
for flag in self.__class__.flags_required_for_semantic_flag_group[group]:
flags.append(self._flags[flag])
self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flags
self._flag_conditions_for_semantic_flag_group = {}
- self.__dict__["flag_conditions_for_semantic_flag_group"] = self.__class__.flag_conditions_for_semantic_flag_group
+ self.flag_conditions_for_semantic_flag_group = self.__class__.flag_conditions_for_semantic_flag_group
for group in self.__class__.flag_conditions_for_semantic_flag_group:
class_cond = {}
for sem_class in self.__class__.flag_conditions_for_semantic_flag_group[group]:
@@ -340,7 +595,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_cond
self._flags_written_by_flag_write_type = {}
- self.__dict__["flags_written_by_flag_write_type"] = self.__class__.flags_written_by_flag_write_type
+ self.flags_written_by_flag_write_type = self.__class__.flags_written_by_flag_write_type
for write_type in self.__class__.flags_written_by_flag_write_type:
flags = []
for flag in self.__class__.flags_written_by_flag_write_type[write_type]:
@@ -348,7 +603,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flags
self._semantic_class_for_flag_write_type = {}
- self.__dict__["semantic_class_for_flag_write_type"] = self.__class__.semantic_class_for_flag_write_type
+ self.semantic_class_for_flag_write_type = self.__class__.semantic_class_for_flag_write_type
for write_type in self.__class__.semantic_class_for_flag_write_type:
sem_class = self.__class__.semantic_class_for_flag_write_type[write_type]
if sem_class in self._semantic_flag_classes:
@@ -357,25 +612,25 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
sem_class_index = 0
self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class_index
- self.__dict__["global_regs"] = self.__class__.global_regs
- self.__dict__["system_regs"] = self.__class__.system_regs
+ self.global_regs = self.__class__.global_regs
+ self.system_regs = self.__class__.system_regs
- self._intrinsics = {}
- self._intrinsics_by_index = {}
- self.__dict__["intrinsics"] = self.__class__.intrinsics
- intrinsic_index = 0
+ self._intrinsics:Mapping[IntrinsicName, IntrinsicIndex] = {}
+ self._intrinsics_by_index:Mapping[IntrinsicIndex, Tuple[IntrinsicName, IntrinsicInfo]] = {}
+ self.intrinsics = self.__class__.intrinsics
+ intrinsic_index = IntrinsicIndex(0)
for intrinsic in self.__class__.intrinsics.keys():
if intrinsic not in self._intrinsics:
info = self.__class__.intrinsics[intrinsic]
for i in range(0, len(info.inputs)):
if isinstance(info.inputs[i], types.Type):
- info.inputs[i] = binaryninja.function.IntrinsicInput(info.inputs[i])
+ info.inputs[i] = IntrinsicInput(info.inputs[i])
elif isinstance(info.inputs[i], tuple):
- info.inputs[i] = binaryninja.function.IntrinsicInput(info.inputs[i][0], info.inputs[i][1])
+ info.inputs[i] = IntrinsicInput(info.inputs[i][0], info.inputs[i][1])
info.index = intrinsic_index
self._intrinsics[intrinsic] = intrinsic_index
self._intrinsics_by_index[intrinsic_index] = (intrinsic, info)
- intrinsic_index += 1
+ intrinsic_index = IntrinsicIndex(intrinsic_index + 1)
self._pending_reg_lists = {}
self._pending_token_lists = {}
@@ -399,27 +654,32 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
def __hash__(self):
return hash(ctypes.addressof(self.handle.contents))
- def __setattr__(self, name, value):
- if ((name == "name") or (name == "endianness") or (name == "address_size") or
- (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length") or
- (name == "get_instruction_alignment")):
- raise AttributeError("attribute '%s' is read only" % name)
- else:
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
+ # def __setattr__(self, name, value):
+ # if ((name == "name") or (name == "endianness") or (name == "address_size") or
+ # (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length") or
+ # (name == "get_instruction_alignment")):
+ # raise AttributeError("attribute '%s' is read only" % name)
+ # else:
+ # try:
+ # object.__setattr__(self, name, value)
+ # except AttributeError:
+ # raise AttributeError("attribute '%s' is read only" % name)
- @property
- def list(self):
- """Allow tab completion to discover metaclass list property"""
- pass
+ @classmethod
+ def register(cls) -> None:
+ binaryninja._init_plugins()
+ if cls.name is None:
+ raise ValueError("architecture 'name' is not defined")
+ arch = cls()
+ cls._registered_cb = arch._cb
+ arch.handle = core.BNRegisterArchitecture(cls.name, arch._cb)
@property
- def full_width_regs(self):
+ def full_width_regs(self) -> List[RegisterName]:
"""List of full width register strings (read-only)"""
count = ctypes.c_ulonglong()
regs = core.BNGetFullWidthArchitectureRegisters(self.handle, count)
+ assert regs is not None, "core.BNGetFullWidthArchitectureRegisters returned None"
result = []
for i in range(0, count.value):
result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
@@ -427,10 +687,11 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
return result
@property
- def calling_conventions(self):
+ def calling_conventions(self) -> Mapping[str, 'callingconvention.CallingConvention']:
"""Dict of CallingConvention objects (read-only)"""
count = ctypes.c_ulonglong()
cc = core.BNGetArchitectureCallingConventions(self.handle, count)
+ assert cc is not None, "core.BNGetArchitectureCallingConventions returned None"
result = {}
for i in range(0, count.value):
obj = callingconvention.CallingConvention(handle=core.BNNewCallingConventionReference(cc[i]))
@@ -439,24 +700,25 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
return result
@property
- def standalone_platform(self):
+ def standalone_platform(self) -> 'platform.Platform':
"""Architecture standalone platform (read-only)"""
pl = core.BNGetArchitectureStandalonePlatform(self.handle)
return platform.Platform(self, pl)
@property
- def type_libraries(self):
+ def type_libraries(self) -> List['typelibrary.TypeLibrary']:
"""Architecture type libraries"""
count = ctypes.c_ulonglong(0)
result = []
handles = core.BNGetArchitectureTypeLibraries(self.handle, count)
+ assert handles is not None, "core.BNGetArchitectureTypeLibraries returned None"
for i in range(0, count.value):
- result.append(binaryninja.typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(handles[i])))
+ result.append(typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(handles[i])))
core.BNFreeTypeLibraryList(handles, count.value)
return result
@property
- def can_assemble(self):
+ def can_assemble(self) -> bool:
"""returns if the architecture can assemble instructions (read-only)"""
return core.BNCanArchitectureAssemble(self.handle)
@@ -550,7 +812,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
tokens = info[0]
length[0] = info[1]
count[0] = len(tokens)
- token_buf = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens)
+ token_buf = function.InstructionTextToken._get_core_struct(tokens)
result[0] = token_buf
ptr = ctypes.cast(token_buf, ctypes.c_void_p)
self._pending_token_lists[ptr.value] = (ptr.value, token_buf)
@@ -600,7 +862,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
log.log_error(traceback.format_exc())
return core.BNAllocString("")
- def _get_flag_write_type_name(self, ctxt, write_type):
+ def _get_flag_write_type_name(self, ctxt, write_type:FlagWriteTypeIndex):
try:
if write_type in self._flag_write_types_by_index:
return core.BNAllocString(self._flag_write_types_by_index[write_type])
@@ -717,16 +979,13 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
count[0] = 0
return None
- def _get_flag_role(self, ctxt, flag, sem_class):
- try:
- if sem_class in self._semantic_flag_classes_by_index:
- sem_class = self._semantic_flag_classes_by_index[sem_class]
- else:
- sem_class = None
- return self.get_flag_role(flag, sem_class)
- except KeyError:
- log.log_error(traceback.format_exc())
- return FlagRole.SpecialFlagRole
+ def _get_flag_role(self, ctxt, flag:FlagIndex, sem_class:Optional[SemanticClassName]=None):
+ if sem_class in self._semantic_flag_classes:
+ assert sem_class is not None
+ _sem_class = self._semantic_flag_classes[sem_class]
+ else:
+ _sem_class = None
+ return self.get_flag_role(flag, _sem_class)
def _get_flags_required_for_flag_condition(self, ctxt, cond, sem_class, count):
try:
@@ -903,6 +1162,8 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
result[0].extend = ImplicitRegisterExtend.NoExtend
def _get_stack_pointer_register(self, ctxt):
+ if self.stack_pointer is None:
+ return None
try:
return self._all_regs[self.stack_pointer]
except KeyError:
@@ -1214,234 +1475,10 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
log.log_error(traceback.format_exc())
return False
- def perform_get_associated_arch_by_address(self, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_associated_arch_by_address`.
- """
+ def get_associated_arch_by_address(self, addr:int) -> Tuple['Architecture', int]:
return self, addr
- @abc.abstractmethod
- def perform_get_instruction_info(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_instruction_info`.
-
- :param str data: bytes to decode
- :param int addr: virtual address of the byte to be decoded
- :return: a :py:class:`InstructionInfo` object containing the length and branch types for the given instruction
- :rtype: InstructionInfo
- """
- raise NotImplementedError
-
- @abc.abstractmethod
- def perform_get_instruction_text(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_instruction_text`.
-
- :param str data: bytes to decode
- :param int addr: virtual address of the byte to be decoded
- :return: a tuple of list(InstructionTextToken) and length of instruction decoded
- :rtype: tuple(list(InstructionTextToken), int)
- """
- raise NotImplementedError
-
- @abc.abstractmethod
- def perform_get_instruction_low_level_il(self, data, addr, il):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_instruction_low_level_il`.
-
- :param str data: bytes to be interpreted as low-level IL instructions
- :param int addr: virtual address of start of ``data``
- :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
- :rtype: length of bytes read on success, None on failure
- """
- raise NotImplementedError
-
- @abc.abstractmethod
- def perform_get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_flag_write_low_level_il`.
-
- :param LowLevelILOperation op:
- :param int size:
- :param int write_type:
- :param int flag:
- :param operands:
- :type operands: list(str) or list(int)
- :param LowLevelILFunction il:
- :rtype: LowLevelILExpr
- """
- flag = self.get_flag_index(flag)
- if flag not in self._flag_roles:
- return il.unimplemented()
- return self.get_default_flag_write_low_level_il(op, size, self._flag_roles[flag], operands, il)
-
- @abc.abstractmethod
- def perform_get_flag_condition_low_level_il(self, cond, sem_class, il):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_flag_condition_low_level_il`.
-
- :param LowLevelILFlagCondition cond: Flag condition to be computed
- :param str sem_class: Semantic class to be used (None for default semantics)
- :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
- :rtype: LowLevelILExpr
- """
- return self.get_default_flag_condition_low_level_il(cond, sem_class, il)
-
- @abc.abstractmethod
- def perform_get_semantic_flag_group_low_level_il(self, sem_group, il):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_semantic_flag_group_low_level_il`.
-
- :param str sem_group: Semantic group to be computed
- :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
- :rtype: LowLevelILExpr
- """
- return il.unimplemented()
-
- @abc.abstractmethod
- def perform_assemble(self, code, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`assemble`.
-
- :param str code: string representation of the instructions to be assembled
- :param int addr: virtual address that the instructions will be loaded at
- :return: the bytes for the assembled instructions or error string
- :rtype: (a tuple of instructions and empty string) or (or None and error string)
- """
- raise NotImplementedError("Architecture does not implement an assembler.\n")
-
- @abc.abstractmethod
- def perform_is_never_branch_patch_available(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`is_never_branch_patch_available`.
-
- .. note:: Architecture subclasses should implement this method.
-
- .. warning:: This method should never be called directly.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: True if the instruction can be patched, False otherwise
- :rtype: bool
- """
- return False
-
- @abc.abstractmethod
- def perform_is_always_branch_patch_available(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`is_always_branch_patch_available`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: True if the instruction can be patched, False otherwise
- :rtype: bool
- """
- return False
-
- @abc.abstractmethod
- def perform_is_invert_branch_patch_available(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`is_invert_branch_patch_available`.
-
- :param int addr: the virtual address of the instruction to be patched
- :return: True if the instruction can be patched, False otherwise
- :rtype: bool
- """
- return False
-
- @abc.abstractmethod
- def perform_is_skip_and_return_zero_patch_available(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`is_skip_and_return_zero_patch_available`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: True if the instruction can be patched, False otherwise
- :rtype: bool
- """
- return False
-
- @abc.abstractmethod
- def perform_is_skip_and_return_value_patch_available(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`is_skip_and_return_value_patch_available`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: True if the instruction can be patched, False otherwise
- :rtype: bool
- """
- return False
-
- @abc.abstractmethod
- def perform_convert_to_nop(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`convert_to_nop`.
-
- :param str data: bytes at virtual address ``addr``
- :param int addr: the virtual address of the instruction to be patched
- :return: nop sequence of same length as ``data`` or None
- :rtype: str or None
- """
- return None
-
- @abc.abstractmethod
- def perform_always_branch(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`always_branch`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: The bytes of the replacement unconditional branch instruction
- :rtype: str
- """
- return None
-
- @abc.abstractmethod
- def perform_invert_branch(self, data, addr):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`invert_branch`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :return: The bytes of the replacement unconditional branch instruction
- :rtype: str
- """
- return None
-
- @abc.abstractmethod
- def perform_skip_and_return_value(self, data, addr, value):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`skip_and_return_value`.
-
- :param str data: bytes to be checked
- :param int addr: the virtual address of the instruction to be patched
- :param int value: value to be returned
- :return: The bytes of the replacement unconditional branch instruction
- :rtype: str
- """
- return None
-
- def perform_get_flag_role(self, flag, sem_class):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_flag_role`.
- """
- if flag in self._flag_roles:
- return self._flag_roles[flag]
- return FlagRole.SpecialFlagRole
-
- def perform_get_flags_required_for_flag_condition(self, cond, sem_class):
- """
- Deprecated method provided for compatibility. Architecture plugins should override :func:`get_flags_required_for_flag_condition`.
- """
- if cond in self.flags_required_for_flag_condition:
- return self.flags_required_for_flag_condition[cond]
- return []
-
- def get_associated_arch_by_address(self, addr):
- return self.perform_get_associated_arch_by_address(addr)
-
- def get_instruction_info(self, data, addr):
+ def get_instruction_info(self, data:bytes, addr:int) -> Optional[InstructionInfo]:
"""
``get_instruction_info`` returns an InstructionInfo object for the instruction at the given virtual address
``addr`` with data ``data``.
@@ -1471,9 +1508,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: the InstructionInfo for the current instruction
:rtype: InstructionInfo
"""
- return self.perform_get_instruction_info(data, addr)
+ raise NotImplementedError
- def get_instruction_text(self, data, addr):
+ def get_instruction_text(self, data:bytes, addr:int) -> Tuple[List['function.InstructionTextToken'], int]:
"""
``get_instruction_text`` returns a tuple containing a list of decoded InstructionTextToken objects and the bytes used at the given virtual
address ``addr`` with data ``data``.
@@ -1485,15 +1522,15 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: a tuple containing the InstructionTextToken list and length of bytes decoded
:rtype: tuple(list(InstructionTextToken), int)
"""
- return self.perform_get_instruction_text(data, addr)
+ raise NotImplementedError
- def get_instruction_low_level_il_instruction(self, bv, addr):
+ def get_instruction_low_level_il_instruction(self, bv:'binaryview.BinaryView', addr:int) -> 'lowlevelil.LowLevelILInstruction':
il = lowlevelil.LowLevelILFunction(self)
data = bv.read(addr, self.max_instr_length)
self.get_instruction_low_level_il(data, addr, il)
return il[0]
- def get_instruction_low_level_il(self, data, addr, il):
+ def get_instruction_low_level_il(self, data:bytes, addr:int, il:'lowlevelil.LowLevelILFunction') -> int:
"""
``get_instruction_low_level_il`` appends LowLevelILExpr objects to ``il`` for the instruction at the given
virtual address ``addr`` with data ``data``.
@@ -1509,94 +1546,108 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: the length of the current instruction
:rtype: int
"""
- return self.perform_get_instruction_low_level_il(data, addr, il)
+ raise NotImplementedError
- def get_low_level_il_from_bytes(self, data, addr):
+ def get_low_level_il_from_bytes(self, data:bytes, addr:int) -> Generator['lowlevelil.LowLevelILInstruction', None, None]:
"""
``get_low_level_il_from_bytes`` converts the instruction in bytes to ``il`` at the given virtual address
:param str data: the bytes of the instruction
:param int addr: virtual address of bytes in ``data``
- :return: the instruction
- :rtype: LowLevelILInstruction
+ :return: a list of low level il instructions
+ :rtype: List[LowLevelILInstruction]
:Example:
- >>> arch.get_low_level_il_from_bytes(b'\\xeb\\xfe', 0x40DEAD)
- <il: jump(0x40dead)>
+ >>> list(arch.get_low_level_il_from_bytes(b'\\xeb\\xfe', 0x40DEAD))
+ [<il: jump(0x40dead)>]
>>>
"""
func = lowlevelil.LowLevelILFunction(self)
self.get_instruction_low_level_il(data, addr, func)
- return func[0]
+ return func.instructions
- def get_reg_name(self, reg):
+ def get_reg_name(self, reg:RegisterIndex) -> RegisterName:
"""
- ``get_reg_name`` gets a register name from a register number.
+ ``get_reg_name`` gets a register name from a register index.
- :param int reg: register number
- :return: the corresponding register string
- :rtype: str
+ :param RegisterIndex reg: register index
+ :return: the corresponding register name
+ :rtype: RegisterName
"""
- return core.BNGetArchitectureRegisterName(self.handle, reg)
+ return RegisterName(core.BNGetArchitectureRegisterName(self.handle, reg))
- def get_reg_stack_name(self, reg_stack):
+ def get_reg_stack_name(self, reg_stack:RegisterStackIndex) -> RegisterStackName:
"""
``get_reg_stack_name`` gets a register stack name from a register stack number.
:param int reg_stack: register stack number
:return: the corresponding register string
- :rtype: str
+ :rtype: RegisterStackName
"""
- return core.BNGetArchitectureRegisterStackName(self.handle, reg_stack)
+ return RegisterStackName(core.BNGetArchitectureRegisterStackName(self.handle, reg_stack))
- def get_reg_stack_for_reg(self, reg):
- reg = self.get_reg_index(reg)
- result = core.BNGetArchitectureRegisterStackForRegister(self.handle, reg)
+ def get_reg_stack_for_reg(self, reg:RegisterName) -> Optional[RegisterStackName]:
+ _reg = self.get_reg_index(reg)
+ result = core.BNGetArchitectureRegisterStackForRegister(self.handle, _reg)
if result == 0xffffffff:
return None
return self.get_reg_stack_name(result)
- def get_flag_name(self, flag):
+ def get_flag_name(self, flag:FlagIndex) -> FlagName:
"""
- ``get_flag_name`` gets a flag name from a flag number.
+ ``get_flag_name`` gets a flag name from a flag index.
- :param int reg: register number
- :return: the corresponding register string
- :rtype: str
+ :param int flag: flag index
+ :return: the corresponding flag name string
+ :rtype: FlagName
"""
- return core.BNGetArchitectureFlagName(self.handle, flag)
+ return FlagName(core.BNGetArchitectureFlagName(self.handle, flag))
- def get_reg_index(self, reg):
+ def get_reg_index(self, reg:RegisterType) -> RegisterIndex:
if isinstance(reg, str):
- return self.regs[reg].index
+ try:
+ index = self.regs[reg].index
+ assert index is not None
+ return index
+ except KeyError:
+ log.log_error(f"Failed to map string {reg} to register index: ")
+ log.log_error(traceback.format_exc())
elif isinstance(reg, lowlevelil.ILRegister):
return reg.index
- return reg
+ elif isinstance(reg, RegisterIndex):
+ return reg
+ raise Exception("Attempting to get register index of non-existant register")
- def get_reg_stack_index(self, reg_stack):
+ def get_reg_stack_index(self, reg_stack:RegisterStackType) -> RegisterStackIndex:
if isinstance(reg_stack, str):
- return self.reg_stacks[reg_stack].index
+ reg_stack_info = self.reg_stacks[reg_stack]
+ if reg_stack_info is not None and reg_stack_info.index is not None:
+ return reg_stack_info.index
elif isinstance(reg_stack, lowlevelil.ILRegisterStack):
return reg_stack.index
- return reg_stack
+ elif isinstance(reg_stack, RegisterStackIndex):
+ return reg_stack
+ raise Exception("reg_stack is not convertable to index")
- def get_flag_index(self, flag):
+ def get_flag_index(self, flag:FlagType) -> FlagIndex:
if isinstance(flag, str):
return self._flags[flag]
elif isinstance(flag, lowlevelil.ILFlag):
return flag.index
- return flag
+ elif isinstance(flag, FlagIndex):
+ return flag
+ raise Exception("flag is not convertable to index")
- def get_semantic_flag_class_index(self, sem_class):
- if sem_class is None:
- return 0
- elif isinstance(sem_class, str):
+ def get_semantic_flag_class_index(self, sem_class:SemanticClassType) -> SemanticClassIndex:
+ if isinstance(sem_class, SemanticClassName):
return self._semantic_flag_classes[sem_class]
elif isinstance(sem_class, lowlevelil.ILSemanticFlagClass):
return sem_class.index
- return sem_class
+ elif isinstance(sem_class, SemanticClassIndex):
+ return sem_class
+ raise Exception("sem_class is not convertable to index")
- def get_semantic_flag_class_name(self, class_index):
+ def get_semantic_flag_class_name(self, class_index:SemanticClassIndex) -> SemanticClassName:
"""
``get_semantic_flag_class_name`` gets the name of a semantic flag class from the index.
@@ -1604,21 +1655,21 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: the name of the semantic flag class
:rtype: str
"""
- if not isinstance(class_index, numbers.Integral):
+ if not isinstance(class_index, int):
raise ValueError("argument 'class_index' must be an integer")
try:
return self._semantic_flag_classes_by_index[class_index]
except KeyError:
raise AttributeError("argument class_index is not a valid class index")
- def get_semantic_flag_group_index(self, sem_group):
+ def get_semantic_flag_group_index(self, sem_group:SemanticGroupType) -> SemanticGroupIndex:
if isinstance(sem_group, str):
return self._semantic_flag_groups[sem_group]
elif isinstance(sem_group, lowlevelil.ILSemanticFlagGroup):
return sem_group.index
return sem_group
- def get_semantic_flag_group_name(self, group_index):
+ def get_semantic_flag_group_name(self, group_index:SemanticGroupIndex) -> SemanticGroupName:
"""
``get_semantic_flag_group_name`` gets the name of a semantic flag group from the index.
@@ -1626,61 +1677,70 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: the name of the semantic flag group
:rtype: str
"""
- if not isinstance(group_index, numbers.Integral):
+ if not isinstance(group_index, int):
raise ValueError("argument 'group_index' must be an integer")
try:
return self._semantic_flag_groups_by_index[group_index]
except KeyError:
raise AttributeError("argument group_index is not a valid group index")
- def get_intrinsic_name(self, intrinsic):
+ def get_intrinsic_name(self, intrinsic:IntrinsicIndex) -> IntrinsicName:
"""
``get_intrinsic_name`` gets an intrinsic name from an intrinsic number.
:param int intrinsic: intrinsic number
:return: the corresponding intrinsic string
- :rtype: str
+ :rtype: IntrinsicName
+ """
+ return IntrinsicName(core.BNGetArchitectureIntrinsicName(self.handle, intrinsic))
+
+ def get_intrinsic_index(self, intrinsic:IntrinsicType) -> IntrinsicIndex:
"""
- return core.BNGetArchitectureIntrinsicName(self.handle, intrinsic)
+ ``get_intrinsic_index`` gets an intrinsic index given an IntrinsicType.
- def get_intrinsic_index(self, intrinsic):
- if isinstance(intrinsic, str):
+ :param IntrinsicType intrinsic: intrinsic number
+ :return: the corresponding intrinsic string
+ :rtype: IntrinsicIndex
+ """
+ if isinstance(intrinsic, IntrinsicName):
return self._intrinsics[intrinsic]
elif isinstance(intrinsic, lowlevelil.ILIntrinsic):
return intrinsic.index
- return intrinsic
+ elif isinstance(intrinsic, IntrinsicIndex):
+ return intrinsic
+ raise Exception("intrinsic is not convertable to index")
- def get_flag_write_type_name(self, write_type):
+ def get_flag_write_type_name(self, write_type:FlagWriteTypeIndex) -> FlagWriteTypeName:
"""
``get_flag_write_type_name`` gets the flag write type name for the given flag.
- :param int write_type: flag
+ :param FlagWriteTypeIndex write_type: flag
:return: flag write type name
- :rtype: str
+ :rtype: FlagWriteTypeName
"""
- return core.BNGetArchitectureFlagWriteTypeName(self.handle, write_type)
+ return FlagWriteTypeName(core.BNGetArchitectureFlagWriteTypeName(self.handle, write_type))
- def get_flag_by_name(self, flag):
+ def get_flag_by_name(self, flag:FlagName) -> FlagIndex:
"""
``get_flag_by_name`` get flag name for flag index.
- :param int flag: flag index
- :return: flag name for flag index
- :rtype: str
+ :param FlagName flag: flag name
+ :return: flag index for flag name
+ :rtype: FlagIndex
"""
return self._flags[flag]
- def get_flag_write_type_by_name(self, write_type):
+ def get_flag_write_type_by_name(self, write_type:FlagWriteTypeName) -> FlagWriteTypeIndex:
"""
``get_flag_write_type_by_name`` gets the flag write type name for the flag write type.
- :param int write_type: flag write type
+ :param str write_type: flag write type
:return: flag write type
- :rtype: str
+ :rtype: int
"""
return self._flag_write_types[write_type]
- def get_semantic_flag_class_by_name(self, sem_class):
+ def get_semantic_flag_class_by_name(self, sem_class:SemanticClassName) -> SemanticClassIndex:
"""
``get_semantic_flag_class_by_name`` gets the semantic flag class index by name.
@@ -1690,17 +1750,17 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
return self._semantic_flag_classes[sem_class]
- def get_semantic_flag_group_by_name(self, sem_group):
+ def get_semantic_flag_group_by_name(self, sem_group:SemanticGroupName) -> SemanticGroupIndex:
"""
``get_semantic_flag_group_by_name`` gets the semantic flag group index by name.
- :param int sem_group: semantic flag group
+ :param SemanticGroupName sem_group: semantic flag group name
:return: semantic flag group index
- :rtype: str
+ :rtype: int
"""
return self._semantic_flag_groups[sem_group]
- def get_flag_role(self, flag, sem_class = None):
+ def get_flag_role(self, flag:FlagIndex, sem_class:Optional[SemanticClassIndex]= None) -> FlagRole:
"""
``get_flag_role`` gets the role of a given flag.
@@ -1709,9 +1769,12 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:return: flag role
:rtype: FlagRole
"""
- return self.perform_get_flag_role(flag, sem_class)
+ if flag in self._flag_roles:
+ return self._flag_roles[flag]
+ return FlagRole.SpecialFlagRole
- def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
+ def get_flag_write_low_level_il(self, op:LowLevelILOperation, size:int, write_type:Optional[FlagWriteTypeName], flag:FlagType,
+ operands:List['lowlevelil.ILRegisterType'], il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILOperation op:
:param int size:
@@ -1721,9 +1784,13 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
:param LowLevelILFunction il:
:rtype: LowLevelILExpr
"""
- return self.perform_get_flag_write_low_level_il(op, size, write_type, flag, operands, il)
+ flag = self.get_flag_index(flag)
+ if flag not in self._flag_roles:
+ return il.unimplemented()
+ return self.get_default_flag_write_low_level_il(op, size, self._flag_roles[flag], operands, il)
- def get_default_flag_write_low_level_il(self, op, size, role, operands, il):
+ def get_default_flag_write_low_level_il(self, op:'lowlevelil.LowLevelILOperation', size:int, role:FlagRole,
+ operands:List['lowlevelil.ILRegisterType'], il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILOperation op:
:param int size:
@@ -1735,49 +1802,59 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
operand_list = (core.BNRegisterOrConstant * len(operands))()
for i in range(len(operands)):
- if isinstance(operands[i], str):
+ operand = operands[i]
+ if isinstance(operand, RegisterName):
operand_list[i].constant = False
- operand_list[i].reg = self.regs[operands[i]].index
- elif isinstance(operands[i], lowlevelil.ILRegister):
+ operand_list[i].reg = self.regs[operand].index
+ elif isinstance(operand, lowlevelil.ILRegister):
operand_list[i].constant = False
- operand_list[i].reg = operands[i].index
+ operand_list[i].reg = operand.index
else:
operand_list[i].constant = True
- operand_list[i].value = operands[i]
+ operand_list[i].value = operand
return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagWriteLowLevelIL(self.handle, op, size,
role, operand_list, len(operand_list), il.handle))
- def get_flag_condition_low_level_il(self, cond, sem_class, il):
+ def get_flag_condition_low_level_il(self, cond:'lowlevelil.LowLevelILFlagCondition', sem_class:Optional[SemanticClassType],
+ il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILFlagCondition cond: Flag condition to be computed
- :param str sem_class: Semantic class to be used (None for default semantics)
+ :param SemanticClassType sem_class: Semantic class to be used (None for default semantics)
:param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
:rtype: LowLevelILExpr
"""
- return self.perform_get_flag_condition_low_level_il(cond, sem_class, il)
+ return self.get_default_flag_condition_low_level_il(cond, sem_class, il)
- def get_default_flag_condition_low_level_il(self, cond, sem_class, il):
+ def get_default_flag_condition_low_level_il(self, cond:'lowlevelil.LowLevelILFlagCondition',
+ sem_class:Optional[SemanticClassType], il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILFlagCondition cond:
+ :param SemanticClassType sem_class:
:param LowLevelILFunction il:
- :param str sem_class:
:rtype: LowLevelILExpr
"""
- class_index = self.get_semantic_flag_class_index(sem_class)
- return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagConditionLowLevelIL(self.handle, cond, class_index, il.handle))
+ _class_index = None
+ if sem_class is not None:
+ _class_index = self.get_semantic_flag_class_index(sem_class)
+ return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagConditionLowLevelIL(self.handle, cond,
+ _class_index, il.handle))
- def get_semantic_flag_group_low_level_il(self, sem_group, il):
+ def get_semantic_flag_group_low_level_il(self, sem_group:Optional[SemanticGroupType],
+ il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
- :param str sem_group:
+ :param Optional[SemanticGroupType] sem_group:
:param LowLevelILFunction il:
:rtype: LowLevelILExpr
"""
- return self.perform_get_semantic_flag_group_low_level_il(sem_group, il)
+ return il.unimplemented()
- def get_flags_required_for_flag_condition(self, cond, sem_class = None):
- return self.perform_get_flags_required_for_flag_condition(cond, sem_class)
+ def get_flags_required_for_flag_condition(self, cond:'lowlevelil.LowLevelILFlagCondition',
+ sem_class:Optional[SemanticClassType]=None):
+ if cond in self.flags_required_for_flag_condition:
+ return self.flags_required_for_flag_condition[cond]
+ return []
- def get_modified_regs_on_write(self, reg):
+ def get_modified_regs_on_write(self, reg:RegisterName) -> List[RegisterName]:
"""
``get_modified_regs_on_write`` returns a list of register names that are modified when ``reg`` is written.
@@ -1788,13 +1865,14 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
reg = core.BNGetArchitectureRegisterByName(self.handle, str(reg))
count = ctypes.c_ulonglong()
regs = core.BNGetModifiedArchitectureRegistersOnWrite(self.handle, reg, count)
+ assert regs is not None, "core.BNGetModifiedArchitectureRegistersOnWrite is not None"
result = []
for i in range(0, count.value):
result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
core.BNFreeRegisterList(regs)
return result
- def assemble(self, code, addr=0):
+ def assemble(self, code:str, addr:int=0) -> bytes:
"""
``assemble`` converts the string of assembly instructions ``code`` loaded at virtual address ``addr`` to the
byte representation of those instructions.
@@ -1819,9 +1897,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
b'\\x0f\\x84\\x04\\x00\\x00\\x00'
>>>
"""
- return self.perform_assemble(code, addr)
+ return NotImplemented
- def is_never_branch_patch_available(self, data, addr):
+ def is_never_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_never_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be made to **never branch**.
@@ -1839,9 +1917,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
False
>>>
"""
- return self.perform_is_never_branch_patch_available(data, addr)
+ return NotImplemented
- def is_always_branch_patch_available(self, data, addr):
+ def is_always_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_always_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be made to
**always branch**.
@@ -1860,9 +1938,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
False
>>>
"""
- return self.perform_is_always_branch_patch_available(data, addr)
+ return NotImplemented
- def is_invert_branch_patch_available(self, data, addr):
+ def is_invert_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_always_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be inverted.
@@ -1880,9 +1958,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
False
>>>
"""
- return self.perform_is_invert_branch_patch_available(data, addr)
+ return NotImplemented
- def is_skip_and_return_zero_patch_available(self, data, addr):
+ def is_skip_and_return_zero_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_skip_and_return_zero_patch_available`` determines if the instruction ``data`` at ``addr`` is a *call-like*
instruction that can be made into an instruction *returns zero*.
@@ -1903,9 +1981,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
False
>>>
"""
- return self.perform_is_skip_and_return_zero_patch_available(data, addr)
+ return NotImplemented
- def is_skip_and_return_value_patch_available(self, data, addr):
+ def is_skip_and_return_value_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_skip_and_return_value_patch_available`` determines if the instruction ``data`` at ``addr`` is a *call-like*
instruction that can be made into an instruction *returns a value*.
@@ -1924,9 +2002,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
False
>>>
"""
- return self.perform_is_skip_and_return_value_patch_available(data, addr)
+ return NotImplemented
- def convert_to_nop(self, data, addr):
+ def convert_to_nop(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``convert_to_nop`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of nop
instructions of the same length as data.
@@ -1943,9 +2021,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
b'\\x90\\x90'
>>>
"""
- return self.perform_convert_to_nop(data, addr)
+ return NotImplemented
- def always_branch(self, data, addr):
+ def always_branch(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``always_branch`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of bytes
of the same length which always branches.
@@ -1965,9 +2043,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
(['jmp', ' ', '0x9'], 5)
>>>
"""
- return self.perform_always_branch(data, addr)
+ return NotImplemented
- def invert_branch(self, data, addr):
+ def invert_branch(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``invert_branch`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of bytes
of the same length which inverts the branch of provided instruction.
@@ -1988,9 +2066,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
(['jl', ' ', '0xa'], 6)
>>>
"""
- return self.perform_invert_branch(data, addr)
+ return NotImplemented
- def skip_and_return_value(self, data, addr, value):
+ def skip_and_return_value(self, data:bytes, addr:int, value:int) -> Optional[bytes]:
"""
``skip_and_return_value`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of
bytes of the same length which doesn't call and instead *return a value*.
@@ -2007,9 +2085,9 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
(['mov', ' ', 'eax', ', ', '0x0'], 5)
>>>
"""
- return self.perform_skip_and_return_value(data, addr, value)
+ return NotImplemented
- def is_view_type_constant_defined(self, type_name, const_name):
+ def is_view_type_constant_defined(self, type_name:str, const_name:str) -> bool:
"""
:param str type_name: the BinaryView type name of the constant to query
@@ -2027,7 +2105,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
return core.BNIsBinaryViewTypeArchitectureConstantDefined(self.handle, type_name, const_name)
- def get_view_type_constant(self, type_name, const_name, default_value=0):
+ def get_view_type_constant(self, type_name:str, const_name:str, default_value:int=0) -> int:
"""
``get_view_type_constant`` retrieves the view type constant for the given type_name and const_name.
@@ -2047,7 +2125,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
return core.BNGetBinaryViewTypeArchitectureConstant(self.handle, type_name, const_name, default_value)
- def set_view_type_constant(self, type_name, const_name, value):
+ def set_view_type_constant(self, type_name:str, const_name:str, value:int) -> None:
"""
``set_view_type_constant`` creates a new binaryview type constant.
@@ -2063,7 +2141,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
core.BNSetBinaryViewTypeArchitectureConstant(self.handle, type_name, const_name, value)
- def register_calling_convention(self, cc):
+ def register_calling_convention(self, cc:'callingconvention.CallingConvention') -> None:
"""
``register_calling_convention`` registers a new calling convention for the Architecture.
@@ -2075,54 +2153,57 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
_architecture_cache = {}
class CoreArchitecture(Architecture):
- def __init__(self, handle):
+ def __init__(self, handle:core.BNArchitecture):
super(CoreArchitecture, self).__init__()
self.handle = core.handle_of_type(handle, core.BNArchitecture)
- self.__dict__["name"] = core.BNGetArchitectureName(self.handle)
- self.__dict__["endianness"] = Endianness(core.BNGetArchitectureEndianness(self.handle))
- self.__dict__["address_size"] = core.BNGetArchitectureAddressSize(self.handle)
- self.__dict__["default_int_size"] = core.BNGetArchitectureDefaultIntegerSize(self.handle)
- self.__dict__["instr_alignment"] = core.BNGetArchitectureInstructionAlignment(self.handle)
- self.__dict__["max_instr_length"] = core.BNGetArchitectureMaxInstructionLength(self.handle)
- self.__dict__["opcode_display_length"] = core.BNGetArchitectureOpcodeDisplayLength(self.handle)
- self.__dict__["stack_pointer"] = core.BNGetArchitectureRegisterName(self.handle,
+ self.name = core.BNGetArchitectureName(self.handle)
+ self.endianness = Endianness(core.BNGetArchitectureEndianness(self.handle))
+ self.address_size = core.BNGetArchitectureAddressSize(self.handle)
+ self.default_int_size = core.BNGetArchitectureDefaultIntegerSize(self.handle)
+ self.instr_alignment = core.BNGetArchitectureInstructionAlignment(self.handle)
+ self.max_instr_length = core.BNGetArchitectureMaxInstructionLength(self.handle)
+ self.opcode_display_length = core.BNGetArchitectureOpcodeDisplayLength(self.handle)
+ self.stack_pointer:str = core.BNGetArchitectureRegisterName(self.handle,
core.BNGetArchitectureStackPointerRegister(self.handle))
link_reg = core.BNGetArchitectureLinkRegister(self.handle)
if link_reg == 0xffffffff:
- self.__dict__["link_reg"] = None
+ self.link_reg = None
else:
- self.__dict__["link_reg"] = core.BNGetArchitectureRegisterName(self.handle, link_reg)
+ self.link_reg = core.BNGetArchitectureRegisterName(self.handle, link_reg)
count = ctypes.c_ulonglong()
regs = core.BNGetAllArchitectureRegisters(self.handle, count)
+ assert regs is not None, "core.BNGetAllArchitectureRegisters returned None"
self._all_regs = {}
self._regs_by_index = {}
self._full_width_regs = {}
- self.__dict__["regs"] = {}
+ self.regs = {}
for i in range(0, count.value):
- name = core.BNGetArchitectureRegisterName(self.handle, regs[i])
+ name = RegisterName(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
+ assert name is not None, ""
info = core.BNGetArchitectureRegisterInfo(self.handle, regs[i])
- full_width_reg = core.BNGetArchitectureRegisterName(self.handle, info.fullWidthRegister)
- self.regs[name] = binaryninja.function.RegisterInfo(full_width_reg, info.size, info.offset,
+ full_width_reg = RegisterName(core.BNGetArchitectureRegisterName(self.handle, info.fullWidthRegister))
+ self.regs[name] = RegisterInfo(full_width_reg, info.size, info.offset,
ImplicitRegisterExtend(info.extend), regs[i])
self._all_regs[name] = regs[i]
self._regs_by_index[regs[i]] = name
for i in range(0, count.value):
info = core.BNGetArchitectureRegisterInfo(self.handle, regs[i])
- full_width_reg = core.BNGetArchitectureRegisterName(self.handle, info.fullWidthRegister)
+ full_width_reg = RegisterName(core.BNGetArchitectureRegisterName(self.handle, info.fullWidthRegister))
if full_width_reg not in self._full_width_regs:
self._full_width_regs[full_width_reg] = self._all_regs[full_width_reg]
core.BNFreeRegisterList(regs)
count = ctypes.c_ulonglong()
flags = core.BNGetAllArchitectureFlags(self.handle, count)
+ assert flags is not None, "core.BNGetAllArchitectureFlags returned None"
self._flags = {}
self._flags_by_index = {}
- self.__dict__["flags"] = []
+ self.flags = []
for i in range(0, count.value):
- name = core.BNGetArchitectureFlagName(self.handle, flags[i])
+ name = FlagName(core.BNGetArchitectureFlagName(self.handle, flags[i]))
self._flags[name] = flags[i]
self._flags_by_index[flags[i]] = name
self.flags.append(name)
@@ -2130,11 +2211,12 @@ class CoreArchitecture(Architecture):
count = ctypes.c_ulonglong()
write_types = core.BNGetAllArchitectureFlagWriteTypes(self.handle, count)
- self._flag_write_types = {}
+ assert write_types is not None, "core.BNGetAllArchitectureFlagWriteTypes returned None"
+ self._flag_write_types:Mapping[str, FlagWriteTypeIndex] = {}
self._flag_write_types_by_index = {}
- self.__dict__["flag_write_types"] = []
+ self.flag_write_types = []
for i in range(0, count.value):
- name = core.BNGetArchitectureFlagWriteTypeName(self.handle, write_types[i])
+ name = FlagWriteTypeName(core.BNGetArchitectureFlagWriteTypeName(self.handle, write_types[i]))
self._flag_write_types[name] = write_types[i]
self._flag_write_types_by_index[write_types[i]] = name
self.flag_write_types.append(name)
@@ -2142,11 +2224,12 @@ class CoreArchitecture(Architecture):
count = ctypes.c_ulonglong()
sem_classes = core.BNGetAllArchitectureSemanticFlagClasses(self.handle, count)
+ assert sem_classes is not None,"core.BNGetAllArchitectureSemanticFlagClasses returned None"
self._semantic_flag_classes = {}
self._semantic_flag_classes_by_index = {}
- self.__dict__["semantic_flag_classes"] = []
+ self.semantic_flag_classes = []
for i in range(0, count.value):
- name = core.BNGetArchitectureSemanticFlagClassName(self.handle, sem_classes[i])
+ name = SemanticClassName(core.BNGetArchitectureSemanticFlagClassName(self.handle, sem_classes[i]))
self._semantic_flag_classes[name] = sem_classes[i]
self._semantic_flag_classes_by_index[sem_classes[i]] = name
self.semantic_flag_classes.append(name)
@@ -2154,39 +2237,42 @@ class CoreArchitecture(Architecture):
count = ctypes.c_ulonglong()
sem_groups = core.BNGetAllArchitectureSemanticFlagGroups(self.handle, count)
+ assert sem_groups is not None,"core.BNGetAllArchitectureSemanticFlagGroups returned Non"
self._semantic_flag_groups = {}
self._semantic_flag_groups_by_index = {}
- self.__dict__["semantic_flag_groups"] = []
+ self.semantic_flag_groups = []
for i in range(0, count.value):
- name = core.BNGetArchitectureSemanticFlagGroupName(self.handle, sem_groups[i])
+ name = SemanticGroupName(core.BNGetArchitectureSemanticFlagGroupName(self.handle, sem_groups[i]))
self._semantic_flag_groups[name] = sem_groups[i]
self._semantic_flag_groups_by_index[sem_groups[i]] = name
self.semantic_flag_groups.append(name)
core.BNFreeRegisterList(sem_groups)
self._flag_roles = {}
- self.__dict__["flag_roles"] = {}
- for flag in self.__dict__["flags"]:
+ self.flag_roles = {}
+ for flag in self.flags:
role = FlagRole(core.BNGetArchitectureFlagRole(self.handle, self._flags[flag], 0))
- self.__dict__["flag_roles"][flag] = role
+ self.flag_roles[flag] = role
self._flag_roles[self._flags[flag]] = role
- self.__dict__["flags_required_for_flag_condition"] = {}
+ self.flags_required_for_flag_condition:Mapping[LowLevelILFlagCondition, List[FlagName]] = {}
for cond in LowLevelILFlagCondition:
count = ctypes.c_ulonglong()
flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, 0, count)
+ assert flags is not None, "core.BNGetArchitectureFlagsRequiredForFlagCondition returned None"
flag_names = []
for i in range(0, count.value):
flag_names.append(self._flags_by_index[flags[i]])
core.BNFreeRegisterList(flags)
- self.__dict__["flags_required_for_flag_condition"][cond] = flag_names
+ self.flags_required_for_flag_condition[cond] = flag_names
self._flags_required_by_semantic_flag_group = {}
- self.__dict__["flags_required_for_semantic_flag_group"] = {}
+ self.flags_required_for_semantic_flag_group = {}
for group in self.semantic_flag_groups:
count = ctypes.c_ulonglong()
flags = core.BNGetArchitectureFlagsRequiredForSemanticFlagGroup(self.handle,
self._semantic_flag_groups[group], count)
+ assert flags is not None, "core.BNGetArchitectureFlagsRequiredForSemanticFlagGroup returned None"
flag_indexes = []
flag_names = []
for i in range(0, count.value):
@@ -2194,14 +2280,15 @@ class CoreArchitecture(Architecture):
flag_names.append(self._flags_by_index[flags[i]])
core.BNFreeRegisterList(flags)
self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flag_indexes
- self.__dict__["flags_required_for_semantic_flag_group"][cond] = flag_names
+ self.flags_required_for_semantic_flag_group[group] = flag_names
self._flag_conditions_for_semantic_flag_group = {}
- self.__dict__["flag_conditions_for_semantic_flag_group"] = {}
+ self.flag_conditions_for_semantic_flag_group = {}
for group in self.semantic_flag_groups:
count = ctypes.c_ulonglong()
conditions = core.BNGetArchitectureFlagConditionsForSemanticFlagGroup(self.handle,
self._semantic_flag_groups[group], count)
+ assert conditions is not None, "core.BNGetArchitectureFlagConditionsForSemanticFlagGroup returned None"
class_index_cond = {}
class_cond = {}
for i in range(0, count.value):
@@ -2212,14 +2299,15 @@ class CoreArchitecture(Architecture):
class_cond[self._semantic_flag_classes_by_index[conditions[i].semanticClass]] = conditions[i].condition
core.BNFreeFlagConditionsForSemanticFlagGroup(conditions)
self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_index_cond
- self.__dict__["flag_conditions_for_semantic_flag_group"][group] = class_cond
+ self.flag_conditions_for_semantic_flag_group[group] = class_cond
self._flags_written_by_flag_write_type = {}
- self.__dict__["flags_written_by_flag_write_type"] = {}
+ self.flags_written_by_flag_write_type = {}
for write_type in self.flag_write_types:
count = ctypes.c_ulonglong()
flags = core.BNGetArchitectureFlagsWrittenByFlagWriteType(self.handle,
self._flag_write_types[write_type], count)
+ assert flags is not None, "core.BNGetArchitectureFlagsWrittenByFlagWriteType returned None"
flag_indexes = []
flag_names = []
for i in range(0, count.value):
@@ -2227,10 +2315,10 @@ class CoreArchitecture(Architecture):
flag_names.append(self._flags_by_index[flags[i]])
core.BNFreeRegisterList(flags)
self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flag_indexes
- self.__dict__["flags_written_by_flag_write_type"][write_type] = flag_names
+ self.flags_written_by_flag_write_type[write_type] = flag_names
self._semantic_class_for_flag_write_type = {}
- self.__dict__["semantic_class_for_flag_write_type"] = {}
+ self.semantic_class_for_flag_write_type = {}
for write_type in self.flag_write_types:
sem_class = core.BNGetArchitectureSemanticClassForFlagWriteType(self.handle,
self._flag_write_types[write_type])
@@ -2239,83 +2327,90 @@ class CoreArchitecture(Architecture):
else:
sem_class_name = self._semantic_flag_classes_by_index[sem_class]
self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class
- self.__dict__["semantic_class_for_flag_write_type"][write_type] = sem_class_name
+ self.semantic_class_for_flag_write_type[write_type] = sem_class_name
count = ctypes.c_ulonglong()
regs = core.BNGetArchitectureGlobalRegisters(self.handle, count)
- self.__dict__["global_regs"] = []
+ assert regs is not None, "core.BNGetArchitectureGlobalRegisters returned None"
+ self.global_regs:List[RegisterName] = []
for i in range(0, count.value):
- self.global_regs.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
+ self.global_regs.append(RegisterName(core.BNGetArchitectureRegisterName(self.handle, regs[i])))
core.BNFreeRegisterList(regs)
count = ctypes.c_ulonglong()
regs = core.BNGetArchitectureSystemRegisters(self.handle, count)
- self.__dict__["system_regs"] = []
+ self.system_regs:List[RegisterName] = []
for i in range(0, count.value):
- self.system_regs.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
+ assert regs is not None, "core.BNGetArchitectureSystemRegisters returned None"
+ self.system_regs.append(RegisterName(core.BNGetArchitectureRegisterName(self.handle, regs[i])))
core.BNFreeRegisterList(regs)
count = ctypes.c_ulonglong()
regs = core.BNGetAllArchitectureRegisterStacks(self.handle, count)
+ assert regs is not None, "core.BNGetAllArchitectureRegisterStacks returned None"
self._all_reg_stacks = {}
self._reg_stacks_by_index = {}
- self.__dict__["reg_stacks"] = {}
+ self.reg_stacks = {}
for i in range(0, count.value):
- name = core.BNGetArchitectureRegisterStackName(self.handle, regs[i])
+ name = RegisterStackName(core.BNGetArchitectureRegisterStackName(self.handle, regs[i]))
info = core.BNGetArchitectureRegisterStackInfo(self.handle, regs[i])
storage = []
for j in range(0, info.storageCount):
storage.append(core.BNGetArchitectureRegisterName(self.handle, info.firstStorageReg + j))
- top_rel = []
+ top_rel:List[RegisterName] = []
for j in range(0, info.topRelativeCount):
- top_rel.append(core.BNGetArchitectureRegisterName(self.handle, info.firstTopRelativeReg + j))
+ reg_name = RegisterName(core.BNGetArchitectureRegisterName(self.handle, info.firstTopRelativeReg + j))
+ top_rel.append(reg_name)
top = core.BNGetArchitectureRegisterName(self.handle, info.stackTopReg)
- self.reg_stacks[name] = binaryninja.function.RegisterStackInfo(storage, top_rel, top, regs[i])
+ self.reg_stacks[name] = RegisterStackInfo(storage, top_rel, RegisterName(top), regs[i])
self._all_reg_stacks[name] = regs[i]
self._reg_stacks_by_index[regs[i]] = name
core.BNFreeRegisterList(regs)
count = ctypes.c_ulonglong()
intrinsics = core.BNGetAllArchitectureIntrinsics(self.handle, count)
- self._intrinsics = {}
- self._intrinsics_by_index = {}
- self.__dict__["intrinsics"] = {}
- for i in range(0, count.value):
- name = core.BNGetArchitectureIntrinsicName(self.handle, intrinsics[i])
+ assert intrinsics is not None, "core.BNGetAllArchitectureIntrinsics returned None"
+ self._intrinsics:Mapping[IntrinsicName, IntrinsicIndex] = {}
+ self._intrinsics_by_index:Mapping[IntrinsicIndex, Tuple[IntrinsicName, IntrinsicInfo]] = {}
+ self._intrinsics_info:Mapping[IntrinsicName, IntrinsicInfo] = {}
+ for i in range(count.value):
+ name = IntrinsicName(core.BNGetArchitectureIntrinsicName(self.handle, intrinsics[i]))
input_count = ctypes.c_ulonglong()
inputs = core.BNGetArchitectureIntrinsicInputs(self.handle, intrinsics[i], input_count)
+ assert inputs is not None, "core.BNGetArchitectureIntrinsicInputs returned None"
input_list = []
for j in range(0, input_count.value):
input_name = inputs[j].name
type_obj = types.Type(core.BNNewTypeReference(inputs[j].type), confidence = inputs[j].typeConfidence)
- input_list.append(binaryninja.function.IntrinsicInput(type_obj, input_name))
+ input_list.append(IntrinsicInput(type_obj, input_name))
core.BNFreeNameAndTypeList(inputs, input_count.value)
output_count = ctypes.c_ulonglong()
outputs = core.BNGetArchitectureIntrinsicOutputs(self.handle, intrinsics[i], output_count)
+ assert outputs is not None, "core.BNGetArchitectureIntrinsicOutputs returned None"
output_list = []
- for j in range(0, output_count.value):
+ for j in range(output_count.value):
output_list.append(types.Type(core.BNNewTypeReference(outputs[j].type), confidence = outputs[j].confidence))
core.BNFreeOutputTypeList(outputs, output_count.value)
- self.intrinsics[name] = binaryninja.function.IntrinsicInfo(input_list, output_list)
+ self._intrinsics_info[name] = IntrinsicInfo(input_list, output_list)
self._intrinsics[name] = intrinsics[i]
- self._intrinsics_by_index[intrinsics[i]] = (name, self.intrinsics[name])
+ self._intrinsics_by_index[intrinsics[i]] = (name, self._intrinsics_info[name])
core.BNFreeRegisterList(intrinsics)
if type(self) is CoreArchitecture:
global _architecture_cache
_architecture_cache[ctypes.addressof(handle.contents)] = self
@classmethod
- def _from_cache(cls, handle):
+ def _from_cache(cls, handle) -> 'Architecture':
global _architecture_cache
return _architecture_cache.get(ctypes.addressof(handle.contents)) or cls(handle)
- def get_associated_arch_by_address(self, addr):
+ def get_associated_arch_by_address(self, addr:int) -> Tuple['Architecture', int]:
new_addr = ctypes.c_ulonglong()
new_addr.value = addr
result = core.BNGetAssociatedArchitectureByAddress(self.handle, new_addr)
return CoreArchitecture._from_cache(handle = result), new_addr.value
- def get_instruction_info(self, data, addr):
+ def get_instruction_info(self, data:Union[bytes, str], addr:int) -> Optional[InstructionInfo]:
"""
``get_instruction_info`` returns an InstructionInfo object for the instruction at the given virtual address
``addr`` with data ``data``.
@@ -2328,12 +2423,17 @@ class CoreArchitecture(Architecture):
:return: the InstructionInfo for the current instruction
:rtype: InstructionInfo
"""
+ if not isinstance(data, bytes):
+ if isinstance(data, str):
+ data=data.encode()
+ else:
+ raise TypeError("Must be bytes or str")
info = core.BNInstructionInfo()
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNGetInstructionInfo(self.handle, buf, addr, len(data), info):
return None
- result = binaryninja.function.InstructionInfo()
+ result = InstructionInfo()
result.length = info.length
result.arch_transition_by_target_addr = info.archTransitionByTargetAddr
result.branch_delay = info.branchDelay
@@ -2346,7 +2446,7 @@ class CoreArchitecture(Architecture):
result.add_branch(BranchType(info.branchType[i]), target, arch)
return result
- def get_instruction_text(self, data, addr):
+ def get_instruction_text(self, data:bytes, addr:int) -> Tuple[List['function.InstructionTextToken'], int]:
"""
``get_instruction_text`` returns a list of InstructionTextToken objects for the instruction at the given virtual
address ``addr`` with data ``data``.
@@ -2367,13 +2467,15 @@ class CoreArchitecture(Architecture):
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
tokens = ctypes.POINTER(core.BNInstructionTextToken)()
- if not core.BNGetInstructionText(self.handle, buf, addr, length, tokens, count):
- return None, 0
- result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
- core.BNFreeInstructionText(tokens, count.value)
- return result, length.value
+ result = []
+ result_length = 0
+ if core.BNGetInstructionText(self.handle, buf, addr, length, tokens, count):
+ result = function.InstructionTextToken._from_core_struct(tokens, count.value)
+ result_length = length.value
+ core.BNFreeInstructionText(tokens, count.value)
+ return result, result_length
- def get_instruction_low_level_il(self, data, addr, il):
+ def get_instruction_low_level_il(self, data:Union[bytes, str], addr:int, il:lowlevelil.LowLevelILFunction) -> int:
"""
``get_instruction_low_level_il`` appends LowLevelILExpr objects to ``il`` for the instruction at the given
virtual address ``addr`` with data ``data``.
@@ -2381,20 +2483,27 @@ class CoreArchitecture(Architecture):
This is used to analyze arbitrary data at an address, if you are working with an existing binary, you likely
want to be using :func:`Function.get_low_level_il_at`.
- :param str data: max_instruction_length bytes from the binary at virtual address ``addr``
+ :param str|bytes data: max_instruction_length bytes from the binary at virtual address ``addr``
:param int addr: virtual address of bytes in ``data``
:param LowLevelILFunction il: The function the current instruction belongs to
:return: the length of the current instruction
:rtype: int
"""
+ if not isinstance(data, bytes):
+ if isinstance(data, str):
+ data=data.encode()
+ else:
+ raise TypeError("Must be bytes or str")
length = ctypes.c_ulonglong()
length.value = len(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
- core.BNGetInstructionLowLevelIL(self.handle, buf, addr, length, il.handle)
+ if not core.BNGetInstructionLowLevelIL(self.handle, buf, addr, length, il.handle):
+ raise Exception("BNGetInstructionLowLevelIL failed")
return length.value
- def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
+ def get_flag_write_low_level_il(self, op:LowLevelILOperation, size:int, write_type:FlagWriteTypeName,
+ flag:FlagType, operands:List['lowlevelil.ILRegisterType'], il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILOperation op:
:param int size:
@@ -2407,19 +2516,21 @@ class CoreArchitecture(Architecture):
flag = self.get_flag_index(flag)
operand_list = (core.BNRegisterOrConstant * len(operands))()
for i in range(len(operands)):
- if isinstance(operands[i], str):
+ operand = operands[i]
+ if isinstance(operand, RegisterName):
operand_list[i].constant = False
- operand_list[i].reg = self.regs[operands[i]].index
- elif isinstance(operands[i], lowlevelil.ILRegister):
+ operand_list[i].reg = self.regs[operand].index
+ elif isinstance(operand, lowlevelil.ILRegister):
operand_list[i].constant = False
- operand_list[i].reg = operands[i].index
+ operand_list[i].reg = operand.index
else:
operand_list[i].constant = True
- operand_list[i].value = operands[i]
+ operand_list[i].value = operand
return lowlevelil.LowLevelILExpr(core.BNGetArchitectureFlagWriteLowLevelIL(self.handle, op, size,
self._flag_write_types[write_type], flag, operand_list, len(operand_list), il.handle))
- def get_flag_condition_low_level_il(self, cond, sem_class, il):
+ def get_flag_condition_low_level_il(self, cond:LowLevelILFlagCondition, sem_class:SemanticClassType,
+ il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param LowLevelILFlagCondition cond: Flag condition to be computed
:param str sem_class: Semantic class to be used (None for default semantics)
@@ -2430,7 +2541,8 @@ class CoreArchitecture(Architecture):
return lowlevelil.LowLevelILExpr(core.BNGetArchitectureFlagConditionLowLevelIL(self.handle, cond,
class_index, il.handle))
- def get_semantic_flag_group_low_level_il(self, sem_group, il):
+ def get_semantic_flag_group_low_level_il(self, sem_group:SemanticGroupName,
+ il:'lowlevelil.LowLevelILFunction') -> 'lowlevelil.LowLevelILExpr':
"""
:param str sem_group:
:param LowLevelILFunction il:
@@ -2439,7 +2551,7 @@ class CoreArchitecture(Architecture):
group_index = self.get_semantic_flag_group_index(sem_group)
return lowlevelil.LowLevelILExpr(core.BNGetArchitectureSemanticFlagGroupLowLevelIL(self.handle, group_index, il.handle))
- def assemble(self, code, addr=0):
+ def assemble(self, code:str, addr:int=0) -> bytes:
"""
``assemble`` converts the string of assembly instructions ``code`` loaded at virtual address ``addr`` to the
byte representation of those instructions.
@@ -2460,12 +2572,9 @@ class CoreArchitecture(Architecture):
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
raise ValueError("Could not assemble: %s" % error_str)
- if isinstance(str(result), bytes):
- return str(result)
- else:
- return bytes(result)
+ return bytes(result)
- def is_never_branch_patch_available(self, data, addr):
+ def is_never_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_never_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be made to **never branch**.
@@ -2485,7 +2594,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureNeverBranchPatchAvailable(self.handle, buf, addr, len(data))
- def is_always_branch_patch_available(self, data, addr):
+ def is_always_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_always_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be made to
**always branch**.
@@ -2506,7 +2615,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureAlwaysBranchPatchAvailable(self.handle, buf, addr, len(data))
- def is_invert_branch_patch_available(self, data, addr):
+ def is_invert_branch_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_always_branch_patch_available`` determines if the instruction ``data`` at ``addr`` can be inverted.
@@ -2526,7 +2635,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureInvertBranchPatchAvailable(self.handle, buf, addr, len(data))
- def is_skip_and_return_zero_patch_available(self, data, addr):
+ def is_skip_and_return_zero_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_skip_and_return_zero_patch_available`` determines if the instruction ``data`` at ``addr`` is a *call-like*
instruction that can be made into an instruction *returns zero*.
@@ -2549,7 +2658,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureSkipAndReturnZeroPatchAvailable(self.handle, buf, addr, len(data))
- def is_skip_and_return_value_patch_available(self, data, addr):
+ def is_skip_and_return_value_patch_available(self, data:bytes, addr:int=0) -> bool:
"""
``is_skip_and_return_value_patch_available`` determines if the instruction ``data`` at ``addr`` is a *call-like*
instruction that can be made into an instruction *returns a value*.
@@ -2570,7 +2679,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureSkipAndReturnValuePatchAvailable(self.handle, buf, addr, len(data))
- def convert_to_nop(self, data, addr):
+ def convert_to_nop(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``convert_to_nop`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of nop
instructions of the same length as data.
@@ -2593,7 +2702,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(result, buf, len(data))
return result.raw
- def always_branch(self, data, addr):
+ def always_branch(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``always_branch`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of bytes
of the same length which always branches.
@@ -2619,7 +2728,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(result, buf, len(data))
return result.raw
- def invert_branch(self, data, addr):
+ def invert_branch(self, data:bytes, addr:int=0) -> Optional[bytes]:
"""
``invert_branch`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of bytes
of the same length which inverts the branch of provided instruction.
@@ -2646,7 +2755,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(result, buf, len(data))
return result.raw
- def skip_and_return_value(self, data, addr, value):
+ def skip_and_return_value(self, data:bytes, addr:int, value:int) -> Optional[bytes]:
"""
``skip_and_return_value`` reads the instruction(s) in ``data`` at virtual address ``addr`` and returns a string of
bytes of the same length which doesn't call and instead *return a value*.
@@ -2669,7 +2778,7 @@ class CoreArchitecture(Architecture):
ctypes.memmove(result, buf, len(data))
return result.raw
- def get_flag_role(self, flag, sem_class = None):
+ def get_flag_role(self, flag:FlagIndex, sem_class:Optional[SemanticClassIndex]= None) -> FlagRole:
"""
``get_flag_role`` gets the role of a given flag.
@@ -2679,13 +2788,19 @@ class CoreArchitecture(Architecture):
:rtype: FlagRole
"""
flag = self.get_flag_index(flag)
- sem_class = self.get_semantic_flag_class_index(sem_class)
- return FlagRole(core.BNGetArchitectureFlagRole(self.handle, flag, sem_class))
+ _sem_class = None
+ if sem_class is not None:
+ _sem_class = self.get_semantic_flag_class_index(sem_class)
+ return FlagRole(core.BNGetArchitectureFlagRole(self.handle, flag, _sem_class))
- def get_flags_required_for_flag_condition(self, cond, sem_class = None):
- sem_class = self.get_semantic_flag_class_index(sem_class)
+ def get_flags_required_for_flag_condition(self, cond:LowLevelILFlagCondition,
+ sem_class:Optional[SemanticClassType]=None) -> List[FlagName]:
+ _sem_class = None
+ if sem_class is not None:
+ _sem_class = self.get_semantic_flag_class_index(sem_class)
count = ctypes.c_ulonglong()
- flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, sem_class, count)
+ flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, _sem_class, count)
+ assert flags is not None, "core.BNGetArchitectureFlagsRequiredForFlagCondition returned None"
flag_names = []
for i in range(0, count.value):
flag_names.append(self._flags_by_index[flags[i]])
@@ -2694,7 +2809,7 @@ class CoreArchitecture(Architecture):
class ArchitectureHook(CoreArchitecture):
- def __init__(self, base_arch):
+ def __init__(self, base_arch:'Architecture'):
self._base_arch = base_arch
super(ArchitectureHook, self).__init__(base_arch.handle)
@@ -2728,198 +2843,9 @@ class ArchitectureHook(CoreArchitecture):
core.BNFinalizeArchitectureHook(self._base_arch.handle)
@property
- def base_arch(self):
- """ """
+ def base_arch(self) -> 'Architecture':
return self._base_arch
@base_arch.setter
- def base_arch(self, value):
+ def base_arch(self, value:'Architecture') -> None:
self._base_arch = value
-
-
-class ReferenceSource(object):
- def __init__(self, func, arch, addr):
- self._function = func
- self._arch = arch
- self._address = addr
-
- def __repr__(self):
- if self._arch:
- return "<ref: %s@%#x>" % (self._arch.name, self._address)
- else:
- return "<ref: %#x>" % self._address
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return (self.function, self.arch, self.address) == (other.function, other.arch, other.address)
-
- def __ne__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return not (self == other)
-
- def __lt__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return self.address < other.address
-
- def __gt__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return self.address > other.address
-
- def __ge__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return self.address >= other.address
-
- def __le__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return self.address <= other.address
-
- def __hash__(self):
- return hash((self._function, self._arch, self._address))
-
- @property
- def function(self):
- """ """
- return self._function
-
- @function.setter
- def function(self, value):
- self._function = value
-
- @property
- def arch(self):
- """ """
- return self._arch
-
- @arch.setter
- def arch(self, value):
- self._arch = value
-
- @property
- def address(self):
- """ """
- return self._address
-
- @address.setter
- def address(self, value):
- self._address = value
-
-
-class TypeFieldReference(object):
- def __init__(self, func, arch, addr, size, t):
- self._function = func
- self._arch = arch
- self._address = addr
- self._size = size
- self._incomingType = t
-
- def __repr__(self):
- if self._arch:
- return "<ref: %s@%#x, size: %#x, type: %s>" % (self._arch.name, self._address, self._size,\
- self._incomingType)
- else:
- return "<ref: %#x, size: %#x, type: %s>" % (self._address, self._size, self._incomingType)
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return (self.function, self.arch, self.address, self._size, self._incomingType) ==\
- (other.function, other.arch, other.address, other.size, other.incomingType)
-
- def __ne__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return not (self == other)
-
- def __lt__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- if self.address < other.address:
- return True
- elif self.address > other.address:
- return False
- else:
- return self.size < other.size
-
- def __gt__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- if self.address > other.address:
- return True
- elif self.address < other.address:
- return False
- else:
- return self.size > other.size
-
- def __ge__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- if self.address > other.address:
- return True
- elif self.address < other.address:
- return False
- else:
- return self.size >= other.size
-
- def __le__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- if self.address < other.address:
- return True
- elif self.address > other.address:
- return False
- else:
- return self.size <= other.size
-
- def __hash__(self):
- return hash((self._function, self._arch, self._address, self._size, self._incomingType))
-
- @property
- def function(self):
- """ """
- return self._function
-
- @function.setter
- def function(self, value):
- self._function = value
-
- @property
- def arch(self):
- """ """
- return self._arch
-
- @arch.setter
- def arch(self, value):
- self._arch = value
-
- @property
- def address(self):
- """ """
- return self._address
-
- @address.setter
- def address(self, value):
- self._address = value
-
- @property
- def size(self):
- """ """
- return self._size
-
- @size.setter
- def size(self, value):
- self._size = value
-
- @property
- def incomingType(self):
- """ """
- return self._incomingType
-
- @size.setter
- def incomingType(self, value):
- self._incomingType = value