summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2020-05-02 11:01:35 -0400
committerPeter LaFosse <peter@vector35.com>2020-05-03 13:20:56 -0400
commit8f1bc5944b849f3ad0cbbd5972d5ab9948ed4d57 (patch)
tree43b48da8a1ec93b148575bc3346059e5316e6bf6 /python/lowlevelil.py
parent5b84fdea8abcb4abba61d07e0d12b4115b516c52 (diff)
Fix up equality operators and had hash operators
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py380
1 files changed, 247 insertions, 133 deletions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index ca00f769..17536beb 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -54,16 +54,24 @@ class ILRegister(object):
def info(self):
return self._arch.regs[self._name]
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return self.info == other.info
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
@property
def arch(self):
@@ -112,16 +120,24 @@ class ILRegisterStack(object):
def info(self):
return self._arch.reg_stacks[self._name]
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return self.info == other.info
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
@property
def arch(self):
@@ -161,12 +177,25 @@ class ILFlag(object):
else:
self._name = self._arch.get_flag_name(self._index)
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
+
@property
def arch(self):
""" """
@@ -210,16 +239,24 @@ class ILSemanticFlagClass(object):
self._index = sem_class
self._name = self._arch.get_semantic_flag_class_name(self._index)
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return self._index == other._index
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
@property
def arch(self):
@@ -255,16 +292,24 @@ class ILSemanticFlagGroup(object):
self._index = sem_group
self._name = self._arch.get_semantic_flag_group_name(self._index)
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return self._index == other.index
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
@property
def arch(self):
@@ -303,16 +348,24 @@ class ILIntrinsic(object):
self._inputs = self._arch.intrinsics[self._name].inputs
self._outputs = self._arch.intrinsics[self._name].outputs
- def __str__(self):
+ def __repr__(self):
return self._name
- def __repr__(self):
+ def __str__(self):
return self._name
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return self._index == other.index
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._arch, self._index, self._name) == (other._arch, other._index, other._name)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._arch, self._index, self._name))
@property
def arch(self):
@@ -368,6 +421,19 @@ class SSARegister(object):
def __repr__(self):
return "<ssa %s version %d>" % (repr(self._reg), self._version)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._reg, self._version) == (other._reg, other._version)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._reg, self._version))
+
@property
def reg(self):
""" """
@@ -395,6 +461,19 @@ class SSARegisterStack(object):
def __repr__(self):
return "<ssa %s version %d>" % (repr(self._reg_stack), self._version)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._reg_stack, self._version) == (other._reg_stack, other._version)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._reg_stack, self._version))
+
@property
def reg_stack(self):
""" """
@@ -422,6 +501,19 @@ class SSAFlag(object):
def __repr__(self):
return "<ssa %s version %d>" % (repr(self._flag), self._version)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._flag, self._version) == (other._flag, other._version)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._flag, self._version))
+
@property
def flag(self):
""" """
@@ -449,6 +541,19 @@ class SSARegisterOrFlag(object):
def __repr__(self):
return "<ssa %s version %d>" % (repr(self._reg_or_flag), self._version)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._reg_or_flag == other._reg_or_flag) and (self._version == other._version)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._reg_or_flag, self._version))
+
@property
def reg_or_flag(self):
""" """
@@ -478,6 +583,19 @@ class LowLevelILOperationAndSize(object):
return "<%s>" % self._operation.name
return "<%s %d>" % (self._operation.name, self._size)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._operation, self._size) == (other._operation, other._size)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._operation, self._size))
+
@property
def operation(self):
""" """
@@ -811,30 +929,38 @@ class LowLevelILInstruction(object):
def __repr__(self):
return "<il: %s>" % str(self)
- def __eq__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index == value.expr_index
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._function == other.function and self.expr_index == other.expr_index
- def __lt__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index < value.expr_index
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
- def __le__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index <= value.expr_index
+ def __lt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._function == other.function and self.expr_index < other.expr_index
- def __gt__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index > value.expr_index
+ def __le__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._function == other.function and self.expr_index <= other.expr_index
- def __ge__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index >= value.expr_index
+ def __gt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._function == other.function and self.expr_index > other.expr_index
+
+ def __ge__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._function == other.function and self.expr_index >= other.expr_index
+
+ def __hash__(self):
+ return hash((self._function, self.expr_index))
@property
def tokens(self):
@@ -1058,12 +1184,6 @@ class LowLevelILInstruction(object):
core.BNFreePossibleValueSet(value)
return result
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
@property
def function(self):
""" """
@@ -1180,23 +1300,10 @@ class LowLevelILFunction(object):
func_handle = self._source_function.handle
self.handle = core.BNCreateLowLevelILFunction(arch.handle, func_handle)
- def __hash__(self):
- return hash(('LLIL', self._source_function))
-
def __del__(self):
if self.handle is not None:
core.BNFreeLowLevelILFunction(self.handle)
- def __eq__(self, value):
- if not isinstance(value, type(self)):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
-
- def __ne__(self, value):
- if not isinstance(value, LowLevelILFunction):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
-
def __repr__(self):
arch = self.source_function.arch
if arch:
@@ -1204,6 +1311,51 @@ class LowLevelILFunction(object):
else:
return "<llil func: %#x>" % self.source_function.start
+ def __len__(self):
+ return int(core.BNGetLowLevelILInstructionCount(self.handle))
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(('LLIL', self._source_function))
+
+ def __getitem__(self, i):
+ if isinstance(i, slice) or isinstance(i, tuple):
+ raise IndexError("expected integer instruction index")
+ if isinstance(i, LowLevelILExpr):
+ return LowLevelILInstruction(self, i.index)
+ # for backwards compatibility
+ if isinstance(i, LowLevelILInstruction):
+ return i
+ if i < -len(self) or i >= len(self):
+ raise IndexError("index out of range")
+ if i < 0:
+ i = len(self) + i
+ return LowLevelILInstruction(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i)
+
+ def __setitem__(self, i, j):
+ raise IndexError("instruction modification not implemented")
+
+ def __iter__(self):
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
+ view = None
+ if self._source_function is not None:
+ view = self._source_function.view
+ try:
+ for i in range(0, count.value):
+ yield LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
+ finally:
+ core.BNFreeBasicBlockList(blocks, count.value)
+
@property
def current_address(self):
"""Current IL Address (read/write)"""
@@ -1294,43 +1446,23 @@ class LowLevelILFunction(object):
def mmlil(self):
return self.mapped_medium_level_il
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
- def __len__(self):
- return int(core.BNGetLowLevelILInstructionCount(self.handle))
+ @property
+ def arch(self):
+ """ """
+ return self._arch
- def __getitem__(self, i):
- if isinstance(i, slice) or isinstance(i, tuple):
- raise IndexError("expected integer instruction index")
- if isinstance(i, LowLevelILExpr):
- return LowLevelILInstruction(self, i.index)
- # for backwards compatibility
- if isinstance(i, LowLevelILInstruction):
- return i
- if i < -len(self) or i >= len(self):
- raise IndexError("index out of range")
- if i < 0:
- i = len(self) + i
- return LowLevelILInstruction(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i)
+ @arch.setter
+ def arch(self, value):
+ self._arch = value
- def __setitem__(self, i, j):
- raise IndexError("instruction modification not implemented")
+ @property
+ def source_function(self):
+ """ """
+ return self._source_function
- def __iter__(self):
- count = ctypes.c_ulonglong()
- blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
- view = None
- if self._source_function is not None:
- view = self._source_function.view
- try:
- for i in range(0, count.value):
- yield LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ @source_function.setter
+ def source_function(self, value):
+ self._source_function = value
def get_instruction_start(self, addr, arch = None):
if arch is None:
@@ -2871,30 +3003,27 @@ class LowLevelILFunction(object):
settings_obj = None
return binaryninja.flowgraph.CoreFlowGraph(core.BNCreateLowLevelILFunctionGraph(self.handle, settings_obj))
- @property
- def arch(self):
- """ """
- return self._arch
-
- @arch.setter
- def arch(self, value):
- self._arch = value
-
- @property
- def source_function(self):
- """ """
- return self._source_function
-
- @source_function.setter
- def source_function(self, value):
- self._source_function = value
-
class LowLevelILBasicBlock(basicblock.BasicBlock):
def __init__(self, view, handle, owner):
super(LowLevelILBasicBlock, self).__init__(handle, view)
self._il_function = owner
+ def __repr__(self):
+ arch = self.arch
+ if arch:
+ return "<llil block: %s@%d-%d>" % (arch.name, self.start, self.end)
+ else:
+ return "<llil block: %d-%d>" % (self.start, self.end)
+
+ def __hash__(self):
+ return hash((self.start, self.end, self._il_function))
+
+ def __contains__(self, instruction):
+ if type(instruction) != LowLevelILInstruction or instruction.il_basic_block != self:
+ return False
+ return True
+
def __iter__(self):
for idx in range(self.start, self.end):
yield self._il_function[idx]
@@ -2912,21 +3041,6 @@ class LowLevelILBasicBlock(basicblock.BasicBlock):
"""Internal method by super to instantiate child instances"""
return LowLevelILBasicBlock(view, handle, self._il_function)
- def __hash__(self):
- return hash((self.start, self.end, self._il_function))
-
- def __repr__(self):
- arch = self.arch
- if arch:
- return "<llil block: %s@%d-%d>" % (arch.name, self.start, self.end)
- else:
- return "<llil block: %d-%d>" % (self.start, self.end)
-
- def __contains__(self, instruction):
- if type(instruction) != LowLevelILInstruction or instruction.il_basic_block != self:
- return False
- return True
-
@property
def il_function(self):
""" """