diff options
| author | Xusheng <xusheng@vector35.com> | 2021-04-19 17:04:24 +0800 |
|---|---|---|
| committer | Xusheng <xusheng@vector35.com> | 2021-05-04 14:04:39 +0800 |
| commit | ad71a51fef925779f5ae30b597efb9979607b693 (patch) | |
| tree | 5f5275f7dc9501c1c3ac824a67d497fc7f39f8fa | |
| parent | 1e2bb984e2fe601b78a4afff3c9097f8f181f9c9 (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.h | 2 | ||||
| -rw-r--r-- | binaryninjacore.h | 5 | ||||
| -rw-r--r-- | binaryview.cpp | 18 | ||||
| -rw-r--r-- | python/binaryview.py | 26 | ||||
| -rw-r--r-- | ui/typeview.h | 10 |
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; |
