summaryrefslogtreecommitdiff
path: root/python
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
parent5b84fdea8abcb4abba61d07e0d12b4115b516c52 (diff)
Fix up equality operators and had hash operators
Diffstat (limited to 'python')
-rw-r--r--python/architecture.py93
-rw-r--r--python/basicblock.py64
-rw-r--r--python/binaryview.py529
-rw-r--r--python/callingconvention.py31
-rw-r--r--python/filemetadata.py42
-rw-r--r--python/flowgraph.py138
-rw-r--r--python/function.py191
-rw-r--r--python/highlevelil.py83
-rw-r--r--python/lineardisassembly.py175
-rw-r--r--python/lowlevelil.py380
-rw-r--r--python/mediumlevelil.py196
-rw-r--r--python/metadata.py277
-rw-r--r--python/platform.py74
-rw-r--r--python/scriptingprovider.py12
-rw-r--r--python/settings.py16
-rw-r--r--python/transform.py19
-rw-r--r--python/types.py263
17 files changed, 1423 insertions, 1160 deletions
diff --git a/python/architecture.py b/python/architecture.py
index ad295c91..8495255c 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -79,12 +79,6 @@ class _ArchitectureMetaClass(type):
cls._registered_cb = arch._cb
arch.handle = core.BNRegisterArchitecture(cls.name, arch._cb)
- def __setattr__(self, name, value):
- try:
- type.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
@@ -387,15 +381,32 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
self._pending_name_and_type_lists = {}
self._pending_type_lists = {}
- def __eq__(self, value):
- if not isinstance(value, Architecture):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ return "<arch: %s>" % self.name
- def __ne__(self, value):
- if not isinstance(value, Architecture):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ 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(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)
@property
def list(self):
@@ -442,21 +453,6 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
core.BNFreeTypeLibraryList(handles, count.value)
return result
-
- 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 __repr__(self):
- return "<arch: %s>" % self.name
-
def _init(self, ctxt, handle):
self.handle = handle
@@ -2749,15 +2745,38 @@ class ReferenceSource(object):
else:
return "<ref: %#x>" % self._address
- def __eq__(self, value):
- if not isinstance(value, ReferenceSource):
- return False
- return self.function == value.function and self.arch == value.arch and self.address == value.address
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self.function, self.arch, self.address) == (other.address, other.function, other.arch)
+
+ 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 __gt__(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 __lt__(self, value):
- if not isinstance(value, ReferenceSource):
- raise TypeError("Can only compare to other ReferenceSource objects")
- return self.address < value.address
+ def __hash__(self):
+ hash((self._function, self._arch, self._address))
@property
def function(self):
diff --git a/python/basicblock.py b/python/basicblock.py
index bfd80387..5bcf6aff 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -39,14 +39,6 @@ class BasicBlockEdge(object):
self._back_edge = back_edge
self._fall_through = fall_through
- def __eq__(self, value):
- if not isinstance(value, BasicBlockEdge):
- return False
- return (self._type, self._source, self._target, self._back_edge, self._fall_through) == (value.type, value.source, value.target, value.back_edge, value.fall_through)
-
- def __hash__(self):
- return hash((self._type, self._source, self._target, self.back_edge, self.fall_through))
-
def __repr__(self):
if self._type == BranchType.UnresolvedBranch:
return "<%s>" % BranchType(self._type).name
@@ -55,6 +47,20 @@ class BasicBlockEdge(object):
else:
return "<%s: %#x>" % (BranchType(self._type).name, self._target.start)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._type, self._source, self._target, self._back_edge, self._fall_through) == \
+ (other._type, other._source, other._target, other._back_edge, other._fall_through)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._type, self._source, self._target, self.back_edge, self.fall_through))
+
@property
def type(self):
""" """
@@ -114,15 +120,28 @@ class BasicBlock(object):
def __del__(self):
core.BNFreeBasicBlock(self.handle)
- def __eq__(self, value):
- if not isinstance(value, BasicBlock):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ arch = self.arch
+ if arch:
+ return "<block: %s@%#x-%#x>" % (arch.name, self.start, self.end)
+ else:
+ return "<block: %#x-%#x>" % (self.start, self.end)
+
+ def __len__(self):
+ return int(core.BNGetBasicBlockLength(self.handle))
- def __ne__(self, value):
- if not isinstance(value, BasicBlock):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ 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((self.start, self.end, self.arch.name))
def __setattr__(self, name, value):
try:
@@ -130,16 +149,6 @@ class BasicBlock(object):
except AttributeError:
raise AttributeError("attribute '%s' is read only" % name)
- def __len__(self):
- return int(core.BNGetBasicBlockLength(self.handle))
-
- def __repr__(self):
- arch = self.arch
- if arch:
- return "<block: %s@%#x-%#x>" % (arch.name, self.start, self.end)
- else:
- return "<block: %#x-%#x>" % (self.start, self.end)
-
def __iter__(self):
if self._instStarts is None:
# don't and instruction start cache the object is likely ephemeral
@@ -165,9 +174,6 @@ class BasicBlock(object):
data = self._view.read(start, length)
return self.arch.get_instruction_text(data, start)
- def __hash__(self):
- return hash((self.start, self.end, self.arch.name))
-
def _buildStartCache(self):
if self._instStarts is None:
# build the instruction start cache
diff --git a/python/binaryview.py b/python/binaryview.py
index 61500f06..fe94b0bf 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -137,13 +137,8 @@ class StringReference(object):
self._length = length
self._view = bv
- @property
- def value(self):
- return self._view.read(self._start, self._length).decode(_decodings[self._type])
-
- @property
- def raw(self):
- return self._view.read(self._start, self._length)
+ def __repr__(self):
+ return "<%s: %#x, len %#x>" % (self._type, self._start, self._length)
def __str__(self):
return pyNativeStr(self.raw)
@@ -151,8 +146,13 @@ class StringReference(object):
def __len__(self):
return self._length
- def __repr__(self):
- return "<%s: %#x, len %#x>" % (self._type, self._start, self._length)
+ @property
+ def value(self):
+ return self._view.read(self._start, self._length).decode(_decodings[self._type])
+
+ @property
+ def raw(self):
+ return self._view.read(self._start, self._length)
@property
def type(self):
@@ -694,15 +694,21 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
def __init__(self, handle):
self.handle = core.handle_of_type(handle, core.BNBinaryViewType)
- def __eq__(self, value):
- if not isinstance(value, BinaryViewType):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ return "<view type: '%s'>" % self.name
- def __ne__(self, value):
- if not isinstance(value, BinaryViewType):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ 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(ctypes.addressof(self.handle.contents))
@property
def list(self):
@@ -719,9 +725,6 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
"""BinaryView long name (read-only)"""
return core.BNGetBinaryViewTypeLongName(self.handle)
- def __repr__(self):
- return "<view type: '%s'>" % self.name
-
def create(self, data):
view = core.BNCreateBinaryViewOfType(self.handle, data.handle)
if view is None:
@@ -902,6 +905,31 @@ class Segment(object):
def __init__(self, handle):
self.handle = handle
+ def __del__(self):
+ core.BNFreeSegment(self.handle)
+
+ def __repr__(self):
+ return "<segment: %#x-%#x, %s%s%s>" % (self.start, self.end,
+ "r" if self.readable else "-",
+ "w" if self.writable else "-",
+ "x" if self.executable else "-")
+
+ def __len__(self):
+ return core.BNSegmentGetLength(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(ctypes.addressof(self.handle.contents))
+
@property
def start(self):
return core.BNSegmentGetStart(self.handle)
@@ -965,36 +993,34 @@ class Segment(object):
core.BNFreeRelocationRanges(ranges, count)
return result
+
+
+class Section(object):
+ def __init__(self, handle):
+ self.handle = core.handle_of_type(handle, core.BNSection)
+
def __del__(self):
- core.BNFreeSegment(self.handle)
+ core.BNFreeSection(self.handle)
+
+ def __repr__(self):
+ return "<section %s: %#x-%#x>" % (self.name, self.start, self.end)
+
+ def __len__(self):
+ return core.BNSectionGetLength(self.handle)
def __eq__(self, other):
- if not isinstance(other, Segment):
- return False
+ 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, Segment):
- return False
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(other.handle.contents)
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
def __hash__(self):
return hash(ctypes.addressof(self.handle.contents))
- def __len__(self):
- return core.BNSegmentGetLength(self.handle)
-
- def __repr__(self):
- return "<segment: %#x-%#x, %s%s%s>" % (self.start, self.end,
- "r" if self.readable else "-",
- "w" if self.writable else "-",
- "x" if self.executable else "-")
-
-
-class Section(object):
- def __init__(self, handle):
- self.handle = core.handle_of_type(handle, core.BNSection)
-
@property
def name(self):
return core.BNSectionGetName(self.handle)
@@ -1039,47 +1065,35 @@ class Section(object):
def end(self):
return self.start + len(self)
- def __del__(self):
- core.BNFreeSection(self.handle)
-
- def __eq__(self, other):
- if not isinstance(other, Section):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
-
- def __ne__(self, other):
- if not isinstance(other, Section):
- return False
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(other.handle.contents)
-
- def __hash__(self):
- return hash(ctypes.addressof(self.handle.contents))
-
- def __len__(self):
- return core.BNSectionGetLength(self.handle)
-
- def __repr__(self):
- return "<section %s: %#x-%#x>" % (self.name, self.start, self.end)
-
class AddressRange(object):
def __init__(self, start, end):
self._start = start
self._end = end
+ def __repr__(self):
+ return "<%#x-%#x>" % (self._start, self._end)
+
def __len__(self):
return self._end - self.start
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._start, self._end) == (other._start, other._end)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._start, self._end))
+
@property
def length(self):
return self._end - self._start
- def __len__(self):
- return self._end - self._start
-
- def __repr__(self):
- return "<%#x-%#x>" % (self._start, self._end)
-
@property
def start(self):
""" """
@@ -1103,6 +1117,25 @@ class TagType(object):
def __init__(self, handle):
self.handle = core.handle_of_type(handle, core.BNTagType)
+ def __del__(self):
+ core.BNFreeTagType(self.handle)
+
+ def __repr__(self):
+ return "<tag type %s: %s>" % (self.name, self.icon)
+
+ 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(ctypes.addressof(self.handle.contents))
+
@property
def name(self):
"""Name of the TagType"""
@@ -1139,30 +1172,31 @@ class TagType(object):
def type(self, value):
core.BNTagTypeSetType(self.handle, value)
+
+
+class Tag(object):
+ def __init__(self, handle):
+ self.handle = core.handle_of_type(handle, core.BNTag)
+
def __del__(self):
- core.BNFreeTagType(self.handle)
+ core.BNFreeTag(self.handle)
+
+ def __repr__(self):
+ return "<tag %s %s: %s>" % (self.type.icon, self.type.name, self.data)
def __eq__(self, other):
- if not isinstance(other, TagType):
- return False
+ 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, TagType):
- return False
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(other.handle.contents)
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
def __hash__(self):
return hash(ctypes.addressof(self.handle.contents))
- def __repr__(self):
- return "<tag type %s: %s>" % (self.name, self.icon)
-
-
-class Tag(object):
- def __init__(self, handle):
- self.handle = core.handle_of_type(handle, core.BNTag)
-
@property
def type(self):
return TagType(core.BNTagGetType(self.handle))
@@ -1175,25 +1209,6 @@ class Tag(object):
def data(self, value):
core.BNTagSetData(self.handle, value)
- def __del__(self):
- core.BNFreeTag(self.handle)
-
- def __eq__(self, other):
- if not isinstance(other, Tag):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
-
- def __ne__(self, other):
- if not isinstance(other, Tag):
- return False
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(other.handle.contents)
-
- def __hash__(self):
- return hash(self.handle.contents)
-
- def __repr__(self):
- return "<tag %s %s: %s>" % (self.type.icon, self.type.name, self.data)
-
class _BinaryViewAssociatedDataStore(associateddatastore._AssociatedDataStore):
_defaults = {}
@@ -1302,15 +1317,108 @@ class BinaryView(object):
self._notifications = {}
self._next_address = None # Do NOT try to access view before init() is called, use placeholder
- def __eq__(self, value):
- if not isinstance(value, BinaryView):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __del__(self):
+ for i in self.notifications.values():
+ i._unregister()
+ core.BNFreeBinaryView(self.handle)
+
+ def __repr__(self):
+ start = self.start
+ length = len(self)
+ if start != 0:
+ size = "start %#x, len %#x" % (start, length)
+ else:
+ size = "len %#x" % length
+ filename = self._file.filename
+ if len(filename) > 0:
+ return "<BinaryView: '%s', %s>" % (filename, size)
+ return "<BinaryView: %s>" % (size)
+
+ def __len__(self):
+ return int(core.BNGetViewLength(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, value):
- if not isinstance(value, BinaryView):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
+
+ def __iter__(self):
+ count = ctypes.c_ulonglong(0)
+ funcs = core.BNGetAnalysisFunctionList(self.handle, count)
+ try:
+ for i in range(0, count.value):
+ yield binaryninja.function.Function(self, core.BNNewFunctionReference(funcs[i]))
+ finally:
+ core.BNFreeFunctionList(funcs, count.value)
+
+
+ def __getitem__(self, i):
+ if isinstance(i, tuple):
+ result = bytes()
+ for s in i:
+ result += self.__getitem__(s)
+ return result
+ elif isinstance(i, slice):
+ if i.step is not None:
+ raise IndexError("step not implemented")
+ i = i.indices(self.end)
+ start = i[0]
+ stop = i[1]
+ if stop <= start:
+ return ""
+ return self.read(start, stop - start)
+ elif i < 0:
+ if i >= -len(self):
+ value = self.read(int(len(self) + i), 1)
+ if len(value) == 0:
+ return IndexError("index not readable")
+ return value
+ raise IndexError("index out of range")
+ elif (i >= self.start) and (i < self.end):
+ value = self.read(int(i), 1)
+ if len(value) == 0:
+ return IndexError("index not readable")
+ return value
+ else:
+ raise IndexError("index out of range")
+
+ def __setitem__(self, i, value):
+ if isinstance(i, slice):
+ if i.step is not None:
+ raise IndexError("step not supported on assignment")
+ i = i.indices(self.end)
+ start = i[0]
+ stop = i[1]
+ if stop < start:
+ stop = start
+ if len(value) != (stop - start):
+ self.remove(start, stop - start)
+ self.insert(start, value)
+ else:
+ self.write(start, value)
+ elif i < 0:
+ if i >= -len(self):
+ if len(value) != 1:
+ raise ValueError("expected single byte for assignment")
+ if self.write(int(len(self) + i), value) != 1:
+ raise IndexError("index not writable")
+ else:
+ raise IndexError("index out of range")
+ elif (i >= self.start) and (i < self.end):
+ if len(value) != 1:
+ raise ValueError("expected single byte for assignment")
+ if self.write(int(i), value) != 1:
+ raise IndexError("index not writable")
+ else:
+ raise IndexError("index out of range")
@classmethod
def register(cls):
@@ -1472,20 +1580,6 @@ class BinaryView(object):
for i in block:
yield i
- def __del__(self):
- for i in self.notifications.values():
- i._unregister()
- core.BNFreeBinaryView(self.handle)
-
- def __iter__(self):
- count = ctypes.c_ulonglong(0)
- funcs = core.BNGetAnalysisFunctionList(self.handle, count)
- try:
- for i in range(0, count.value):
- yield binaryninja.function.Function(self, core.BNNewFunctionReference(funcs[i]))
- finally:
- core.BNFreeFunctionList(funcs, count.value)
-
@property
def parent_view(self):
"""View that contains the raw data used by this view (read-only)"""
@@ -1909,81 +2003,6 @@ class BinaryView(object):
def new_auto_function_analysis_suppressed(self, suppress):
core.BNSetNewAutoFunctionAnalysisSuppressed(self.handle, suppress)
- def __len__(self):
- return int(core.BNGetViewLength(self.handle))
-
- def __getitem__(self, i):
- if isinstance(i, tuple):
- result = bytes()
- for s in i:
- result += self.__getitem__(s)
- return result
- elif isinstance(i, slice):
- if i.step is not None:
- raise IndexError("step not implemented")
- i = i.indices(self.end)
- start = i[0]
- stop = i[1]
- if stop <= start:
- return ""
- return self.read(start, stop - start)
- elif i < 0:
- if i >= -len(self):
- value = self.read(int(len(self) + i), 1)
- if len(value) == 0:
- return IndexError("index not readable")
- return value
- raise IndexError("index out of range")
- elif (i >= self.start) and (i < self.end):
- value = self.read(int(i), 1)
- if len(value) == 0:
- return IndexError("index not readable")
- return value
- else:
- raise IndexError("index out of range")
-
- def __setitem__(self, i, value):
- if isinstance(i, slice):
- if i.step is not None:
- raise IndexError("step not supported on assignment")
- i = i.indices(self.end)
- start = i[0]
- stop = i[1]
- if stop < start:
- stop = start
- if len(value) != (stop - start):
- self.remove(start, stop - start)
- self.insert(start, value)
- else:
- self.write(start, value)
- elif i < 0:
- if i >= -len(self):
- if len(value) != 1:
- raise ValueError("expected single byte for assignment")
- if self.write(int(len(self) + i), value) != 1:
- raise IndexError("index not writable")
- else:
- raise IndexError("index out of range")
- elif (i >= self.start) and (i < self.end):
- if len(value) != 1:
- raise ValueError("expected single byte for assignment")
- if self.write(int(i), value) != 1:
- raise IndexError("index not writable")
- else:
- raise IndexError("index out of range")
-
- def __repr__(self):
- start = self.start
- length = len(self)
- if start != 0:
- size = "start %#x, len %#x" % (start, length)
- else:
- size = "len %#x" % length
- filename = self._file.filename
- if len(filename) > 0:
- return "<BinaryView: '%s', %s>" % (filename, size)
- return "<BinaryView: %s>" % (size)
-
def _init(self, ctxt):
try:
return self.init()
@@ -5386,15 +5405,18 @@ class BinaryReader(object):
def __del__(self):
core.BNFreeBinaryReader(self.handle)
- def __eq__(self, value):
- if not isinstance(value, BinaryReader):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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, value):
- if not isinstance(value, BinaryReader):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
@property
def endianness(self):
@@ -5706,15 +5728,18 @@ class BinaryWriter(object):
def __del__(self):
core.BNFreeBinaryWriter(self.handle)
- def __eq__(self, value):
- if not isinstance(value, BinaryWriter):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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, value):
- if not isinstance(value, BinaryWriter):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
@property
def endianness(self):
@@ -5920,6 +5945,27 @@ class StructuredDataValue(object):
self._address = address
self._value = value
+ def __str__(self):
+ decode_str = "{}B".format(self._type.width)
+ return ' '.join(["{:02x}".format(x) for x in struct.unpack(decode_str, self._value)])
+
+ def __repr__(self):
+ return "<StructuredDataValue type:{} value:{}>".format(str(self._type), str(self))
+
+ def __int__(self):
+ if self._type.width == 1:
+ code = "B"
+ elif self._type.width == 2:
+ code = "H"
+ elif self._type.width == 4:
+ code = "I"
+ elif self._type.width == 8:
+ code = "Q"
+ else:
+ raise Exception("Could not convert to integer with width {}".format(self._type.width))
+
+ return struct.unpack(code, self._value)[0]
+
@property
def type(self):
return self._type
@@ -5944,27 +5990,6 @@ class StructuredDataValue(object):
def str(self):
return str(self)
- def __int__(self):
- if self._type.width == 1:
- code = "B"
- elif self._type.width == 2:
- code = "H"
- elif self._type.width == 4:
- code = "I"
- elif self._type.width == 8:
- code = "Q"
- else:
- raise Exception("Could not convert to integer with width {}".format(self._type.width))
-
- return struct.unpack(code, self._value)[0]
-
- def __str__(self):
- decode_str = "{}B".format(self._type.width)
- return ' '.join(["{:02x}".format(x) for x in struct.unpack(decode_str, self._value)])
-
- def __repr__(self):
- return "<StructuredDataValue type:{} value:{}>".format(str(self._type), str(self))
-
class StructuredDataView(object):
"""
@@ -6000,19 +6025,12 @@ class StructuredDataView(object):
self._lookup_structure()
self._define_members()
- def _lookup_structure(self):
- s = self._bv.get_type_by_name(self._structure_name)
- if s is None:
- raise Exception("Could not find structure with name: {}".format(self._structure_name))
-
- if s.type_class != TypeClass.StructureTypeClass:
- raise Exception("{} is not a StructureTypeClass, got: {}".format(self._structure_name, s._type_class))
-
- self._structure = s.structure
+ def __repr__(self):
+ return "<StructuredDataView type:{} size:{:#x} address:{:#x}>".format(self._structure_name,
+ self._structure.width, self._address)
- def _define_members(self):
- for m in self._structure.members:
- self._members[m.name] = m
+ def __len__(self):
+ return self._structure.width
def __getattr__(self, key):
m = self._members.get(key, None)
@@ -6056,9 +6074,16 @@ class StructuredDataView(object):
return rv
- def __repr__(self):
- return "<StructuredDataView type:{} size:{:#x} address:{:#x}>".format(self._structure_name,
- self._structure.width, self._address)
+ def _lookup_structure(self):
+ s = self._bv.get_type_by_name(self._structure_name)
+ if s is None:
+ raise Exception("Could not find structure with name: {}".format(self._structure_name))
- def __len__(self):
- return self._structure.width
+ if s.type_class != TypeClass.StructureTypeClass:
+ raise Exception("{} is not a StructureTypeClass, got: {}".format(self._structure_name, s._type_class))
+
+ self._structure = s.structure
+
+ def _define_members(self):
+ for m in self._structure.members:
+ self._members[m.name] = m
diff --git a/python/callingconvention.py b/python/callingconvention.py
index c6e5895a..66569a96 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -159,15 +159,24 @@ class CallingConvention(object):
if self.handle is not None:
core.BNFreeCallingConvention(self.handle)
- def __eq__(self, value):
- if not isinstance(value, CallingConvention):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ return "<calling convention: %s %s>" % (self.arch.name, self.name)
+
+ def __str__(self):
+ return self.name
+
+ 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, value):
- if not isinstance(value, CallingConvention):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
def _get_caller_saved_regs(self, ctxt, count):
try:
@@ -364,12 +373,6 @@ class CallingConvention(object):
result[0].index = in_var[0].index
result[0].storage = in_var[0].storage
- def __repr__(self):
- return "<calling convention: %s %s>" % (self.arch.name, self.name)
-
- def __str__(self):
- return self.name
-
def perform_get_incoming_reg_value(self, reg, func):
reg_stack = self.arch.get_reg_stack_for_reg(reg)
if reg_stack is not None:
diff --git a/python/filemetadata.py b/python/filemetadata.py
index ce88fdce..58afeeec 100644
--- a/python/filemetadata.py
+++ b/python/filemetadata.py
@@ -88,6 +88,27 @@ class FileMetadata(object):
core.BNSetFilename(self.handle, str(filename))
self._nav = None
+ def __repr__(self):
+ return "<FileMetadata: %s>" % self.filename
+
+ def __del__(self):
+ if self.navigation is not None:
+ core.BNSetFileMetadataNavigationHandler(self.handle, None)
+ core.BNFreeFileMetadata(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(ctypes.addressof(self.handle.contents))
+
@property
def nav(self):
"""
@@ -98,21 +119,6 @@ class FileMetadata(object):
def nav(self, value):
self._nav = value
- def __del__(self):
- if self.navigation is not None:
- core.BNSetFileMetadataNavigationHandler(self.handle, None)
- core.BNFreeFileMetadata(self.handle)
-
- def __eq__(self, value):
- if not isinstance(value, FileMetadata):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
-
- def __ne__(self, value):
- if not isinstance(value, FileMetadata):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
-
@classmethod
def _unregister(cls, f):
handle = ctypes.cast(f, ctypes.c_void_p)
@@ -373,9 +379,3 @@ class FileMetadata(object):
if view is None:
return None
return binaryninja.binaryview.BinaryView(file_metadata = self, handle = view)
-
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
diff --git a/python/flowgraph.py b/python/flowgraph.py
index 6c3f41f7..404aa4bb 100644
--- a/python/flowgraph.py
+++ b/python/flowgraph.py
@@ -67,15 +67,41 @@ class FlowGraphNode(object):
if self.handle is not None:
core.BNFreeFlowGraphNode(self.handle)
- def __eq__(self, value):
- if not isinstance(value, FlowGraphNode):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ block = self.basic_block
+ if block:
+ arch = block.arch
+ if arch:
+ return "<graph node: %s@%#x-%#x>" % (arch.name, block.start, block.end)
+ else:
+ return "<graph node: %#x-%#x>" % (block.start, block.end)
+ return "<graph node>"
- def __ne__(self, value):
- if not isinstance(value, FlowGraphNode):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ 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 __iter__(self):
+ count = ctypes.c_ulonglong()
+ lines = core.BNGetFlowGraphNodeLines(self.handle, count)
+ block = self.basic_block
+ try:
+ for i in range(0, count.value):
+ addr = lines[i].addr
+ if (lines[i].instrIndex != 0xffffffffffffffff) and (block is not None) and hasattr(block, 'il_function'):
+ il_instr = block.il_function[lines[i].instrIndex]
+ else:
+ il_instr = None
+ tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
+ yield function.DisassemblyTextLine(tokens, addr, il_instr)
+ finally:
+ core.BNFreeDisassemblyTextLines(lines, count.value)
@property
def graph(self):
@@ -245,32 +271,6 @@ class FlowGraphNode(object):
color = highlight.HighlightColor(color)
core.BNSetFlowGraphNodeHighlight(self.handle, color._get_core_struct())
- def __repr__(self):
- block = self.basic_block
- if block:
- arch = block.arch
- if arch:
- return "<graph node: %s@%#x-%#x>" % (arch.name, block.start, block.end)
- else:
- return "<graph node: %#x-%#x>" % (block.start, block.end)
- return "<graph node>"
-
- def __iter__(self):
- count = ctypes.c_ulonglong()
- lines = core.BNGetFlowGraphNodeLines(self.handle, count)
- block = self.basic_block
- try:
- for i in range(0, count.value):
- addr = lines[i].addr
- if (lines[i].instrIndex != 0xffffffffffffffff) and (block is not None) and hasattr(block, 'il_function'):
- il_instr = block.il_function[lines[i].instrIndex]
- else:
- il_instr = None
- tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
- yield function.DisassemblyTextLine(tokens, addr, il_instr)
- finally:
- core.BNFreeDisassemblyTextLines(lines, count.value)
-
def add_outgoing_edge(self, edge_type, target):
"""
``add_outgoing_edge`` connects two flow graph nodes with an edge.
@@ -366,15 +366,42 @@ class FlowGraph(object):
def __del__(self):
core.BNFreeFlowGraph(self.handle)
- def __eq__(self, value):
- if not isinstance(value, FlowGraph):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ function = self.function
+ if function is None:
+ return "<flow graph>"
+ return "<graph of %s>" % repr(function)
+
+ 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 __ne__(self, value):
- if not isinstance(value, FlowGraph):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __setattr__(self, name, value):
+ try:
+ object.__setattr__(self, name, value)
+ except AttributeError:
+ raise AttributeError("attribute '%s' is read only" % name)
+
+ def __iter__(self):
+ count = ctypes.c_ulonglong()
+ nodes = core.BNGetFlowGraphNodes(self.handle, count)
+ try:
+ for i in range(0, count.value):
+ yield FlowGraphNode(self, core.BNNewFlowGraphNodeReference(nodes[i]))
+ finally:
+ core.BNFreeFlowGraphNodeList(nodes, count.value)
+
+ def __getitem__(self, i):
+ node = core.BNGetFlowGraphNode(self.handle, i)
+ if node is None:
+ return None
+ return FlowGraphNode(self, node)
def _prepare_for_layout(self, ctxt):
try:
@@ -639,27 +666,6 @@ class FlowGraph(object):
def shows_secondary_reg_highlighting(self, value):
self.set_option(FlowGraphOption.FlowGraphShowsSecondaryRegisterHighlighting, value)
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
- def __repr__(self):
- function = self.function
- if function is None:
- return "<flow graph>"
- return "<graph of %s>" % repr(function)
-
- def __iter__(self):
- count = ctypes.c_ulonglong()
- nodes = core.BNGetFlowGraphNodes(self.handle, count)
- try:
- for i in range(0, count.value):
- yield FlowGraphNode(self, core.BNNewFlowGraphNodeReference(nodes[i]))
- finally:
- core.BNFreeFlowGraphNodeList(nodes, count.value)
-
def layout(self, callback = None):
"""
``layout`` starts rendering a graph for display. Once a layout is complete, each node will contain
@@ -712,12 +718,6 @@ class FlowGraph(object):
"""
return core.BNAddFlowGraphNode(self.handle, node.handle)
- def __getitem__(self, i):
- node = core.BNGetFlowGraphNode(self.handle, i)
- if node is None:
- return None
- return FlowGraphNode(self, node)
-
def show(self, title):
"""
``show`` displays the graph in a new tab in the UI.
diff --git a/python/function.py b/python/function.py
index 81cfc6b6..7f9648f5 100644
--- a/python/function.py
+++ b/python/function.py
@@ -49,6 +49,19 @@ class LookupTableEntry(object):
def __repr__(self):
return "[%s] -> %#x" % (', '.join(["%#x" % i for i in self.from_values]), self.to_value)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._from_values, self._to_value) == (other._from_values, other._to_value)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._from_values, self._to_value))
+
@property
def from_values(self):
""" """
@@ -113,26 +126,30 @@ class RegisterValue(object):
return "<undetermined>"
def __hash__(self):
- if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue]:
- return hash(self._value)
- elif self.type == RegisterValueType.EntryValue:
- return hash(self._reg)
- elif self._type == RegisterValueType.StackFrameOffset:
- return hash(self._offset)
+ if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue]:
+ return hash(self._value)
+ elif self.type == RegisterValueType.EntryValue:
+ return hash(self._reg)
+ elif self._type == RegisterValueType.StackFrameOffset:
+ return hash(self._offset)
def __eq__(self, other):
- if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and isinstance(other, numbers.Integral):
- return self._value == other
- elif self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and hasattr(other, 'type') and other.type == self._type:
- return self._value == other.value
- elif self._type == RegisterValueType.EntryValue and hasattr(other, "type") and other.type == self._type:
- return self._reg == other.reg
- elif self._type == RegisterValueType.StackFrameOffset and hasattr(other, 'type') and other.type == self._type:
- return self._offset == other.offset
- elif self._type == RegisterValueType.StackFrameOffset and isinstance(other, numbers.Integral):
- return self._offset == other
- else:
- raise TypeError("'%s' is not valid for comparison to '%s'" % (other, self))
+ if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and isinstance(other, numbers.Integral):
+ return self._value == other
+ elif self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, RegisterValueType.ImportedAddressValue, RegisterValueType.ReturnAddressValue] and hasattr(other, 'type') and other.type == self._type:
+ return self._value == other.value
+ elif self._type == RegisterValueType.EntryValue and hasattr(other, "type") and other.type == self._type:
+ return self._reg == other.reg
+ elif self._type == RegisterValueType.StackFrameOffset and hasattr(other, 'type') and other.type == self._type:
+ return self._offset == other.offset
+ elif self._type == RegisterValueType.StackFrameOffset and isinstance(other, numbers.Integral):
+ return self._offset == other
+ return NotImplemented
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
def _to_api_object(self):
result = core.BNRegisterValue()
@@ -351,6 +368,19 @@ class PossibleValueSet(object):
return "<return address>"
return "<undetermined>"
+ def __eq__(self, other):
+ if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and isinstance(other, numbers.Integral):
+ return self.value == other
+ if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and hasattr(other, 'type') and other.type == self.type:
+ return self.value == other.value
+ else:
+ return self == other
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
@property
def type(self):
""" """
@@ -431,14 +461,6 @@ class PossibleValueSet(object):
""" """
self._values = value
- def __eq__(self, other):
- if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and isinstance(other, numbers.Integral):
- return self.value == other
- if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and hasattr(other, 'type') and other.type == self.type:
- return self.value == other.value
- else:
- return self == other
-
class StackVariableReference(object):
def __init__(self, src_operand, t, name, var, ref_ofs, size):
@@ -460,6 +482,20 @@ class StackVariableReference(object):
return "<operand %d ref to %s%+#x>" % (self._source_operand, self._name, self._var.storage)
return "<operand %d ref to %s>" % (self._source_operand, self._name)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._source_operand, self._type, self._name, self._var, self._referenced_offset, self._size) == \
+ (other._source_operand, other._type, other._name, other._var, other._referenced_offset, other._size)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._source_operand, self._type, self._name, self._var, self._referenced_offset, self._size))
+
@property
def source_operand(self):
""" """
@@ -541,6 +577,27 @@ class Variable(object):
self._name = name
self._type = var_type
+ def __repr__(self):
+ if self._type is None:
+ return "<var %s>" % self.name
+ return "<var %s %s%s>" % (self._type.get_string_before_name(), self.name, self._type.get_string_after_name())
+
+ def __str__(self):
+ return self.name
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self.identifier, self.function) == (other.identifier, other.function)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self.identifier, self.function))
+
@property
def function(self):
"""Function where the variable is defined"""
@@ -609,23 +666,6 @@ class Variable(object):
var = core.BNFromVariableIdentifier(identifier)
return Variable(func, VariableSourceType(var.type), var.index, var.storage, name, var_type)
- def __repr__(self):
- if self._type is None:
- return "<var %s>" % self.name
- return "<var %s %s%s>" % (self._type.get_string_before_name(), self.name, self._type.get_string_after_name())
-
- def __str__(self):
- return self.name
-
- def __eq__(self, other):
- if not isinstance(other, Variable):
- return False
- return (self.identifier, self.function) == (other.identifier, other.function)
-
- def __hash__(self):
- return hash((self.identifier, self.function))
-
-
class ConstantReference(object):
def __init__(self, val, size, ptr, intermediate):
self._value = val
@@ -698,6 +738,9 @@ class ParameterVariables(object):
def __repr__(self):
return repr(self._vars)
+ def __len__(self):
+ return len(self._vars)
+
def __iter__(self):
for var in self._vars:
yield var
@@ -705,9 +748,6 @@ class ParameterVariables(object):
def __getitem__(self, idx):
return self._vars[idx]
- def __len__(self):
- return len(self._vars)
-
def with_confidence(self, confidence):
return ParameterVariables(list(self._vars), confidence = confidence)
@@ -756,20 +796,42 @@ class Function(object):
core.BNReleaseAdvancedFunctionAnalysisDataMultiple(self.handle, self._advanced_analysis_requests)
core.BNFreeFunction(self.handle)
- def __lt__(self, value):
- if not isinstance(value, Function):
- raise TypeError("Can only compare to other Function objects")
- return self.start < value.start
+ def __repr__(self):
+ arch = self.arch
+ if arch:
+ return "<func: %s@%#x>" % (arch.name, self.start)
+ else:
+ return "<func: %#x>" % self.start
- def __eq__(self, value):
- if not isinstance(value, Function):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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 __lt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.start < other.start
- def __ne__(self, value):
- if not isinstance(value, Function):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __gt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.start > other.start
+
+ def __le__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.start <= other.start
+
+ def __ge__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.start >= other.start
def __hash__(self):
return hash((self.start, self.arch.name, self.platform.name))
@@ -798,25 +860,12 @@ class Function(object):
finally:
core.BNFreeBasicBlockList(blocks, count.value)
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
def __str__(self):
result = ""
for token in self.type_tokens:
result += token.text
return result
- def __repr__(self):
- arch = self.arch
- if arch:
- return "<func: %s@%#x>" % (arch.name, self.start)
- else:
- return "<func: %#x>" % self.start
-
@classmethod
def _unregister(cls, func):
handle = ctypes.cast(func, ctypes.c_void_p)
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 5cf94b34..1e680274 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -48,10 +48,17 @@ class HighLevelILOperationAndSize(object):
def __eq__(self, other):
if isinstance(other, HighLevelILOperation):
return other == self._operation
- if isinstance(other, HighLevelILOperationAndSize):
+ if isinstance(other, self.__class__):
return other.size == self._size and other.operation == self._operation
- else:
- return False
+ return NotImplemented
+
+ def __ne__(self, other):
+ if isinstance(other, self.__class__) or isinstance(other, HighLevelILOperation):
+ return not (self == other)
+ return NotImplemented
+
+ def __hash__(self):
+ return hash((self._operation, self._size))
@property
def operation(self):
@@ -77,6 +84,12 @@ class GotoLabel(object):
self._function = function
self._id = id
+ def __repr__(self):
+ return "<label: %s>" % self.name
+
+ def __str__(self):
+ return self.name
+
@property
def label_id(self):
return self._id
@@ -97,12 +110,6 @@ class GotoLabel(object):
def uses(self):
return self._function.get_label_uses(self._id)
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return "<label: %s>" % self.name
-
class HighLevelILInstruction(object):
"""
@@ -334,10 +341,18 @@ class HighLevelILInstruction(object):
continuation = "..."
return "<%s: %s%s>" % (self._operation.name, first_line, continuation)
- 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, self._expr_index) == (other._function, other._expr_index)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._function, self._expr_index))
@property
def lines(self):
@@ -380,21 +395,11 @@ class HighLevelILInstruction(object):
result.append(HighLevelILOperationAndSize(self._operation, self._size))
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):
""" """
return self._function
- @function.setter
- def function(self, value):
- self._function = value
-
@property
def expr_index(self):
""" """
@@ -480,16 +485,6 @@ class HighLevelILInstruction(object):
return HighLevelILInstruction(self._function, self._parent, self._as_ast)
@property
- def instr_index(self):
- """ """
- return self._instr_index
-
- @property
- def instr(self):
- """High level IL instruction that contains this expression"""
- return self._function[self._instr_index]
-
- @property
def ssa_form(self):
"""SSA form of expression (read-only)"""
return HighLevelILInstruction(self._function.ssa_form,
@@ -608,22 +603,22 @@ class HighLevelILFunction(object):
func_handle = self._source_function.handle
self.handle = core.BNCreateHighLevelILFunction(arch.handle, func_handle)
- def __hash__(self):
- return hash(('HLIL', self._source_function))
-
def __del__(self):
if self.handle is not None:
core.BNFreeHighLevelILFunction(self.handle)
- def __eq__(self, value):
- if not isinstance(value, HighLevelILFunction):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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, value):
- if not isinstance(value, HighLevelILFunction):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(('HLIL', self._source_function))
@property
def current_address(self):
diff --git a/python/lineardisassembly.py b/python/lineardisassembly.py
index 3e49f5ee..44f0aeb9 100644
--- a/python/lineardisassembly.py
+++ b/python/lineardisassembly.py
@@ -35,12 +35,12 @@ class LinearDisassemblyLine(object):
self.block = block
self.contents = contents
- def __str__(self):
- return str(self.contents)
-
def __repr__(self):
return repr(self.contents)
+ def __str__(self):
+ return str(self.contents)
+
class LinearViewObjectIdentifier(object):
def __init__(self, name, start = None, end = None):
@@ -48,29 +48,8 @@ class LinearViewObjectIdentifier(object):
self._start = start
self._end = end
- @property
- def name(self):
- return self._name
-
- @property
- def address(self):
- return self._start
-
- @property
- def start(self):
- return self._start
-
- @property
- def end(self):
- return self._end
-
- @property
- def has_address(self):
- return self._start is not None
-
- @property
- def has_range(self):
- return self._start is not None and self._end is not None
+ def __repr__(self):
+ return "<LinearViewObjectIdentifier: " + str(self) + ">"
def __str__(self):
if not self.has_address:
@@ -79,8 +58,18 @@ class LinearViewObjectIdentifier(object):
return "%s 0x%x-0x%x" % (self._name, self._start, self._end)
return "%s 0x%x" % (self._name, self._start)
- def __repr__(self):
- return "<LinearViewObjectIdentifier: " + str(self) + ">"
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._name, self._start, self._end) == (other._name, other._start, other._end)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self._name, self._start, self._end))
def _to_api_object(self, obj = None):
if obj is None:
@@ -102,6 +91,30 @@ class LinearViewObjectIdentifier(object):
result.end = 0
return result
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def address(self):
+ return self._start
+
+ @property
+ def start(self):
+ return self._start
+
+ @property
+ def end(self):
+ return self._end
+
+ @property
+ def has_address(self):
+ return self._start is not None
+
+ @property
+ def has_range(self):
+ return self._start is not None and self._end is not None
+
@classmethod
def _from_api_object(cls, obj):
if obj.type == LinearViewObjectIdentifierType.AddressLinearViewObject:
@@ -121,6 +134,18 @@ class LinearViewObject(object):
def __del__(self):
core.BNFreeLinearViewObject(self.handle)
+ def __repr__(self):
+ return "<LinearViewObject: " + str(self) + ">"
+
+ def __len__(self):
+ return self.end - self.start
+
+ def __str__(self):
+ result = str(self.identifier)
+ if self._parent is not None:
+ result = str(self._parent) + "/" + result
+ return result
+
@property
def first_child(self):
result = core.BNGetFirstLinearViewObjectChild(self.handle)
@@ -189,18 +214,6 @@ class LinearViewObject(object):
def ordering_index_total(self):
return core.BNGetLinearViewObjectOrderingIndexTotal(self.handle)
- def __len__(self):
- return self.end - self.start
-
- def __str__(self):
- result = str(self.identifier)
- if self._parent is not None:
- result = str(self._parent) + "/" + result
- return result
-
- def __repr__(self):
- return "<LinearViewObject: " + str(self) + ">"
-
def child_for_address(self, addr):
result = core.BNGetLinearViewObjectChildForAddress(self.handle, addr)
if not result:
@@ -323,6 +336,47 @@ class LinearViewCursor(object):
def __del__(self):
core.BNFreeLinearViewCursor(self.handle)
+ def __repr__(self):
+ return "<LinearViewCursor: " + str(self.current_object) + ">"
+
+ def __str__(self):
+ return str(self.current_object)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) == 0
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) != 0
+
+ def __lt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) < 0
+
+ def __le__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) <= 0
+
+ def __gt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) > 0
+
+ def __ge__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other) >= 0
+
+ def __cmp__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return LinearViewCursor.compare(self, other)
+
@property
def before_begin(self):
return core.BNIsLinearViewCursorBeforeBegin(self.handle)
@@ -431,47 +485,6 @@ class LinearViewCursor(object):
def duplicate(self):
return LinearViewCursor(None, handle = core.BNDuplicateLinearViewCursor(self.handle))
- def __str__(self):
- return str(self.current_object)
-
- def __repr__(self):
- return "<LinearViewCursor: " + str(self.current_object) + ">"
-
- def __eq__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) == 0
- return False
-
- def __ne__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) != 0
- return True
-
- def __lt__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) < 0
- return False
-
- def __le__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) <= 0
- return False
-
- def __gt__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) > 0
- return False
-
- def __ge__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other) >= 0
- return False
-
- def __cmp__(self, other):
- if isinstance(other, LinearViewCursor):
- return LinearViewCursor.compare(self, other)
- return 0
-
@classmethod
def compare(cls, a, b):
return core.BNCompareLinearViewCursors(a.handle, b.handle)
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):
""" """
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 21c50817..8b2a4c89 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -43,12 +43,14 @@ class SSAVariable(object):
return "<ssa %s version %d>" % (repr(self._var), self._version)
def __eq__(self, other):
- if not isinstance(other, type(self)):
- return False
- return isinstance(other, SSAVariable) and (
- (self._var, self._version) ==
- (other.var, other.version)
- )
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._var, self._version) == (other.var, other.version)
+
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
def __hash__(self):
return hash((self._var, self._version))
@@ -94,13 +96,17 @@ class MediumLevelILOperationAndSize(object):
def __eq__(self, other):
if isinstance(other, MediumLevelILOperation):
return other == self._operation
- if isinstance(other, MediumLevelILOperationAndSize):
- return other.size == self._size and other.operation == self._operation
- else:
- return False
+ if isinstance(other, self.__class__):
+ return (other.size, other.operation) == (self._size, self._operation)
+ return NotImplemented
+
+ def __ne__(self, other):
+ if isinstance(other, MediumLevelILOperation) or isinstance(other, self.__class__):
+ return not (self == other)
+ return NotImplemented
def __hash__(self):
- return hash((self._size, self._operation))
+ return hash((self._operation, self._size))
@property
def operation(self):
@@ -361,33 +367,33 @@ class MediumLevelILInstruction(object):
def __repr__(self):
return "<il: %s>" % str(self)
- def __hash__(self):
- return hash((self._instr_index, self._function))
+ 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 __eq__(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 __lt__(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 __le__(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 __gt__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index > value.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 __ge__(self, value):
- if not isinstance(value, type(self)):
- return False
- return self._function == value.function and self.expr_index >= value.expr_index
+ def __hash__(self):
+ return hash((self._instr_index, self._function))
@property
def tokens(self):
@@ -716,12 +722,6 @@ class MediumLevelILInstruction(object):
def get_branch_dependence(self, branch_instr):
return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self._function.handle, self._instr_index, branch_instr))
- 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):
""" """
@@ -807,23 +807,10 @@ class MediumLevelILFunction(object):
func_handle = self._source_function.handle
self.handle = core.BNCreateMediumLevelILFunction(arch.handle, func_handle)
- def __hash__(self):
- return hash(('MLIL', self._source_function))
-
def __del__(self):
if self.handle is not None:
core.BNFreeMediumLevelILFunction(self.handle)
- def __eq__(self, value):
- if not isinstance(value, MediumLevelILFunction):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
-
- def __ne__(self, value):
- if not isinstance(value, MediumLevelILFunction):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
-
def __repr__(self):
arch = self.source_function.arch
if arch:
@@ -831,6 +818,51 @@ class MediumLevelILFunction(object):
else:
return "<mlil func: %#x>" % self.source_function.start
+ def __len__(self):
+ return int(core.BNGetMediumLevelILInstructionCount(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(('MLIL', self._source_function))
+
+ def __getitem__(self, i):
+ if isinstance(i, slice) or isinstance(i, tuple):
+ raise IndexError("expected integer instruction index")
+ if isinstance(i, MediumLevelILExpr):
+ return MediumLevelILInstruction(self, i.index)
+ # for backwards compatibility
+ if isinstance(i, MediumLevelILInstruction):
+ return i
+ if i < -len(self) or i >= len(self):
+ raise IndexError("index out of range")
+ if i < 0:
+ i = len(self) + i
+ return MediumLevelILInstruction(self, core.BNGetMediumLevelILIndexForInstruction(self.handle, i), i)
+
+ def __setitem__(self, i, j):
+ raise IndexError("instruction modification not implemented")
+
+ def __iter__(self):
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetMediumLevelILBasicBlockList(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 MediumLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
+ finally:
+ core.BNFreeBasicBlockList(blocks, count.value)
+
@property
def current_address(self):
"""Current IL Address (read/write)"""
@@ -895,44 +927,6 @@ class MediumLevelILFunction(object):
"""Alias for low_level_il"""
return self.low_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.BNGetMediumLevelILInstructionCount(self.handle))
-
- def __getitem__(self, i):
- if isinstance(i, slice) or isinstance(i, tuple):
- raise IndexError("expected integer instruction index")
- if isinstance(i, MediumLevelILExpr):
- return MediumLevelILInstruction(self, i.index)
- # for backwards compatibility
- if isinstance(i, MediumLevelILInstruction):
- return i
- if i < -len(self) or i >= len(self):
- raise IndexError("index out of range")
- if i < 0:
- i = len(self) + i
- return MediumLevelILInstruction(self, core.BNGetMediumLevelILIndexForInstruction(self.handle, i), i)
-
- def __setitem__(self, i, j):
- raise IndexError("instruction modification not implemented")
-
- def __iter__(self):
- count = ctypes.c_ulonglong()
- blocks = core.BNGetMediumLevelILBasicBlockList(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 MediumLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
-
def get_instruction_start(self, addr, arch = None):
if arch is None:
arch = self._arch
@@ -1186,6 +1180,13 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock):
super(MediumLevelILBasicBlock, self).__init__(handle, view)
self.il_function = owner
+ def __repr__(self):
+ arch = self.arch
+ if arch:
+ return "<mlil block: %s@%d-%d>" % (arch.name, self.start, self.end)
+ else:
+ return "<mlil block: %d-%d>" % (self.start, self.end)
+
def __iter__(self):
for idx in range(self.start, self.end):
yield self.il_function[idx]
@@ -1199,20 +1200,9 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock):
else:
return self.il_function[self.end + idx]
- def _create_instance(self, handle, view):
- """Internal method by super to instantiate child instances"""
- return MediumLevelILBasicBlock(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 "<mlil block: %s@%d-%d>" % (arch.name, self.start, self.end)
- else:
- return "<mlil block: %d-%d>" % (self.start, self.end)
-
def __contains__(self, instruction):
if type(instruction) != MediumLevelILInstruction or instruction.il_basic_block != self:
return False
@@ -1221,6 +1211,10 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock):
else:
return False
+ def _create_instance(self, handle, view):
+ """Internal method by super to instantiate child instances"""
+ return MediumLevelILBasicBlock(view, handle, self.il_function)
+
@property
def il_function(self):
""" """
diff --git a/python/metadata.py b/python/metadata.py
index 27b0abb0..3fe78415 100644
--- a/python/metadata.py
+++ b/python/metadata.py
@@ -66,85 +66,78 @@ class Metadata(object):
else:
raise ValueError("{} doesn't contain type of: int, bool, str, float, list, dict".format(type(value).__name__))
- @property
- def value(self):
- if self.is_integer:
- return int(self)
- elif self.is_string:
- return str(self)
- elif self.is_raw:
- return bytes(self)
- elif self.is_float:
- return float(self)
- elif self.is_boolean:
- return bool(self)
- elif self.is_array:
- return list(self)
- elif self.is_dict:
- return self.get_dict()
- raise TypeError()
-
- def get_dict(self):
- if not self.is_dict:
- raise TypeError()
- result = {}
- for key in self:
- result[key] = self[key]
- return result
-
- @property
- def type(self):
- return MetadataType(core.BNMetadataGetType(self.handle))
-
- @property
- def is_integer(self):
- return self.is_signed_integer or self.is_unsigned_integer
-
- @property
- def is_signed_integer(self):
- return core.BNMetadataIsSignedInteger(self.handle)
-
- @property
- def is_unsigned_integer(self):
- return core.BNMetadataIsUnsignedInteger(self.handle)
-
- @property
- def is_float(self):
- return core.BNMetadataIsDouble(self.handle)
-
- @property
- def is_boolean(self):
- return core.BNMetadataIsBoolean(self.handle)
-
- @property
- def is_string(self):
- return core.BNMetadataIsString(self.handle)
-
- @property
- def is_raw(self):
- return core.BNMetadataIsRaw(self.handle)
-
- @property
- def is_array(self):
- return core.BNMetadataIsArray(self.handle)
-
- @property
- def is_dict(self):
- return core.BNMetadataIsKeyValueStore(self.handle)
-
- def remove(self, key_or_index):
- if isinstance(key_or_index, str) and self.is_dict:
- core.BNMetadataRemoveKey(self.handle, key_or_index)
- elif isinstance(key_or_index, int) and self.is_array:
- core.BNMetadataRemoveIndex(self.handle, key_or_index)
- else:
- raise TypeError("remove only valid for dict and array objects")
-
def __len__(self):
if self.is_array or self.is_dict or self.is_string or self.is_raw:
return core.BNMetadataSize(self.handle)
raise Exception("Metadata object doesn't support len()")
+ def __eq__(self, other):
+ if isinstance(other, int) and self.is_integer:
+ return int(self) == other
+ elif isinstance(other, str) and (self.is_string or self.is_raw):
+ return str(self) == other
+ elif isinstance(other, float) and self.is_float:
+ return float(self) == other
+ elif isinstance(other, bool) and self.is_boolean:
+ return bool(self) == other
+ elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)):
+ if len(self) != len(other):
+ return False
+ for a, b in zip(self, other):
+ if a != b:
+ return False
+ return True
+ elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)):
+ if len(self) != len(other):
+ return False
+ for a, b in zip(self, other):
+ if a != b or self[a] != other[b]:
+ return False
+ return True
+ elif isinstance(other, Metadata) and self.is_integer and other.is_integer:
+ return int(self) == int(other)
+ elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw):
+ return str(self) == str(other)
+ elif isinstance(other, Metadata) and self.is_float and other.is_float:
+ return float(self) == float(other)
+ elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean:
+ return bool(self) == bool(other)
+ return NotImplemented
+
+ def __ne__(self, other):
+ if isinstance(other, int) and self.is_integer:
+ return int(self) != other
+ elif isinstance(other, str) and (self.is_string or self.is_raw):
+ return str(self) != other
+ elif isinstance(other, float) and self.is_float:
+ return float(self) != other
+ elif isinstance(other, bool):
+ return bool(self) != other
+ elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)):
+ if len(self) != len(other):
+ return True
+ areEqual = True
+ for a, b in zip(self, other):
+ if a != b:
+ areEqual = False
+ return not areEqual
+ elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)):
+ if len(self) != len(other):
+ return True
+ for a, b in zip(self, other):
+ if a != b or self[a] != other[b]:
+ return True
+ return False
+ elif isinstance(other, Metadata) and self.is_integer and other.is_integer:
+ return int(self) != int(other)
+ elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw):
+ return str(self) != str(other)
+ elif isinstance(other, Metadata) and self.is_float and other.is_float:
+ return float(self) != float(other)
+ elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean:
+ return bool(self) != bool(other)
+ return NotImplemented
+
def __iter__(self):
if self.is_array:
for i in range(core.BNMetadataSize(self.handle)):
@@ -215,68 +208,76 @@ class Metadata(object):
raise ValueError("Metadata object is not boolean type")
return core.BNMetadataGetBoolean(self.handle)
- def __eq__(self, other):
- if isinstance(other, int) and self.is_integer:
- return int(self) == other
- elif isinstance(other, str) and (self.is_string or self.is_raw):
- return str(self) == other
- elif isinstance(other, float) and self.is_float:
- return float(self) == other
- elif isinstance(other, bool) and self.is_boolean:
- return bool(self) == other
- elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)):
- if len(self) != len(other):
- return False
- for a, b in zip(self, other):
- if a != b:
- return False
- return True
- elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)):
- if len(self) != len(other):
- return False
- for a, b in zip(self, other):
- if a != b or self[a] != other[b]:
- return False
- return True
- elif isinstance(other, Metadata) and self.is_integer and other.is_integer:
- return int(self) == int(other)
- elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw):
- return str(self) == str(other)
- elif isinstance(other, Metadata) and self.is_float and other.is_float:
- return float(self) == float(other)
- elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean:
- return bool(self) == bool(other)
- raise NotImplementedError()
+ @property
+ def value(self):
+ if self.is_integer:
+ return int(self)
+ elif self.is_string:
+ return str(self)
+ elif self.is_raw:
+ return bytes(self)
+ elif self.is_float:
+ return float(self)
+ elif self.is_boolean:
+ return bool(self)
+ elif self.is_array:
+ return list(self)
+ elif self.is_dict:
+ return self.get_dict()
+ raise TypeError()
- def __ne__(self, other):
- if isinstance(other, int) and self.is_integer:
- return int(self) != other
- elif isinstance(other, str) and (self.is_string or self.is_raw):
- return str(self) != other
- elif isinstance(other, float) and self.is_float:
- return float(self) != other
- elif isinstance(other, bool):
- return bool(self) != other
- elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)):
- if len(self) != len(other):
- return True
- areEqual = True
- for a, b in zip(self, other):
- if a != b:
- areEqual = False
- return not areEqual
- elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)):
- if len(self) != len(other):
- return True
- for a, b in zip(self, other):
- if a != b or self[a] != other[b]:
- return True
- return False
- elif isinstance(other, Metadata) and self.is_integer and other.is_integer:
- return int(self) != int(other)
- elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw):
- return str(self) != str(other)
- elif isinstance(other, Metadata) and self.is_float and other.is_float:
- return float(self) != float(other)
- elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean:
- return bool(self) != bool(other)
+ def get_dict(self):
+ if not self.is_dict:
+ raise TypeError()
+ result = {}
+ for key in self:
+ result[key] = self[key]
+ return result
+
+ @property
+ def type(self):
+ return MetadataType(core.BNMetadataGetType(self.handle))
+
+ @property
+ def is_integer(self):
+ return self.is_signed_integer or self.is_unsigned_integer
+
+ @property
+ def is_signed_integer(self):
+ return core.BNMetadataIsSignedInteger(self.handle)
+
+ @property
+ def is_unsigned_integer(self):
+ return core.BNMetadataIsUnsignedInteger(self.handle)
+
+ @property
+ def is_float(self):
+ return core.BNMetadataIsDouble(self.handle)
+
+ @property
+ def is_boolean(self):
+ return core.BNMetadataIsBoolean(self.handle)
+
+ @property
+ def is_string(self):
+ return core.BNMetadataIsString(self.handle)
+
+ @property
+ def is_raw(self):
+ return core.BNMetadataIsRaw(self.handle)
+
+ @property
+ def is_array(self):
+ return core.BNMetadataIsArray(self.handle)
+
+ @property
+ def is_dict(self):
+ return core.BNMetadataIsKeyValueStore(self.handle)
+
+ def remove(self, key_or_index):
+ if isinstance(key_or_index, str) and self.is_dict:
+ core.BNMetadataRemoveKey(self.handle, key_or_index)
+ elif isinstance(key_or_index, int) and self.is_array:
+ core.BNMetadataRemoveIndex(self.handle, key_or_index)
+ else:
+ raise TypeError("remove only valid for dict and array objects") \ No newline at end of file
diff --git a/python/platform.py b/python/platform.py
index b4163892..9059e1c4 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -32,6 +32,23 @@ from binaryninja import with_metaclass
class _PlatformMetaClass(type):
+ def __iter__(self):
+ binaryninja._init_plugins()
+ count = ctypes.c_ulonglong()
+ platforms = core.BNGetPlatformList(count)
+ try:
+ for i in range(0, count.value):
+ yield Platform(handle = core.BNNewPlatformReference(platforms[i]))
+ finally:
+ core.BNFreePlatformList(platforms, count.value)
+
+ def __getitem__(cls, value):
+ binaryninja._init_plugins()
+ platform = core.BNGetPlatformByName(str(value))
+ if platform is None:
+ raise KeyError("'%s' is not a valid platform" % str(value))
+ return Platform(handle = platform)
+
@property
def list(self):
binaryninja._init_plugins()
@@ -54,29 +71,6 @@ class _PlatformMetaClass(type):
core.BNFreePlatformOSList(platforms, count.value)
return result
- def __iter__(self):
- binaryninja._init_plugins()
- count = ctypes.c_ulonglong()
- platforms = core.BNGetPlatformList(count)
- try:
- for i in range(0, count.value):
- yield Platform(handle = core.BNNewPlatformReference(platforms[i]))
- finally:
- core.BNFreePlatformList(platforms, count.value)
-
- def __setattr__(self, name, value):
- try:
- type.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
- def __getitem__(cls, value):
- binaryninja._init_plugins()
- platform = core.BNGetPlatformByName(str(value))
- if platform is None:
- raise KeyError("'%s' is not a valid platform" % str(value))
- return Platform(handle = platform)
-
def get_list(cls, os = None, arch = None):
binaryninja._init_plugins()
count = ctypes.c_ulonglong()
@@ -116,15 +110,21 @@ class Platform(with_metaclass(_PlatformMetaClass, object)):
if self.handle is not None:
core.BNFreePlatform(self.handle)
- def __eq__(self, value):
- if not isinstance(value, Platform):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ return "<platform: %s>" % self.name
- def __ne__(self, value):
- if not isinstance(value, Platform):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __str__(self):
+ return self.name
+
+ 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)
@property
def list(self):
@@ -305,18 +305,6 @@ class Platform(with_metaclass(_PlatformMetaClass, object)):
core.BNFreeTypeLibraryList(libs, count.value)
return result
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
- def __repr__(self):
- return "<platform: %s>" % self.name
-
- def __str__(self):
- return self.name
-
def register(self, os):
"""
``register`` registers the platform for given OS name.
diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py
index 73cb2a0d..af230c75 100644
--- a/python/scriptingprovider.py
+++ b/python/scriptingprovider.py
@@ -340,9 +340,6 @@ class _ScriptingProviderMetaclass(type):
class ScriptingProvider(with_metaclass(_ScriptingProviderMetaclass, object)):
-
- name = None
- instance_class = None
_registered_providers = []
def __init__(self, handle = None):
@@ -351,11 +348,18 @@ class ScriptingProvider(with_metaclass(_ScriptingProviderMetaclass, object)):
self.__dict__["name"] = core.BNGetScriptingProviderName(handle)
@property
+ def name(self):
+ return NotImplemented
+
+ @property
+ def instance_class(self):
+ return NotImplemented
+
+ @property
def list(self):
"""Allow tab completion to discover metaclass list property"""
pass
-
def register(self):
self._cb = core.BNScriptingProviderCallbacks()
self._cb.context = 0
diff --git a/python/settings.py b/python/settings.py
index 447604c5..3b92ec5d 100644
--- a/python/settings.py
+++ b/python/settings.py
@@ -80,15 +80,15 @@ class Settings(object):
if self.handle is not Settings.handle and self.handle is not None:
core.BNFreeSettings(self.handle)
- def __eq__(self, value):
- if not isinstance(value, Settings):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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, value):
- if not isinstance(value, Settings):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
def __hash__(self):
return hash((self.instance_id, ctypes.addressof(self.handle.contents)))
diff --git a/python/transform.py b/python/transform.py
index 946b349b..3e89555d 100644
--- a/python/transform.py
+++ b/python/transform.py
@@ -166,15 +166,18 @@ class Transform(with_metaclass(_TransformMetaClass, object)):
def __repr__(self):
return "<transform: %s>" % self.name
- def __eq__(self, value):
- if not isinstance(value, Transform):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ 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, value):
- if not isinstance(value, Transform):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
def _get_parameters(self, ctxt, count):
try:
diff --git a/python/types.py b/python/types.py
index 0d766e5c..b0faf9ed 100644
--- a/python/types.py
+++ b/python/types.py
@@ -38,7 +38,7 @@ class QualifiedName(object):
if isinstance(name, str):
self._name = [name]
self._byte_name = [name.encode('charmap')]
- elif isinstance(name, QualifiedName):
+ elif isinstance(name, self.__class__):
self._name = name.name
self._byte_name = [n.encode('charmap') for n in name.name]
else:
@@ -54,48 +54,57 @@ class QualifiedName(object):
def __len__(self):
return len(self.name)
- def __hash__(self):
- return hash(str(self))
-
def __eq__(self, other):
if isinstance(other, str):
return str(self) == other
elif isinstance(other, list):
return self.name == other
- elif isinstance(other, QualifiedName):
+ elif isinstance(other, self.__class__):
return self.name == other.name
- return False
+ return NotImplemented
def __ne__(self, other):
- return not (self == other)
+ if isinstance(other, str):
+ return str(self) != other
+ elif isinstance(other, list):
+ return self.name != other
+ elif isinstance(other, self.__class__):
+ return self.name != other.name
+ return NotImplemented
def __lt__(self, other):
- if isinstance(other, QualifiedName):
+ if isinstance(other, self.__class__):
return self.name < other.name
- return False
+ return NotImplemented
def __le__(self, other):
- if isinstance(other, QualifiedName):
+ if isinstance(other, self.__class__):
return self.name <= other.name
- return False
+ return NotImplemented
def __gt__(self, other):
- if isinstance(other, QualifiedName):
+ if isinstance(other, self.__class__):
return self.name > other.name
- return False
+ return NotImplemented
def __ge__(self, other):
- if isinstance(other, QualifiedName):
+ if isinstance(other, self.__class__):
return self.name >= other.name
- return False
+ return NotImplemented
def __cmp__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+
if self == other:
return 0
if self < other:
return -1
return 1
+ def __hash__(self):
+ return hash(str(self))
+
def __getitem__(self, key):
return self.name[key]
@@ -157,6 +166,7 @@ class NameSpace(QualifiedName):
result.append(name.name[i])
return NameSpace(result)
+
class Symbol(object):
"""
Symbols are defined as one of the following types:
@@ -194,15 +204,21 @@ class Symbol(object):
def __del__(self):
core.BNFreeSymbol(self.handle)
- def __eq__(self, value):
- if not isinstance(value, Symbol):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ return "<%s: \"%s\" @ %#x>" % (self.type, self.full_name, self.address)
+
+ 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 __ne__(self, value):
- if not isinstance(value, Symbol):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
@property
def type(self):
@@ -270,15 +286,6 @@ class Symbol(object):
core.BNFreeStringList(aliases, count)
return result
- def __repr__(self):
- return "<%s: \"%s\" @ %#x>" % (self.type, self.full_name, self.address)
-
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
class FunctionParameter(object):
def __init__(self, param_type, name = "", location = None):
@@ -343,15 +350,34 @@ class Type(object):
else:
core.BNFreeType(self._handle)
- def __eq__(self, value):
- if not isinstance(value, Type):
- return False
- return core.BNTypesEqual(self.handle, value.handle)
+ def __repr__(self):
+ if self._confidence < max_confidence:
+ return "<type: %s, %d%% confidence>" % (str(self), (self._confidence * 100) // max_confidence)
+ return "<type: %s>" % str(self)
+
+ def __str__(self):
+ platform = None
+ if self._platform is not None:
+ platform = self._platform.handle
+ if self._mutable:
+ return core.BNGetTypeBuilderString(self._handle, platform)
+ name = self.registered_name
+ if (name is not None) and (self.type_class != TypeClass.StructureTypeClass) and (self.type_class != TypeClass.EnumerationTypeClass):
+ return self.get_string_before_name() + " " + str(name.name) + self.get_string_after_name()
+ return core.BNGetTypeString(self._handle, platform)
+
+ def __len__(self):
+ return self.width
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return core.BNTypesEqual(self.handle, other.handle)
- def __ne__(self, value):
- if not isinstance(value, Type):
- return True
- return core.BNTypesNotEqual(self.handle, value.handle)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return core.BNTypesNotEqual(self.handle, other.handle)
@property
def handle(self):
@@ -595,25 +621,6 @@ class Type(object):
return None
return NamedTypeReference(handle = name)
- def __len__(self):
- return self.width
-
- def __str__(self):
- platform = None
- if self._platform is not None:
- platform = self._platform.handle
- if self._mutable:
- return core.BNGetTypeBuilderString(self._handle, platform)
- name = self.registered_name
- if (name is not None) and (self.type_class != TypeClass.StructureTypeClass) and (self.type_class != TypeClass.EnumerationTypeClass):
- return self.get_string_before_name() + " " + str(name.name) + self.get_string_after_name()
- return core.BNGetTypeString(self._handle, platform)
-
- def __repr__(self):
- if self._confidence < max_confidence:
- return "<type: %s, %d%% confidence>" % (str(self), (self._confidence * 100) // max_confidence)
- return "<type: %s>" % str(self)
-
def get_string_before_name(self):
platform = None
if self._platform is not None:
@@ -868,7 +875,7 @@ class Type(object):
return core.BNGetAutoDemangledTypeIdSource()
def with_confidence(self, confidence):
- return Type(handle = core.BNNewTypeReference(self.handle), platform = self._platform, confidence = confidence)
+ return Type(handle = core.BNNewTypeReference(self._handle), platform = self._platform, confidence = confidence)
@property
def confidence(self):
@@ -894,13 +901,13 @@ class Type(object):
return Type(core.BNCreateTypeBuilderFromType(self._handle), confidence = self._confidence)
def with_replaced_structure(self, from_struct, to_struct):
- return Type(handle = core.BNTypeWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle))
+ return Type(handle = core.BNTypeWithReplacedStructure(self._handle, from_struct.handle, to_struct.handle))
def with_replaced_enumeration(self, from_enum, to_enum):
- return Type(handle = core.BNTypeWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle))
+ return Type(handle = core.BNTypeWithReplacedEnumeration(self._handle, from_enum.handle, to_enum.handle))
def with_replaced_named_type_reference(self, from_ref, to_ref):
- return Type(handle = core.BNTypeWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle))
+ return Type(handle = core.BNTypeWithReplacedNamedTypeReference(self._handle, from_ref.handle, to_ref.handle))
class BoolWithConfidence(object):
@@ -1087,15 +1094,29 @@ class NamedTypeReference(object):
def __del__(self):
core.BNFreeNamedTypeReference(self.handle)
- def __eq__(self, value):
- if not isinstance(value, NamedTypeReference):
- return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ def __repr__(self):
+ if self.type_class == NamedTypeReferenceClass.TypedefNamedTypeClass:
+ return "<named type: typedef %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.StructNamedTypeClass:
+ return "<named type: struct %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.UnionNamedTypeClass:
+ return "<named type: union %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.EnumNamedTypeClass:
+ return "<named type: enum %s>" % str(self.name)
+ return "<named type: unknown %s>" % str(self.name)
+
+ 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, value):
- if not isinstance(value, NamedTypeReference):
- return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ def __ne__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return not (self == other)
+
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
@property
def type_class(self):
@@ -1112,17 +1133,6 @@ class NamedTypeReference(object):
core.BNFreeQualifiedName(name)
return result
- def __repr__(self):
- if self.type_class == NamedTypeReferenceClass.TypedefNamedTypeClass:
- return "<named type: typedef %s>" % str(self.name)
- if self.type_class == NamedTypeReferenceClass.StructNamedTypeClass:
- return "<named type: struct %s>" % str(self.name)
- if self.type_class == NamedTypeReferenceClass.UnionNamedTypeClass:
- return "<named type: union %s>" % str(self.name)
- if self.type_class == NamedTypeReferenceClass.EnumNamedTypeClass:
- return "<named type: enum %s>" % str(self.name)
- return "<named type: unknown %s>" % str(self.name)
-
@classmethod
def generate_auto_type_ref(self, type_class, source, name):
type_id = Type.generate_auto_type_id(source, name)
@@ -1146,6 +1156,39 @@ class StructureMember(object):
return "<%s %s%s, offset %#x>" % (self._type.get_string_before_name(), self._name,
self._type.get_string_after_name(), self._offset)
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (self._type, self._name, self._offset) == (other._type, other._name, other._offset)
+
+ 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._offset < other._offset
+
+ def __gt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._offset > other._offset
+
+ def __le__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._offset <= other._offset
+
+ def __ge__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._offset >= other._offset
+
+ def __hash__(self):
+ return hash((self._type, self._name, self._offset))
+
@property
def type(self):
""" """
@@ -1189,15 +1232,21 @@ class Structure(object):
else:
core.BNFreeStructure(self._handle)
- def __eq__(self, value):
- if not isinstance(value, Structure):
- return False
- return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents)
+ def __repr__(self):
+ return "<struct: size %#x>" % self.width
+
+ 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 __ne__(self, value):
- if not isinstance(value, Structure):
- return True
- return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents)
+ def __hash__(self):
+ return hash(ctypes.addressof(self._handle.contents))
def __getitem__(self, name):
try:
@@ -1304,9 +1353,6 @@ class Structure(object):
raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
core.BNSetStructureBuilderType(self._handle, value)
- def __repr__(self):
- return "<struct: size %#x>" % self.width
-
def append(self, t, name = ""):
if not self._mutable:
raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
@@ -1342,13 +1388,13 @@ class Structure(object):
return Structure(core.BNCreateStructureBuilderFromStructure(self._handle))
def with_replaced_structure(self, from_struct, to_struct):
- return Structure(core.BNStructureWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle))
+ return Structure(core.BNStructureWithReplacedStructure(self._handle, from_struct.handle, to_struct.handle))
def with_replaced_enumeration(self, from_enum, to_enum):
- return Structure(core.BNStructureWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle))
+ return Structure(core.BNStructureWithReplacedEnumeration(self._handle, from_enum.handle, to_enum.handle))
def with_replaced_named_type_reference(self, from_ref, to_ref):
- return Structure(core.BNStructureWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle))
+ return Structure(core.BNStructureWithReplacedNamedTypeReference(self._handle, from_ref.handle, to_ref.handle))
class EnumerationMember(object):
@@ -1403,15 +1449,21 @@ class Enumeration(object):
else:
core.BNFreeEnumeration(self._handle)
- def __eq__(self, value):
- if not isinstance(value, Enumeration):
- return False
- return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents)
+ def __repr__(self):
+ return "<enum: %s>" % repr(self.members)
+
+ 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 __ne__(self, value):
- if not isinstance(value, Enumeration):
- return True
- return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents)
+ def __hash__(self):
+ return hash(ctypes.addressof(self.handle.contents))
@property
def handle(self):
@@ -1437,9 +1489,6 @@ class Enumeration(object):
core.BNFreeEnumerationMemberList(members, count.value)
return result
- def __repr__(self):
- return "<enum: %s>" % repr(self.members)
-
def append(self, name, value = None):
if not self._mutable:
raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()")