summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2021-04-19 17:04:24 +0800
committerXusheng <xusheng@vector35.com>2021-05-04 14:04:39 +0800
commitad71a51fef925779f5ae30b597efb9979607b693 (patch)
tree5f5275f7dc9501c1c3ac824a67d497fc7f39f8fa
parent1e2bb984e2fe601b78a4afff3c9097f8f181f9c9 (diff)
render non-member access to type on a new line
add Python API for retrieving all type fields referenced by code change m_updatesRequired to std::atomic_bool fix potential UAF after calling AnalysisCompletionEvent::Cancel()
-rw-r--r--binaryninjaapi.h2
-rw-r--r--binaryninjacore.h5
-rw-r--r--binaryview.cpp18
-rw-r--r--python/binaryview.py26
-rw-r--r--ui/typeview.h10
5 files changed, 57 insertions, 4 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 6af35d69..8f9e8e61 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1618,6 +1618,8 @@ __attribute__ ((format (printf, 1, 2)))
std::vector<TypeReferenceSource> GetCodeReferencesForTypeFieldFrom(ReferenceSource src);
std::vector<TypeReferenceSource> GetCodeReferencesForTypeFieldFrom(ReferenceSource src, uint64_t len);
+ std::vector<uint64_t> GetAllFieldsReferencedByCode(const QualifiedName& type);
+
std::vector<uint64_t> GetCallees(ReferenceSource addr);
std::vector<ReferenceSource> GetCallers(uint64_t addr);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 0eabe6b1..41c3acc1 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -28,7 +28,7 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
-#define BN_CURRENT_CORE_ABI_VERSION 7
+#define BN_CURRENT_CORE_ABI_VERSION 8
// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
@@ -3416,6 +3416,9 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI BNTypeReferenceSource* BNGetCodeReferencesForTypeFieldsFrom(BNBinaryView* view, BNReferenceSource* addr, size_t* count);
BINARYNINJACOREAPI BNTypeReferenceSource* BNGetCodeReferencesForTypeFieldsFromInRange(BNBinaryView* view, BNReferenceSource* addr, uint64_t len, size_t* count);
+ BINARYNINJACOREAPI uint64_t* BNGetAllFieldsReferencedByCode(BNBinaryView* view,
+ BNQualifiedName* type, size_t* count);
+
BINARYNINJACOREAPI void BNRegisterGlobalFunctionRecognizer(BNFunctionRecognizer* rec);
BINARYNINJACOREAPI bool BNGetStringAtAddress(BNBinaryView* view, uint64_t addr, BNStringReference* strRef);
diff --git a/binaryview.cpp b/binaryview.cpp
index bde0afca..ec3fc8f7 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -362,6 +362,8 @@ void AnalysisCompletionEvent::Cancel()
{
unique_lock<recursive_mutex> lock(m_mutex);
m_callback = []() {};
+ // This allows the API side to free the BinaryNinja::AnalysisCompletionEvent object
+ BNCancelAnalysisCompletionEvent(m_object);
}
@@ -2061,6 +2063,20 @@ vector<TypeReferenceSource> BinaryView::GetCodeReferencesForTypeFieldFrom(Refere
}
+vector<uint64_t> BinaryView::GetAllFieldsReferencedByCode(const QualifiedName& type)
+{
+ size_t count;
+ BNQualifiedName nameObj = type.GetAPIObject();
+ uint64_t* fields = BNGetAllFieldsReferencedByCode(m_object, &nameObj, &count);
+
+ vector<uint64_t> result(fields, &fields[count]);
+ // Data refs and the fields above are both an array of uint64_t, so they can be freed in
+ // the same way
+ BNFreeDataReferences(fields);
+ return result;
+}
+
+
vector<uint64_t> BinaryView::GetCallees(ReferenceSource callSite)
{
size_t count;
@@ -2594,6 +2610,8 @@ vector<BNStringReference> BinaryView::GetStrings(uint64_t start, uint64_t len)
}
+// The caller of this function must hold a reference to the returned Ref<AnalysisCompletionEvent>.
+// Otherwise, it can be freed before the callback is triggered, leading to a crash.
Ref<AnalysisCompletionEvent> BinaryView::AddAnalysisCompletionEvent(const function<void()>& callback)
{
return new AnalysisCompletionEvent(this, callback);
diff --git a/python/binaryview.py b/python/binaryview.py
index 43f2e9db..5adbff87 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -3705,6 +3705,32 @@ class BinaryView(object):
core.BNRemoveUserDataReference(self.handle, from_addr, to_addr)
+ def get_all_type_fields_referenced_by_code(self, name):
+ """
+ ``get_all_type_fields_referenced_by_code`` returns a list of offsets in the QualifiedName
+ specified by name, which are referenced by code.
+
+ :param QualifiedName name: name of type to query for references
+ :return: List of offsets
+ :rtype: list(integer)
+ :Example:
+
+ >>> bv.get_all_type_fields_referenced_by_code('A')
+ ['<type D, offset 0x8, direct>', '<type C, offset 0x10, indirect>']
+ >>>
+
+ """
+ count = ctypes.c_ulonglong(0)
+ name = types.QualifiedName(name)._get_core_struct()
+ refs = core.BNGetAllFieldsReferencedByCode(self.handle, name, count)
+
+ result = []
+ for i in range(0, count.value):
+ result.append(refs[i])
+
+ core.BNFreeDataReferences(refs, count.value)
+ return result
+
def get_callers(self, addr):
"""
``get_callers`` returns a list of ReferenceSource objects (xrefs or cross-references) that call the provided virtual address.
diff --git a/ui/typeview.h b/ui/typeview.h
index b9dab368..87f64ae2 100644
--- a/ui/typeview.h
+++ b/ui/typeview.h
@@ -28,7 +28,8 @@ enum BINARYNINJAUIAPI TypeDefinitionLineType
EnumDefinitionLineType,
EnumMemberLineType,
EnumDefinitionEndLineType,
- PaddingLineType
+ PaddingLineType,
+ UndefinedXrefLineType
};
struct BINARYNINJAUIAPI TypeDefinitionLine
@@ -113,7 +114,8 @@ class BINARYNINJAUIAPI TypeView: public QAbstractScrollArea, public View, public
std::map<BinaryNinja::QualifiedName, std::vector<TypeDefinitionLine>> m_typeLines;
std::vector<TypeLineIndex> m_types;
- bool m_updatesRequired;
+ BinaryNinja::Ref<BinaryNinja::AnalysisCompletionEvent> m_completionEvent = nullptr;
+ std::atomic_bool m_updatesRequired;
QTimer* m_updateTimer;
Qt::KeyboardModifiers m_ctrl, m_command;
@@ -208,7 +210,9 @@ public:
virtual ArchitectureRef getOrAskForArchitecture();
- static std::vector<TypeDefinitionLine> getLinesForType(const std::string& name, const std::string& varName, size_t index, TypeRef type, TypeRef parent, int paddingCols);
+ static std::vector<TypeDefinitionLine> getLinesForType(const std::string& name,
+ const std::string& varName, size_t index, TypeRef type, TypeRef parent, BinaryViewRef data,
+ int paddingCols);
protected:
virtual void resizeEvent(QResizeEvent* event) override;