summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2020-08-31 17:53:02 +0800
committerXusheng <xusheng@vector35.com>2020-09-03 21:14:41 +0800
commitaa407ca14f6a99c5a953ff564461ec8dac1e0a84 (patch)
tree6c0e699b434893b1b8dc01702c114f348828c34d
parentc1b11a0085c780ac3d5e3400a31ad939b376ede3 (diff)
allow redefining an existing type
-rw-r--r--binaryninjaapi.h6
-rw-r--r--binaryninjacore.h11
-rw-r--r--binaryview.cpp32
-rw-r--r--python/binaryview.py4
-rw-r--r--ui/createtypedialog.h4
-rw-r--r--ui/typeview.h2
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();