diff options
| author | Xusheng <xusheng@vector35.com> | 2020-08-31 17:53:02 +0800 |
|---|---|---|
| committer | Xusheng <xusheng@vector35.com> | 2020-09-03 21:14:41 +0800 |
| commit | aa407ca14f6a99c5a953ff564461ec8dac1e0a84 (patch) | |
| tree | 6c0e699b434893b1b8dc01702c114f348828c34d | |
| parent | c1b11a0085c780ac3d5e3400a31ad939b376ede3 (diff) | |
allow redefining an existing type
| -rw-r--r-- | binaryninjaapi.h | 6 | ||||
| -rw-r--r-- | binaryninjacore.h | 11 | ||||
| -rw-r--r-- | binaryview.cpp | 32 | ||||
| -rw-r--r-- | python/binaryview.py | 4 | ||||
| -rw-r--r-- | ui/createtypedialog.h | 4 | ||||
| -rw-r--r-- | ui/typeview.h | 2 |
6 files changed, 48 insertions, 11 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 692cbebf..99d74b16 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1659,9 +1659,11 @@ __attribute__ ((format (printf, 1, 2))) uint64_t GetPreviousDataBeforeAddress(uint64_t addr); uint64_t GetPreviousDataVariableStartBeforeAddress(uint64_t addr); - bool ParseTypeString(const std::string& text, QualifiedNameAndType& result, std::string& errors); + bool ParseTypeString(const std::string& text, QualifiedNameAndType& result, std::string& errors, + const std::set<QualifiedName>& typesAllowRedefinition = {}); bool ParseTypeString(const std::string& text, std::map<QualifiedName, Ref<Type>>& types, - std::map<QualifiedName, Ref<Type>>& variables, std::map<QualifiedName, Ref<Type>>& functions, std::string& errors); + std::map<QualifiedName, Ref<Type>>& variables, std::map<QualifiedName, Ref<Type>>& functions, std::string& errors, + const std::set<QualifiedName>& typesAllowRedefinition = {}); std::map<QualifiedName, Ref<Type>> GetTypes(); std::vector<QualifiedName> GetTypeNames(const std::string& matching=""); diff --git a/binaryninjacore.h b/binaryninjacore.h index 5d22367e..773f70c0 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1735,6 +1735,12 @@ extern "C" size_t typeCount, variableCount, functionCount; }; + struct BNQualifiedNameList + { + BNQualifiedName* names; + size_t count; + }; + enum BNUpdateResult { UpdateFailed = 0, @@ -3262,8 +3268,9 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI bool BNGetDataVariableAtAddress(BNBinaryView* view, uint64_t addr, BNDataVariable* var); BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text, - BNQualifiedNameAndType* result, char** errors); - BINARYNINJACOREAPI bool BNParseTypesString(BNBinaryView* view, const char* text, BNTypeParserResult* result, char** errors); + BNQualifiedNameAndType* result, char** errors, BNQualifiedNameList* typesAllowRedefinition); + BINARYNINJACOREAPI bool BNParseTypesString(BNBinaryView* view, const char* text, BNTypeParserResult* result, + char** errors, BNQualifiedNameList typesAllowRedefinition); BINARYNINJACOREAPI void BNFreeQualifiedNameAndType(BNQualifiedNameAndType* obj); BINARYNINJACOREAPI void BNFreeQualifiedNameAndTypeArray(BNQualifiedNameAndType* obj, size_t count); diff --git a/binaryview.cpp b/binaryview.cpp index 102578b7..9374c9b8 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -2446,15 +2446,27 @@ uint64_t BinaryView::GetPreviousDataVariableStartBeforeAddress(uint64_t addr) } -bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& result, string& errors) +bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& result, string& errors, + const std::set<QualifiedName>& typesAllowRedefinition) { BNQualifiedNameAndType nt; char* errorStr; - if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr)) + BNQualifiedNameList typesList; + typesList.count = typesAllowRedefinition.size(); + typesList.names = new BNQualifiedName[typesList.count]; + size_t i = 0; + for(auto& type : typesAllowRedefinition) + { + typesList.names[i] = type.GetAPIObject(); + i ++; + } + + if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr, &typesList)) { errors = errorStr; BNFreeString(errorStr); + delete[] typesList.names; return false; } @@ -2462,12 +2474,14 @@ bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& resul result.type = new Type(BNNewTypeReference(nt.type)); errors = ""; BNFreeQualifiedNameAndType(&nt); + delete[] typesList.names; return true; } bool BinaryView::ParseTypeString(const string& source, map<QualifiedName, Ref<Type>>& types, - map<QualifiedName, Ref<Type>>& variables, map<QualifiedName, Ref<Type>>& functions, string& errors) + map<QualifiedName, Ref<Type>>& variables, map<QualifiedName, Ref<Type>>& functions, string& errors, + const std::set<QualifiedName>& typesAllowRedefinition) { BNTypeParserResult result; char* errorStr = nullptr; @@ -2476,7 +2490,17 @@ bool BinaryView::ParseTypeString(const string& source, map<QualifiedName, Ref<Ty variables.clear(); functions.clear(); - bool ok = BNParseTypesString(m_object, source.c_str(), &result, &errorStr); + BNQualifiedNameList typesList; + typesList.count = typesAllowRedefinition.size(); + typesList.names = new BNQualifiedName[typesList.count]; + size_t i = 0; + for(auto& type : typesAllowRedefinition) + { + typesList.names[i] = type.GetAPIObject(); + i ++; + } + + bool ok = BNParseTypesString(m_object, source.c_str(), &result, &errorStr, typesList); if (errorStr) { errors = errorStr; diff --git a/python/binaryview.py b/python/binaryview.py index abcc5f49..2c20a694 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -4623,7 +4623,9 @@ class BinaryView(object): raise AttributeError("Source must be a string") result = core.BNQualifiedNameAndType() errors = ctypes.c_char_p() - if not core.BNParseTypeString(self.handle, text, result, errors): + type_list = core.BNQualifiedNameList() + type_list.count = 0 + if not core.BNParseTypeString(self.handle, text, result, errors, type_list): error_str = errors.value.decode("utf-8") core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise SyntaxError(error_str) diff --git a/ui/createtypedialog.h b/ui/createtypedialog.h index 552f2076..19880bc8 100644 --- a/ui/createtypedialog.h +++ b/ui/createtypedialog.h @@ -14,9 +14,11 @@ class BINARYNINJAUIAPI CreateTypeDialog: public QDialog BinaryViewRef m_data; std::map<BinaryNinja::QualifiedName, TypeRef> m_results; + std::set<BinaryNinja::QualifiedName> m_typesAllowRedefinition; public: - CreateTypeDialog(QWidget* parent, BinaryViewRef data, const QString& title, const QString& definition); + CreateTypeDialog(QWidget* parent, BinaryViewRef data, const QString& title, + const QString& definition, const std::set<BinaryNinja::QualifiedName>& typesAllowRedefinition = {}); std::map<BinaryNinja::QualifiedName, TypeRef> getResults() { return m_results; } private Q_SLOTS: diff --git a/ui/typeview.h b/ui/typeview.h index 1e3b1c25..bc2fcc10 100644 --- a/ui/typeview.h +++ b/ui/typeview.h @@ -140,7 +140,7 @@ class BINARYNINJAUIAPI TypeView: public QAbstractScrollArea, public View, public void goToAddress(bool selecting); void moveCursorToMouse(QMouseEvent* event, bool selecting); - void createNewTypes(const QString& definition = ""); + void createNewTypes(const QString& definition = "", const std::set<BinaryNinja::QualifiedName>& typesAllowRedefinition = {}); void bindActions(); void checkForValidSelection(); |
