summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basicblock.cpp30
-rw-r--r--binaryninjaapi.h42
-rw-r--r--binaryninjacore.h7
-rw-r--r--python/architecture.py10
-rw-r--r--python/basicblock.py56
-rw-r--r--python/binaryview.py40
-rw-r--r--python/callingconvention.py10
-rw-r--r--python/filemetadata.py10
-rw-r--r--python/function.py30
-rw-r--r--python/lowlevelil.py10
-rw-r--r--python/platform.py10
-rw-r--r--python/transform.py10
-rw-r--r--python/types.py50
13 files changed, 291 insertions, 24 deletions
diff --git a/basicblock.cpp b/basicblock.cpp
index 4edcc568..153a7768 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -108,6 +108,12 @@ uint64_t BasicBlock::GetLength() const
}
+size_t BasicBlock::GetIndex() const
+{
+ return BNGetBasicBlockIndex(m_object);
+}
+
+
vector<BasicBlockEdge> BasicBlock::GetOutgoingEdges() const
{
size_t count;
@@ -118,12 +124,30 @@ vector<BasicBlockEdge> BasicBlock::GetOutgoingEdges() const
{
BasicBlockEdge edge;
edge.type = array[i].type;
- edge.target = array[i].target;
- edge.arch = array[i].arch ? new CoreArchitecture(array[i].arch) : nullptr;
+ edge.target = array[i].target ? new BasicBlock(BNNewBasicBlockReference(array[i].target)) : nullptr;
+ result.push_back(edge);
+ }
+
+ BNFreeBasicBlockEdgeList(array, count);
+ return result;
+}
+
+
+vector<BasicBlockEdge> BasicBlock::GetIncomingEdges() const
+{
+ size_t count;
+ BNBasicBlockEdge* array = BNGetBasicBlockIncomingEdges(m_object, &count);
+
+ vector<BasicBlockEdge> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ BasicBlockEdge edge;
+ edge.type = array[i].type;
+ edge.target = array[i].target ? new BasicBlock(BNNewBasicBlockReference(array[i].target)) : nullptr;
result.push_back(edge);
}
- BNFreeBasicBlockOutgoingEdgeList(array);
+ BNFreeBasicBlockEdgeList(array, count);
return result;
}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 370a9ae2..7004501c 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -51,6 +51,8 @@ namespace BinaryNinja
RefCountObject(): m_refs(0) {}
virtual ~RefCountObject() {}
+ RefCountObject* GetObject() { return this; }
+
void AddRef()
{
#ifdef WIN32
@@ -101,7 +103,7 @@ namespace BinaryNinja
CoreRefCountObject(): m_refs(0), m_object(nullptr) {}
virtual ~CoreRefCountObject() {}
- T* GetObject() { return m_object; }
+ T* GetObject() const { return m_object; }
void AddRef()
{
@@ -158,7 +160,7 @@ namespace BinaryNinja
StaticCoreRefCountObject(): m_refs(0), m_object(nullptr) {}
virtual ~StaticCoreRefCountObject() {}
- T* GetObject() { return m_object; }
+ T* GetObject() const { return m_object; }
void AddRef()
{
@@ -246,6 +248,36 @@ namespace BinaryNinja
return m_obj == NULL;
}
+ bool operator==(const T* obj) const
+ {
+ return m_obj->GetObject() == obj->GetObject();
+ }
+
+ bool operator==(const Ref<T>& obj) const
+ {
+ return m_obj->GetObject() == obj.m_obj->GetObject();
+ }
+
+ bool operator!=(const T* obj) const
+ {
+ return m_obj->GetObject() != obj->GetObject();
+ }
+
+ bool operator!=(const Ref<T>& obj) const
+ {
+ return m_obj->GetObject() != obj.m_obj->GetObject();
+ }
+
+ bool operator<(const T* obj) const
+ {
+ return m_obj->GetObject() < obj->GetObject();
+ }
+
+ bool operator<(const Ref<T>& obj) const
+ {
+ return m_obj->GetObject() < obj.m_obj->GetObject();
+ }
+
T* GetPtr() const
{
return m_obj;
@@ -1728,8 +1760,7 @@ namespace BinaryNinja
struct BasicBlockEdge
{
BNBranchType type;
- uint64_t target;
- Ref<Architecture> arch;
+ Ref<BasicBlock> target;
};
class BasicBlock: public CoreRefCountObject<BNBasicBlock, BNNewBasicBlockReference, BNFreeBasicBlock>
@@ -1744,7 +1775,10 @@ namespace BinaryNinja
uint64_t GetEnd() const;
uint64_t GetLength() const;
+ size_t GetIndex() const;
+
std::vector<BasicBlockEdge> GetOutgoingEdges() const;
+ std::vector<BasicBlockEdge> GetIncomingEdges() const;
bool HasUndeterminedOutgoingEdges() const;
void MarkRecentUse();
diff --git a/binaryninjacore.h b/binaryninjacore.h
index b8531742..2d22bb3f 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -793,8 +793,7 @@ extern "C"
struct BNBasicBlockEdge
{
BNBranchType type;
- uint64_t target;
- BNArchitecture* arch;
+ BNBasicBlock* target;
};
struct BNPoint
@@ -1726,8 +1725,10 @@ extern "C"
BINARYNINJACOREAPI uint64_t BNGetBasicBlockEnd(BNBasicBlock* block);
BINARYNINJACOREAPI uint64_t BNGetBasicBlockLength(BNBasicBlock* block);
BINARYNINJACOREAPI BNBasicBlockEdge* BNGetBasicBlockOutgoingEdges(BNBasicBlock* block, size_t* count);
- BINARYNINJACOREAPI void BNFreeBasicBlockOutgoingEdgeList(BNBasicBlockEdge* edges);
+ BINARYNINJACOREAPI BNBasicBlockEdge* BNGetBasicBlockIncomingEdges(BNBasicBlock* block, size_t* count);
+ BINARYNINJACOREAPI void BNFreeBasicBlockEdgeList(BNBasicBlockEdge* edges, size_t count);
BINARYNINJACOREAPI bool BNBasicBlockHasUndeterminedOutgoingEdges(BNBasicBlock* block);
+ BINARYNINJACOREAPI size_t BNGetBasicBlockIndex(BNBasicBlock* block);
BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetBasicBlockDisassemblyText(BNBasicBlock* block,
BNDisassemblySettings* settings, size_t* count);
diff --git a/python/architecture.py b/python/architecture.py
index 5bafe949..39e5e72d 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -333,6 +333,16 @@ class Architecture(object):
self._pending_reg_lists = {}
self._pending_token_lists = {}
+ def __eq__(self, value):
+ if not isinstance(value, Architecture):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, Architecture):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def full_width_regs(self):
"""List of full width register strings (read-only)"""
diff --git a/python/basicblock.py b/python/basicblock.py
index f6dbd60d..ebacb311 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -29,19 +29,17 @@ import function
class BasicBlockEdge(object):
- def __init__(self, branch_type, target, arch):
+ def __init__(self, branch_type, target):
self.type = branch_type
- if self.type != BranchType.UnresolvedBranch:
- self.target = target
- self.arch = arch
+ self.target = target
def __repr__(self):
if self.type == BranchType.UnresolvedBranch:
return "<%s>" % BranchType(self.type).name
- elif self.arch:
- return "<%s: %s@%#x>" % (self.type, self.arch.name, self.target)
+ elif self.target.arch:
+ return "<%s: %s@%#x>" % (BranchType(self.type).name, self.target.arch.name, self.target.start)
else:
- return "<%s: %#x>" % (self.type, self.target)
+ return "<%s: %#x>" % (BranchType(self.type).name, self.target.start)
class BasicBlock(object):
@@ -52,6 +50,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, BasicBlock):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def function(self):
"""Basic block function (read-only)"""
@@ -84,20 +92,40 @@ class BasicBlock(object):
return core.BNGetBasicBlockLength(self.handle)
@property
+ def index(self):
+ """Basic block index in list of blocks for the function (read-only)"""
+ return core.BNGetBasicBlockIndex(self.handle)
+
+ @property
def outgoing_edges(self):
"""List of basic block outgoing edges (read-only)"""
count = ctypes.c_ulonglong(0)
edges = core.BNGetBasicBlockOutgoingEdges(self.handle, count)
result = []
for i in xrange(0, count.value):
- branch_type = edges[i].type
- target = edges[i].target
- if edges[i].arch:
- arch = architecture.Architecture(edges[i].arch)
+ branch_type = BranchType(edges[i].type)
+ if edges[i].target:
+ target = BasicBlock(self.view, core.BNNewBasicBlockReference(edges[i].target))
+ else:
+ target = None
+ result.append(BasicBlockEdge(branch_type, target))
+ core.BNFreeBasicBlockEdgeList(edges, count.value)
+ return result
+
+ @property
+ def incoming_edges(self):
+ """List of basic block incoming edges (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ edges = core.BNGetBasicBlockIncomingEdges(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ branch_type = BranchType(edges[i].type)
+ if edges[i].target:
+ target = BasicBlock(self.view, core.BNNewBasicBlockReference(edges[i].target))
else:
- arch = None
- result.append(BasicBlockEdge(branch_type, target, arch))
- core.BNFreeBasicBlockOutgoingEdgeList(edges)
+ target = None
+ result.append(BasicBlockEdge(branch_type, target))
+ core.BNFreeBasicBlockEdgeList(edges, count.value)
return result
@property
diff --git a/python/binaryview.py b/python/binaryview.py
index 9753b653..dd37be69 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -299,6 +299,16 @@ class BinaryViewType(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 __ne__(self, value):
+ if not isinstance(value, BinaryViewType):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def name(self):
"""BinaryView name (read-only)"""
@@ -547,6 +557,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, BinaryView):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@classmethod
def register(cls):
startup._init_plugins()
@@ -3255,6 +3275,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, BinaryReader):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def endianness(self):
"""
@@ -3562,6 +3592,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, BinaryWriter):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def endianness(self):
"""
diff --git a/python/callingconvention.py b/python/callingconvention.py
index 5f4adeab..04ba711f 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -112,6 +112,16 @@ class CallingConvention(object):
def __del__(self):
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 __ne__(self, value):
+ if not isinstance(value, CallingConvention):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
def _get_caller_saved_regs(self, ctxt, count):
try:
regs = self.__class__.caller_saved_regs
diff --git a/python/filemetadata.py b/python/filemetadata.py
index f6593405..b489d5bb 100644
--- a/python/filemetadata.py
+++ b/python/filemetadata.py
@@ -93,6 +93,16 @@ class FileMetadata(object):
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)
diff --git a/python/function.py b/python/function.py
index 3aeb8e22..4cdd6cc9 100644
--- a/python/function.py
+++ b/python/function.py
@@ -177,6 +177,16 @@ class Function(object):
core.BNReleaseAdvancedFunctionAnalysisDataMultiple(self.handle, self._advanced_analysis_requests)
core.BNFreeFunction(self.handle)
+ def __eq__(self, value):
+ if not isinstance(value, Function):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, Function):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@classmethod
def _unregister(cls, func):
handle = ctypes.cast(func, ctypes.c_void_p)
@@ -856,6 +866,16 @@ class FunctionGraphBlock(object):
def __del__(self):
core.BNFreeFunctionGraphBlock(self.handle)
+ def __eq__(self, value):
+ if not isinstance(value, FunctionGraphBlock):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, FunctionGraphBlock):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def basic_block(self):
"""Basic block associated with this part of the function graph (read-only)"""
@@ -1030,6 +1050,16 @@ class FunctionGraph(object):
self.abort()
core.BNFreeFunctionGraph(self.handle)
+ def __eq__(self, value):
+ if not isinstance(value, FunctionGraph):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, FunctionGraph):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def function(self):
"""Function for a function graph (read-only)"""
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 29b46b65..c80fcd0d 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -253,6 +253,16 @@ class LowLevelILFunction(object):
def __del__(self):
core.BNFreeLowLevelILFunction(self.handle)
+ def __eq__(self, value):
+ if not isinstance(value, LowLevelILFunction):
+ 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)
+
@property
def current_address(self):
"""Current IL Address (read/write)"""
diff --git a/python/platform.py b/python/platform.py
index ccc80476..139b7d5e 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -110,6 +110,16 @@ class Platform(object):
def __del__(self):
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 __ne__(self, value):
+ if not isinstance(value, Platform):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def default_calling_convention(self):
"""
diff --git a/python/transform.py b/python/transform.py
index 0c003738..40382c69 100644
--- a/python/transform.py
+++ b/python/transform.py
@@ -131,6 +131,16 @@ class Transform(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 __ne__(self, value):
+ if not isinstance(value, Transform):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
def _get_parameters(self, ctxt, count):
try:
count[0] = len(self.parameters)
diff --git a/python/types.py b/python/types.py
index 43aaa66f..ebaa36fc 100644
--- a/python/types.py
+++ b/python/types.py
@@ -139,6 +139,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, Symbol):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def type(self):
"""Symbol type (read-only)"""
@@ -194,6 +204,16 @@ class Type(object):
def __del__(self):
core.BNFreeType(self.handle)
+ def __eq__(self, value):
+ if not isinstance(value, Type):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, Type):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def type_class(self):
"""Type class (read-only)"""
@@ -491,6 +511,16 @@ 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 __ne__(self, value):
+ if not isinstance(value, NamedTypeReference):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def type_class(self):
return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.handle))
@@ -564,6 +594,16 @@ class Structure(object):
def __del__(self):
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 __ne__(self, value):
+ if not isinstance(value, Structure):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def members(self):
"""Structure member list (read-only)"""
@@ -652,6 +692,16 @@ class Enumeration(object):
def __del__(self):
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 __ne__(self, value):
+ if not isinstance(value, Enumeration):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
@property
def members(self):
"""Enumeration member list (read-only)"""