diff options
| -rw-r--r-- | binaryninjaapi.h | 81 | ||||
| -rw-r--r-- | binaryninjacore.h | 73 | ||||
| -rw-r--r-- | binaryview.cpp | 14 | ||||
| -rw-r--r-- | binaryviewtype.cpp | 17 | ||||
| -rw-r--r-- | examples/triage/files.cpp | 17 | ||||
| -rw-r--r-- | examples/triage/triage.cpp | 11 | ||||
| -rw-r--r-- | examples/triage/view.cpp | 11 | ||||
| -rw-r--r-- | python/binaryview.py | 30 | ||||
| -rw-r--r-- | python/settings.py | 136 | ||||
| -rw-r--r-- | settings.cpp | 148 | ||||
| -rw-r--r-- | suite/api_test.py | 173 | ||||
| -rw-r--r-- | ui/disassemblyview.h | 1 | ||||
| -rw-r--r-- | ui/uitypes.h | 1 |
13 files changed, 435 insertions, 278 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 02dc26c2..68eee4db 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -544,6 +544,7 @@ namespace BinaryNinja class Architecture; class BackgroundTask; class Platform; + class Settings; class Type; class DataBuffer; class MainThreadAction; @@ -1672,8 +1673,8 @@ namespace BinaryNinja std::vector<uint8_t> GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); - std::string GetLoadSettings(std::string typeName); - void SetLoadSettings(std::string typeName, std::string loadSettings); + Ref<Settings> GetLoadSettings(std::string typeName); + void SetLoadSettings(std::string typeName, Ref<Settings> settings); BNAnalysisParameters GetParametersForAnalysis(); void SetParametersForAnalysis(BNAnalysisParameters params); @@ -1723,7 +1724,7 @@ namespace BinaryNinja static BNBinaryView* CreateCallback(void* ctxt, BNBinaryView* data); static bool IsValidCallback(void* ctxt, BNBinaryView* data); - static char* GetSettingsCallback(void* ctxt, BNBinaryView* data); + static BNSettings* GetSettingsCallback(void* ctxt, BNBinaryView* data); BinaryViewType(BNBinaryViewType* type); @@ -1751,7 +1752,7 @@ namespace BinaryNinja virtual BinaryView* Create(BinaryView* data) = 0; virtual bool IsTypeValidForData(BinaryView* data) = 0; - virtual std::string GetLoadSettingsForData(BinaryView* data) = 0; + virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) = 0; }; class CoreBinaryViewType: public BinaryViewType @@ -1760,7 +1761,7 @@ namespace BinaryNinja CoreBinaryViewType(BNBinaryViewType* type); virtual BinaryView* Create(BinaryView* data) override; virtual bool IsTypeValidForData(BinaryView* data) override; - virtual std::string GetLoadSettingsForData(BinaryView* data) override; + virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) override; }; class ReadException: public std::exception @@ -4493,57 +4494,63 @@ namespace BinaryNinja Ref<Repository> GetDefaultRepository(); }; - class Settings + class Settings: public CoreRefCountObject<BNSettings, BNNewSettingsReference, BNFreeSettings> { - std::string m_registry; + std::string m_instanceId; + + Settings() = delete; + Settings(const std::string& m_instanceId); public: - Settings(const std::string& registry = "default") : m_registry(registry) { } + Settings(BNSettings* settings); + static Ref<Settings> Instance(const std::string& schemaId = ""); + virtual ~Settings() {} bool RegisterGroup(const std::string& group, const std::string& title); - bool RegisterSetting(const std::string& id, const std::string& properties); + bool RegisterSetting(const std::string& key, const std::string& properties); + bool Contains(const std::string& key); - template<typename T> T QueryProperty(const std::string& id, const std::string& property); + template<typename T> T QueryProperty(const std::string& key, const std::string& property); - bool UpdateProperty(const std::string& id, const std::string& property); - bool UpdateProperty(const std::string& id, const std::string& property, bool value); - bool UpdateProperty(const std::string& id, const std::string& property, double value); - bool UpdateProperty(const std::string& id, const std::string& property, int value); - bool UpdateProperty(const std::string& id, const std::string& property, int64_t value); - bool UpdateProperty(const std::string& id, const std::string& property, uint64_t value); - bool UpdateProperty(const std::string& id, const std::string& property, const char* value); - bool UpdateProperty(const std::string& id, const std::string& property, const std::string& value); - bool UpdateProperty(const std::string& id, const std::string& property, const std::vector<std::string>& value); + bool UpdateProperty(const std::string& key, const std::string& property); + bool UpdateProperty(const std::string& key, const std::string& property, bool value); + bool UpdateProperty(const std::string& key, const std::string& property, double value); + bool UpdateProperty(const std::string& key, const std::string& property, int value); + bool UpdateProperty(const std::string& key, const std::string& property, int64_t value); + bool UpdateProperty(const std::string& key, const std::string& property, uint64_t value); + bool UpdateProperty(const std::string& key, const std::string& property, const char* value); + bool UpdateProperty(const std::string& key, const std::string& property, const std::string& value); + bool UpdateProperty(const std::string& key, const std::string& property, const std::vector<std::string>& value); bool DeserializeSchema(const std::string& schema); std::string SerializeSchema(); bool DeserializeSettings(const std::string& contents, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); std::string SerializeSettings(Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool CopyValue(const std::string& destRegistry, const std::string& id); - bool Reset(const std::string& id, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool CopyValuesFrom(Ref<Settings> source, BNSettingsScope scope = SettingsAutoScope); + bool Reset(const std::string& key, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); bool ResetAll(Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - template<typename T> T Get(const std::string& id, Ref<BinaryView> view = nullptr, BNSettingsScope* scope = nullptr); + template<typename T> T Get(const std::string& key, Ref<BinaryView> view = nullptr, BNSettingsScope* scope = nullptr); - bool Set(const std::string& id, bool value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, double value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, int value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, int64_t value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, uint64_t value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, const char* value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, const std::string& value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); - bool Set(const std::string& id, const std::vector<std::string>& value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, bool value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, double value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, int value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, int64_t value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, uint64_t value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, const char* value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, const std::string& value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); + bool Set(const std::string& key, const std::vector<std::string>& value, Ref<BinaryView> view = nullptr, BNSettingsScope scope = SettingsAutoScope); }; // explicit specializations - template<> std::vector<std::string> Settings::QueryProperty<std::vector<std::string>>(const std::string& id, const std::string& property); - template<> bool Settings::Get<bool>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); - template<> double Settings::Get<double>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); - template<> int64_t Settings::Get<int64_t>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); - template<> uint64_t Settings::Get<uint64_t>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); - template<> std::string Settings::Get<std::string>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); - template<> std::vector<std::string> Settings::Get<std::vector<std::string>>(const std::string& id, Ref<BinaryView> view, BNSettingsScope* scope); + template<> std::vector<std::string> Settings::QueryProperty<std::vector<std::string>>(const std::string& key, const std::string& property); + template<> bool Settings::Get<bool>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); + template<> double Settings::Get<double>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); + template<> int64_t Settings::Get<int64_t>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); + template<> uint64_t Settings::Get<uint64_t>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); + template<> std::string Settings::Get<std::string>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); + template<> std::vector<std::string> Settings::Get<std::vector<std::string>>(const std::string& key, Ref<BinaryView> view, BNSettingsScope* scope); typedef BNMetadataType MetadataType; diff --git a/binaryninjacore.h b/binaryninjacore.h index 7dc1f8c2..7ae63459 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -151,6 +151,7 @@ extern "C" struct BNRepository; struct BNRepoPlugin; struct BNRepositoryManager; + struct BNSettings; struct BNMetadata; struct BNReportCollection; struct BNRelocation; @@ -1127,7 +1128,7 @@ extern "C" void* context; BNBinaryView* (*create)(void* ctxt, BNBinaryView* data); bool (*isValidForData)(void* ctxt, BNBinaryView* data); - char* (*getLoadSettingsForData)(void* ctxt, BNBinaryView* data); + BNSettings* (*getLoadSettingsForData)(void* ctxt, BNBinaryView* data); }; struct BNTransformParameterInfo @@ -2334,8 +2335,8 @@ extern "C" BINARYNINJACOREAPI char* BNGetBinaryViewTypeLongName(BNBinaryViewType* type); BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data); BINARYNINJACOREAPI bool BNIsBinaryViewTypeValidForData(BNBinaryViewType* type, BNBinaryView* data); - BINARYNINJACOREAPI char* BNGetBinaryViewDefaultLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data); - BINARYNINJACOREAPI char* BNGetBinaryViewLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data); + BINARYNINJACOREAPI BNSettings* BNGetBinaryViewDefaultLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data); + BINARYNINJACOREAPI BNSettings* BNGetBinaryViewLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data); BINARYNINJACOREAPI BNBinaryViewType* BNRegisterBinaryViewType(const char* name, const char* longName, BNCustomBinaryViewType* type); @@ -3934,39 +3935,43 @@ extern "C" BINARYNINJACOREAPI bool BNRenameFile(const char* source, const char* dest); // Settings APIs - BINARYNINJACOREAPI bool BNSettingsRegisterGroup(const char* registry, const char* group, const char* title); - BINARYNINJACOREAPI bool BNSettingsRegisterSetting(const char* registry, const char* id, const char* properties); - BINARYNINJACOREAPI const char** BNSettingsQueryPropertyStringList(const char* registry, const char* id, const char* property, size_t* inoutSize); - BINARYNINJACOREAPI bool BNSettingsUpdateProperty(const char* registry, const char* id, const char* property); - BINARYNINJACOREAPI bool BNSettingsUpdateBoolProperty(const char* registry, const char* id, const char* property, bool value); - BINARYNINJACOREAPI bool BNSettingsUpdateDoubleProperty(const char* registry, const char* id, const char* property, double value); - BINARYNINJACOREAPI bool BNSettingsUpdateInt64Property(const char* registry, const char* id, const char* property, int64_t value); - BINARYNINJACOREAPI bool BNSettingsUpdateUInt64Property(const char* registry, const char* id, const char* property, uint64_t value); - BINARYNINJACOREAPI bool BNSettingsUpdateStringProperty(const char* registry, const char* id, const char* property, const char* value); - BINARYNINJACOREAPI bool BNSettingsUpdateStringListProperty(const char* registry, const char* id, const char* property, const char** value, size_t size); + BINARYNINJACOREAPI BNSettings* BNCreateSettings(const char* schemaId); + BINARYNINJACOREAPI BNSettings* BNNewSettingsReference(BNSettings* settings); + BINARYNINJACOREAPI void BNFreeSettings(BNSettings* settings); + BINARYNINJACOREAPI bool BNSettingsRegisterGroup(BNSettings* settings, const char* group, const char* title); + BINARYNINJACOREAPI bool BNSettingsRegisterSetting(BNSettings* settings, const char* key, const char* properties); + BINARYNINJACOREAPI bool BNSettingsContains(BNSettings* settings, const char* key); + BINARYNINJACOREAPI const char** BNSettingsQueryPropertyStringList(BNSettings* settings, const char* key, const char* property, size_t* inoutSize); + BINARYNINJACOREAPI bool BNSettingsUpdateProperty(BNSettings* settings, const char* key, const char* property); + BINARYNINJACOREAPI bool BNSettingsUpdateBoolProperty(BNSettings* settings, const char* key, const char* property, bool value); + BINARYNINJACOREAPI bool BNSettingsUpdateDoubleProperty(BNSettings* settings, const char* key, const char* property, double value); + BINARYNINJACOREAPI bool BNSettingsUpdateInt64Property(BNSettings* settings, const char* key, const char* property, int64_t value); + BINARYNINJACOREAPI bool BNSettingsUpdateUInt64Property(BNSettings* settings, const char* key, const char* property, uint64_t value); + BINARYNINJACOREAPI bool BNSettingsUpdateStringProperty(BNSettings* settings, const char* key, const char* property, const char* value); + BINARYNINJACOREAPI bool BNSettingsUpdateStringListProperty(BNSettings* settings, const char* key, const char* property, const char** value, size_t size); - BINARYNINJACOREAPI bool BNSettingsDeserializeSchema(const char* registry, const char* schema); - BINARYNINJACOREAPI char* BNSettingsSerializeSchema(const char* registry); - BINARYNINJACOREAPI bool BNDeserializeSettings(const char* registry, const char* contents, BNBinaryView* view, BNSettingsScope scope); - BINARYNINJACOREAPI char* BNSerializeSettings(const char* registry, BNBinaryView* view, BNSettingsScope scope); + BINARYNINJACOREAPI bool BNSettingsDeserializeSchema(BNSettings* settings, const char* schema); + BINARYNINJACOREAPI char* BNSettingsSerializeSchema(BNSettings* settings); + BINARYNINJACOREAPI bool BNDeserializeSettings(BNSettings* settings, const char* contents, BNBinaryView* view, BNSettingsScope scope); + BINARYNINJACOREAPI char* BNSerializeSettings(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope); - BINARYNINJACOREAPI bool BNSettingsCopyValue(const char* registry, const char* destRegistry, const char* id); - BINARYNINJACOREAPI bool BNSettingsReset(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope scope); - BINARYNINJACOREAPI bool BNSettingsResetAll(const char* registry, BNBinaryView* view, BNSettingsScope scope); + BINARYNINJACOREAPI bool BNSettingsCopyValuesFrom(BNSettings* settings, BNSettings* source, BNSettingsScope scope); + BINARYNINJACOREAPI bool BNSettingsReset(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope scope); + BINARYNINJACOREAPI bool BNSettingsResetAll(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope); - BINARYNINJACOREAPI bool BNSettingsGetBool(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope); - BINARYNINJACOREAPI double BNSettingsGetDouble(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope); - BINARYNINJACOREAPI int64_t BNSettingsGetInt64(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope); - BINARYNINJACOREAPI uint64_t BNSettingsGetUInt64(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope); - BINARYNINJACOREAPI char* BNSettingsGetString(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope); - BINARYNINJACOREAPI const char** BNSettingsGetStringList(const char* registry, const char* id, BNBinaryView* view, BNSettingsScope* scope, size_t* inoutSize); + BINARYNINJACOREAPI bool BNSettingsGetBool(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope); + BINARYNINJACOREAPI double BNSettingsGetDouble(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope); + BINARYNINJACOREAPI int64_t BNSettingsGetInt64(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope); + BINARYNINJACOREAPI uint64_t BNSettingsGetUInt64(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope); + BINARYNINJACOREAPI char* BNSettingsGetString(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope); + BINARYNINJACOREAPI const char** BNSettingsGetStringList(BNSettings* settings, const char* key, BNBinaryView* view, BNSettingsScope* scope, size_t* inoutSize); - BINARYNINJACOREAPI bool BNSettingsSetBool(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, bool value); - BINARYNINJACOREAPI bool BNSettingsSetDouble(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, double value); - BINARYNINJACOREAPI bool BNSettingsSetInt64(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, int64_t value); - BINARYNINJACOREAPI bool BNSettingsSetUInt64(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, uint64_t value); - BINARYNINJACOREAPI bool BNSettingsSetString(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, const char* value); - BINARYNINJACOREAPI bool BNSettingsSetStringList(const char* registry, BNBinaryView* view, BNSettingsScope scope, const char* id, const char** value, size_t size); + BINARYNINJACOREAPI bool BNSettingsSetBool(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, bool value); + BINARYNINJACOREAPI bool BNSettingsSetDouble(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, double value); + BINARYNINJACOREAPI bool BNSettingsSetInt64(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, int64_t value); + BINARYNINJACOREAPI bool BNSettingsSetUInt64(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, uint64_t value); + BINARYNINJACOREAPI bool BNSettingsSetString(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, const char* value); + BINARYNINJACOREAPI bool BNSettingsSetStringList(BNSettings* settings, BNBinaryView* view, BNSettingsScope scope, const char* key, const char** value, size_t size); //Metadata APIs @@ -4022,8 +4027,8 @@ extern "C" BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key); BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key); - BINARYNINJACOREAPI char* BNBinaryViewGetLoadSettings(BNBinaryView* view, const char* typeName); - BINARYNINJACOREAPI void BNBinaryViewSetLoadSettings(BNBinaryView* view, const char* typeName, const char* loadSettings); + BINARYNINJACOREAPI BNSettings* BNBinaryViewGetLoadSettings(BNBinaryView* view, const char* typeName); + BINARYNINJACOREAPI void BNBinaryViewSetLoadSettings(BNBinaryView* view, const char* typeName, BNSettings* settings); // Relocation object methods BINARYNINJACOREAPI BNRelocation* BNNewRelocationReference(BNRelocation* reloc); diff --git a/binaryview.cpp b/binaryview.cpp index 553ce251..c62b434e 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -2977,18 +2977,18 @@ uint64_t BinaryView::GetUIntMetadata(const string& key) } -string BinaryView::GetLoadSettings(string typeName) +Ref<Settings> BinaryView::GetLoadSettings(string typeName) { - char* name = BNBinaryViewGetLoadSettings(m_object, typeName.c_str()); - string result = name; - BNFreeString(name); - return result; + BNSettings* settings = BNBinaryViewGetLoadSettings(m_object, typeName.c_str()); + if (!settings) + return nullptr; + return new Settings(settings); } -void BinaryView::SetLoadSettings(string typeName, string loadSettings) +void BinaryView::SetLoadSettings(string typeName, Ref<Settings> settings) { - BNBinaryViewSetLoadSettings(m_object, typeName.c_str(), loadSettings.c_str()); + BNBinaryViewSetLoadSettings(m_object, typeName.c_str(), settings->GetObject()); } diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp index 815b508e..bd99bf80 100644 --- a/binaryviewtype.cpp +++ b/binaryviewtype.cpp @@ -43,11 +43,14 @@ bool BinaryViewType::IsValidCallback(void* ctxt, BNBinaryView* data) } -char* BinaryViewType::GetSettingsCallback(void* ctxt, BNBinaryView* data) +BNSettings* BinaryViewType::GetSettingsCallback(void* ctxt, BNBinaryView* data) { BinaryViewType* type = (BinaryViewType*)ctxt; Ref<BinaryView> view = new BinaryView(BNNewViewReference(data)); - return BNAllocString(type->GetLoadSettingsForData(view).c_str()); + Ref<Settings> result = type->GetLoadSettingsForData(view); + if (!result) + return nullptr; + return BNNewSettingsReference(result->GetObject()); } @@ -220,10 +223,10 @@ bool CoreBinaryViewType::IsTypeValidForData(BinaryView* data) } -string CoreBinaryViewType::GetLoadSettingsForData(BinaryView* data) +Ref<Settings> CoreBinaryViewType::GetLoadSettingsForData(BinaryView* data) { - char* settings = BNGetBinaryViewLoadSettingsForData(m_object, data->GetObject()); - string result = settings; - BNFreeString(settings); - return result; + BNSettings* settings = BNGetBinaryViewLoadSettingsForData(m_object, data->GetObject()); + if (!settings) + return nullptr; + return new Settings(settings); } diff --git a/examples/triage/files.cpp b/examples/triage/files.cpp index 7c0f7b9c..e2f86e0f 100644 --- a/examples/triage/files.cpp +++ b/examples/triage/files.cpp @@ -63,6 +63,7 @@ void TriageFilePicker::openSelectedFiles() { std::vector<QString> failedToOpen; std::set<QString> files; + SettingsRef settings = BinaryNinja::Settings::Instance(); for (auto& index: m_tree->selectionModel()->selectedIndexes()) if (m_model->fileInfo(index).isFile()) @@ -81,24 +82,24 @@ void TriageFilePicker::openSelectedFiles() for (auto data: f->getAllDataViews()) { - BinaryNinja::Settings().Set("analysis.mode", BinaryNinja::Settings().Get<std::string>("triage.analysisMode"), data); - BinaryNinja::Settings().Set("triage.preferSummaryView", true, data); + settings->Set("analysis.mode", settings->Get<std::string>("triage.analysisMode"), data); + settings->Set("triage.preferSummaryView", true, data); if (data->GetTypeName() != "Raw") { - std::string linearSweepMode = BinaryNinja::Settings().Get<std::string>("triage.linearSweep"); + std::string linearSweepMode = settings->Get<std::string>("triage.linearSweep"); if (linearSweepMode == "none") { - BinaryNinja::Settings().Set("analysis.linearSweep.autorun", false, data); + settings->Set("analysis.linearSweep.autorun", false, data); } else if (linearSweepMode == "partial") { - BinaryNinja::Settings().Set("analysis.linearSweep.autorun", true, data); - BinaryNinja::Settings().Set("analysis.linearSweep.controlFlowGraph", false, data); + settings->Set("analysis.linearSweep.autorun", true, data); + settings->Set("analysis.linearSweep.controlFlowGraph", false, data); } else if (linearSweepMode == "full") { - BinaryNinja::Settings().Set("analysis.linearSweep.autorun", true, data); - BinaryNinja::Settings().Set("analysis.linearSweep.controlFlowGraph", true, data); + settings->Set("analysis.linearSweep.autorun", true, data); + settings->Set("analysis.linearSweep.controlFlowGraph", true, data); } } } diff --git a/examples/triage/triage.cpp b/examples/triage/triage.cpp index 37431d65..ae48ead2 100644 --- a/examples/triage/triage.cpp +++ b/examples/triage/triage.cpp @@ -12,8 +12,9 @@ extern "C" BINARYNINJAPLUGIN bool UIPluginInit() #endif { - BinaryNinja::Settings().RegisterGroup("triage", "Triage"); - BinaryNinja::Settings().RegisterSetting("triage.preferSummaryView", + SettingsRef settings = BinaryNinja::Settings::Instance(); + settings->RegisterGroup("triage", "Triage"); + settings->RegisterSetting("triage.preferSummaryView", R"({ "title" : "Always Prefer Triage Summary View", "type" : "boolean", @@ -21,7 +22,7 @@ extern "C" "description" : "Always prefer opening binaries in Triage Summary view, even when performing full analysis." })"); - BinaryNinja::Settings().RegisterSetting("triage.preferSummaryViewForRaw", + settings->RegisterSetting("triage.preferSummaryViewForRaw", R"({ "title" : "Prefer Triage Summary View for Raw Files", "type" : "boolean", @@ -31,7 +32,7 @@ extern "C" ViewType::registerViewType(new TriageViewType()); - BinaryNinja::Settings().RegisterSetting("triage.analysisMode", + settings->RegisterSetting("triage.analysisMode", R"({ "title" : "Triage Analysis Mode", "type" : "string", @@ -44,7 +45,7 @@ extern "C" "Perform full analysis of the binary." ] })"); - BinaryNinja::Settings().RegisterSetting("triage.linearSweep", + settings->RegisterSetting("triage.linearSweep", R"({ "title" : "Triage Linear Sweep Mode", "type" : "string", diff --git a/examples/triage/view.cpp b/examples/triage/view.cpp index e4077521..ddd1d4ff 100644 --- a/examples/triage/view.cpp +++ b/examples/triage/view.cpp @@ -99,7 +99,7 @@ TriageView::TriageView(QWidget* parent, BinaryViewRef data): QScrollArea(parent) setWidgetResizable(true); setWidget(container); - if (m_fullAnalysisButton && (BinaryNinja::Settings().Get<std::string>("analysis.mode", data) == "full")) + if (m_fullAnalysisButton && (BinaryNinja::Settings::Instance()->Get<std::string>("analysis.mode", data) == "full")) m_fullAnalysisButton->hide(); } @@ -153,7 +153,7 @@ bool TriageView::navigate(uint64_t addr) void TriageView::startFullAnalysis() { - BinaryNinja::Settings().Set("analysis.mode", "full", m_data); + BinaryNinja::Settings::Instance()->Set("analysis.mode", "full", m_data); for (auto& f: m_data->GetAnalysisFunctionList()) { if (f->IsAnalysisSkipped()) @@ -220,9 +220,10 @@ TriageViewType::TriageViewType(): ViewType("Triage", "Triage Summary") int TriageViewType::getPriority(BinaryViewRef data, const QString&) { - bool full = BinaryNinja::Settings().Get<std::string>("analysis.mode", data) == "full"; - bool alwaysPrefer = BinaryNinja::Settings().Get<bool>("triage.preferSummaryView", data); - bool preferForRaw = BinaryNinja::Settings().Get<bool>("triage.preferSummaryViewForRaw", data); + BinaryNinja::Ref<BinaryNinja::Settings> settings = BinaryNinja::Settings::Instance(); + bool full = settings->Get<std::string>("analysis.mode", data) == "full"; + bool alwaysPrefer = settings->Get<bool>("triage.preferSummaryView", data); + bool preferForRaw = settings->Get<bool>("triage.preferSummaryViewForRaw", data); if (data->IsExecutable() && (alwaysPrefer || !full)) return 100; if (data->GetLength() > 0) diff --git a/python/binaryview.py b/python/binaryview.py index fe8fde76..fc6b816d 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -42,6 +42,7 @@ from binaryninja import lineardisassembly from binaryninja import metadata from binaryninja import highlight from binaryninja import function +from binaryninja import settings # 2-3 compatibility from binaryninja import range @@ -680,10 +681,16 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)): return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle) def get_default_load_settings_for_data(self, data): - return core.BNGetBinaryViewDefaultLoadSettingsForData(self.handle, data.handle) + load_settings = core.BNGetBinaryViewDefaultLoadSettingsForData(self.handle, data.handle) + if load_settings is None: + return None + return settings.Settings(handle=load_settings) def get_load_settings_for_data(self, data): - return core.BNGetBinaryViewLoadSettingsForData(self.handle, data.handle) + load_settings = core.BNGetBinaryViewLoadSettingsForData(self.handle, data.handle) + if load_settings is None: + return None + return settings.Settings(handle=load_settings) def register_arch(self, ident, endian, arch): core.BNRegisterArchitectureForViewType(self.handle, ident, endian, arch.handle) @@ -1148,10 +1155,15 @@ class BinaryView(object): @classmethod def _get_load_settings_for_data(cls, ctxt, data): try: - return cls.get_load_settings_for_data(BinaryView(handle=core.BNNewViewReference(data))) + attr = getattr(cls, "get_load_settings_for_data", None) + if callable(attr): + result = cls.get_load_settings_for_data(BinaryView(handle=core.BNNewViewReference(data))) + return ctypes.cast(core.BNNewSettingsReference(result.handle), ctypes.c_void_p).value + else: + return None except: log.log_error(traceback.format_exc()) - return core.BNAllocString("") + return None @classmethod def open(cls, src, file_metadata=None): @@ -4862,13 +4874,13 @@ class BinaryView(object): core.BNBinaryViewRemoveMetadata(self.handle, key) def get_load_settings(self, type_name): - settings_id = core.BNBinaryViewGetLoadSettings(self.handle, type_name) - if settings_id == "": + settings_handle = core.BNBinaryViewGetLoadSettings(self.handle, type_name) + if settings_handle is None: return None - return settings_id + return settings.Settings(handle=settings_handle) - def set_load_settings(self, type_name, load_settings): - core.BNBinaryViewSetLoadSettings(self.handle, type_name, load_settings) + def set_load_settings(self, type_name, settings): + core.BNBinaryViewSetLoadSettings(self.handle, type_name, settings.handle) def __setattr__(self, name, value): try: diff --git a/python/settings.py b/python/settings.py index 8bfe7255..df3522fa 100644 --- a/python/settings.py +++ b/python/settings.py @@ -30,17 +30,46 @@ from binaryninja.enums import SettingsScope class Settings(object): - def __init__(self, registry_id = "default"): - self._registry_id = registry_id + handle = core.BNCreateSettings("default") + + def __init__(self, instance_id = "default", handle = None): + if handle is None: + if instance_id is None or instance_id is "": + instance_id = "default" + self._instance_id = instance_id + if instance_id == "default": + self.handle = Settings.handle + else: + self.handle = core.BNCreateSettings(instance_id) + else: + instance_id = core.BNGetUniqueIdentifierString() + self.handle = handle + + def __del__(self): + if self.handle is not Settings.handle and self.handle is not None: + core.BNFreeSettings(self.handle) + + def __eq__(self, value): + if not isinstance(value, Settings): + return False + return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents) + + def __ne__(self, value): + if not isinstance(value, Settings): + return True + return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + + def __hash__(self): + return hash((self.instance_id, self.handle)) @property - def registry_id(self): + def instance_id(self): """(read-only)""" - return self._registry_id + return self._instance_id def register_group(self, group, title): """ - ``register_group`` registers a group for use with this Settings registry. Groups provide a simple way to organize settings. + ``register_group`` registers a group for use with this Settings instance. Groups provide a simple way to organize settings. :param str group: a unique identifier :param str title: a user friendly name appropriate for UI presentation @@ -52,13 +81,13 @@ class Settings(object): True >>> """ - return core.BNSettingsRegisterGroup(self._registry_id, group, title) + return core.BNSettingsRegisterGroup(self.handle, group, title) - def register_setting(self, id, properties): + def register_setting(self, key, properties): """ - ``register_setting`` registers a new setting with this Settings registry. + ``register_setting`` registers a new setting with this Settings instance. - :param str id: a unique setting identifier in the form <group>.<id> + :param str key: a unique setting identifier in the form <group>.<name> :param str properties: a JSON string describes the setting schema :return: True on success, False on failure. :rtype: bool @@ -66,134 +95,137 @@ class Settings(object): >>> Settings().register_group("solver", "Solver") True - >>> Settings().register_setting("solver.basicBlockSlicing", '{"description" : "Enable the basic block slicing in the solver.", "title" : "Basic Block Slicing", "default" : true, "type" : "boolean", "id" : "basicBlockSlicing"}') + >>> Settings().register_setting("solver.basicBlockSlicing", '{"description" : "Enable the basic block slicing in the solver.", "title" : "Basic Block Slicing", "default" : true, "type" : "boolean"}') True """ - return core.BNSettingsRegisterSetting(self._registry_id, id, properties) + return core.BNSettingsRegisterSetting(self.handle, key, properties) + + def contains(self, key): + return core.BNSettingsContains(self.handle, key) - def query_property_string_list(self, id, property_name): + def query_property_string_list(self, key, property_name): length = ctypes.c_ulonglong() - result = core.BNSettingsQueryPropertyStringList(self._registry_id, id, property_name, ctypes.byref(length)) + result = core.BNSettingsQueryPropertyStringList(self.handle, key, property_name, ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(pyNativeStr(result[i])) core.BNFreeStringList(result, length) return out_list - def update_property(self, id, setting_property): - return core.BNSettingsUpdateProperty(self.registry_id, id, setting_property) + def update_property(self, key, setting_property): + return core.BNSettingsUpdateProperty(self.handle, key, setting_property) def deserialize_schema(self, schema): - return core.BNSettingsDeserializeSchema(self.registry_id, schema) + return core.BNSettingsDeserializeSchema(self.handle, schema) def serialize_schema(self): - return core.BNSettingsSerializeSchema(self.registry_id) + return core.BNSettingsSerializeSchema(self.handle) - def copy_value(self, dest_registry_id, id): - return core.BNSettingsCopyValue(self._registry_id, dest_registry_id, id) + def copy_values_from(self, source, scope = SettingsScope.SettingsAutoScope): + return core.BNSettingsCopyValuesFrom(self.handle, source.handle, scope) - def reset(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def reset(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsReset(self._registry_id, id, view, scope) + return core.BNSettingsReset(self.handle, key, view, scope) def reset_all(self, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsResetAll(self._registry_id, view, scope) + return core.BNSettingsResetAll(self.handle, view, scope) - def get_bool(self, id, view = None): + def get_bool(self, key, view = None): if view is not None: view = view.handle - return core.BNSettingsGetBool(self._registry_id, id, view, None) + return core.BNSettingsGetBool(self.handle, key, view, None) - def get_double(self, id, view = None): + def get_double(self, key, view = None): if view is not None: view = view.handle - return core.BNSettingsGetDouble(self._registry_id, id, view, None) + return core.BNSettingsGetDouble(self.handle, key, view, None) - def get_integer(self, id, view = None): + def get_integer(self, key, view = None): if view is not None: view = view.handle - return core.BNSettingsGetUInt64(self._registry_id, id, view, None) + return core.BNSettingsGetUInt64(self.handle, key, view, None) - def get_string(self, id, view = None): + def get_string(self, key, view = None): if view is not None: view = view.handle - return core.BNSettingsGetString(self._registry_id, id, view, None) + return core.BNSettingsGetString(self.handle, key, view, None) - def get_string_list(self, id, view = None): + def get_string_list(self, key, view = None): if view is not None: view = view.handle length = ctypes.c_ulonglong() - result = core.BNSettingsGetStringList(self._registry_id, id, view, None, ctypes.byref(length)) + result = core.BNSettingsGetStringList(self.handle, key, view, None, ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(pyNativeStr(result[i])) core.BNFreeStringList(result, length) return out_list - def get_bool_with_scope(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def get_bool_with_scope(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) - result = core.BNSettingsGetBool(self._registry_id, id, view, ctypes.byref(c_scope)) + result = core.BNSettingsGetBool(self.handle, key, view, ctypes.byref(c_scope)) return (result, SettingsScope(c_scope.value)) - def get_double_with_scope(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def get_double_with_scope(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) - result = core.BNSettingsGetDouble(self._registry_id, id, view, ctypes.byref(c_scope)) + result = core.BNSettingsGetDouble(self.handle, key, view, ctypes.byref(c_scope)) return (result, SettingsScope(c_scope.value)) - def get_integer_with_scope(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def get_integer_with_scope(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) - result = core.BNSettingsGetUInt64(self._registry_id, id, view, ctypes.byref(c_scope)) + result = core.BNSettingsGetUInt64(self.handle, key, view, ctypes.byref(c_scope)) return (result, SettingsScope(c_scope.value)) - def get_string_with_scope(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def get_string_with_scope(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) - result = core.BNSettingsGetString(self._registry_id, id, view, ctypes.byref(c_scope)) + result = core.BNSettingsGetString(self.handle, key, view, ctypes.byref(c_scope)) return (result, SettingsScope(c_scope.value)) - def get_string_list_with_scope(self, id, view = None, scope = SettingsScope.SettingsAutoScope): + def get_string_list_with_scope(self, key, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) length = ctypes.c_ulonglong() - result = core.BNSettingsGetStringList(self._registry_id, id, view, ctypes.byref(c_scope), ctypes.byref(length)) + result = core.BNSettingsGetStringList(self.handle, key, view, ctypes.byref(c_scope), ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(pyNativeStr(result[i])) core.BNFreeStringList(result, length) return (out_list, SettingsScope(c_scope.value)) - def set_bool(self, id, value, view = None, scope = SettingsScope.SettingsAutoScope): + def set_bool(self, key, value, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsSetBool(self._registry_id, view, scope, id, value) + return core.BNSettingsSetBool(self.handle, view, scope, key, value) - def set_double(self, id, value, view = None, scope = SettingsScope.SettingsAutoScope): + def set_double(self, key, value, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsSetDouble(self._registry_id, view, scope, id, value) + return core.BNSettingsSetDouble(self.handle, view, scope, key, value) - def set_integer(self, id, value, view = None, scope = SettingsScope.SettingsAutoScope): + def set_integer(self, key, value, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsSetUInt64(self._registry_id, view, scope, id, value) + return core.BNSettingsSetUInt64(self.handle, view, scope, key, value) - def set_string(self, id, value, view = None, scope = SettingsScope.SettingsAutoScope): + def set_string(self, key, value, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle - return core.BNSettingsSetString(self._registry_id, view, scope, id, value) + return core.BNSettingsSetString(self.handle, view, scope, key, value) - def set_string_list(self, id, value, view = None, scope = SettingsScope.SettingsAutoScope): + def set_string_list(self, key, value, view = None, scope = SettingsScope.SettingsAutoScope): if view is not None: view = view.handle length = ctypes.c_ulonglong() @@ -201,4 +233,4 @@ class Settings(object): string_list = (ctypes.c_char_p * len(value))() for i in range(len(value)): string_list[i] = value[i].encode('charmap') - return core.BNSettingsSetStringList(self._registry_id, view, scope, id, string_list, length) + return core.BNSettingsSetStringList(self.handle, view, scope, key, string_list, length) diff --git a/settings.cpp b/settings.cpp index a4c1c29a..c779c10e 100644 --- a/settings.cpp +++ b/settings.cpp @@ -6,22 +6,50 @@ using namespace BinaryNinja; using namespace std; +Settings::Settings(BNSettings* settings) +{ + m_object = BNNewSettingsReference(settings); +} + + +Settings::Settings(const std::string& instanceId) : m_instanceId(instanceId) +{ + m_object = BNCreateSettings(m_instanceId.c_str()); +} + + +Ref<Settings> Settings::Instance(const std::string& instanceId) +{ + static Ref<Settings> defaultInstance = new Settings("default"); + if (!instanceId.size() || (instanceId == "default")) + return defaultInstance; + else + return new Settings(instanceId); +} + + bool Settings::RegisterGroup(const string& group, const string& title) { - return BNSettingsRegisterGroup(m_registry.c_str(), group.c_str(), title.c_str()); + return BNSettingsRegisterGroup(m_object, group.c_str(), title.c_str()); +} + + +bool Settings::RegisterSetting(const string& key, const string& properties) +{ + return BNSettingsRegisterSetting(m_object, key.c_str(), properties.c_str()); } -bool Settings::RegisterSetting(const string& id, const string& properties) +bool Settings::Contains(const string& key) { - return BNSettingsRegisterSetting(m_registry.c_str(), id.c_str(), properties.c_str()); + return BNSettingsContains(m_object, key.c_str()); } -template<> vector<string> Settings::QueryProperty<vector<string>>(const string& id, const string& property) +template<> vector<string> Settings::QueryProperty<vector<string>>(const string& key, const string& property) { size_t size = 0; - char** outBuffer = (char**)BNSettingsQueryPropertyStringList(m_registry.c_str(), id.c_str(), property.c_str(), &size); + char** outBuffer = (char**)BNSettingsQueryPropertyStringList(m_object, key.c_str(), property.c_str(), &size); vector<string> result; result.reserve(size); @@ -33,55 +61,55 @@ template<> vector<string> Settings::QueryProperty<vector<string>>(const string& } -bool Settings::UpdateProperty(const std::string& id, const std::string& property) +bool Settings::UpdateProperty(const std::string& key, const std::string& property) { - return BNSettingsUpdateProperty(m_registry.c_str(), id.c_str(), property.c_str()); + return BNSettingsUpdateProperty(m_object, key.c_str(), property.c_str()); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, bool value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, bool value) { - return BNSettingsUpdateBoolProperty(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateBoolProperty(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, double value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, double value) { - return BNSettingsUpdateDoubleProperty(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateDoubleProperty(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, int value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, int value) { - return BNSettingsUpdateInt64Property(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateInt64Property(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, int64_t value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, int64_t value) { - return BNSettingsUpdateInt64Property(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateInt64Property(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, uint64_t value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, uint64_t value) { - return BNSettingsUpdateUInt64Property(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateUInt64Property(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, const char* value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, const char* value) { - return BNSettingsUpdateStringProperty(m_registry.c_str(), id.c_str(), property.c_str(), value); + return BNSettingsUpdateStringProperty(m_object, key.c_str(), property.c_str(), value); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, const std::string& value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, const std::string& value) { - return BNSettingsUpdateStringProperty(m_registry.c_str(), id.c_str(), property.c_str(), value.c_str()); + return BNSettingsUpdateStringProperty(m_object, key.c_str(), property.c_str(), value.c_str()); } -bool Settings::UpdateProperty(const std::string& id, const std::string& property, const std::vector<std::string>& value) +bool Settings::UpdateProperty(const std::string& key, const std::string& property, const std::vector<std::string>& value) { char** buffer = new char*[value.size()]; if (!buffer) @@ -90,7 +118,7 @@ bool Settings::UpdateProperty(const std::string& id, const std::string& property for (size_t i = 0; i < value.size(); i++) buffer[i] = BNAllocString(value[i].c_str()); - bool result = BNSettingsUpdateStringListProperty(m_registry.c_str(), id.c_str(), property.c_str(), (const char**)buffer, value.size()); + bool result = BNSettingsUpdateStringListProperty(m_object, key.c_str(), property.c_str(), (const char**)buffer, value.size()); BNFreeStringList(buffer, value.size()); return result; } @@ -98,13 +126,13 @@ bool Settings::UpdateProperty(const std::string& id, const std::string& property bool Settings::DeserializeSchema(const string& schema) { - return BNSettingsDeserializeSchema(m_registry.c_str(), schema.c_str()); + return BNSettingsDeserializeSchema(m_object, schema.c_str()); } string Settings::SerializeSchema() { - char* schemaStr = BNSettingsSerializeSchema(m_registry.c_str()); + char* schemaStr = BNSettingsSerializeSchema(m_object); string schema(schemaStr); BNFreeString(schemaStr); return schema; @@ -113,74 +141,74 @@ string Settings::SerializeSchema() bool Settings::DeserializeSettings(const string& contents, Ref<BinaryView> view, BNSettingsScope scope) { - return BNDeserializeSettings(m_registry.c_str(), contents.c_str(), view ? view->GetObject() : nullptr, scope); + return BNDeserializeSettings(m_object, contents.c_str(), view ? view->GetObject() : nullptr, scope); } string Settings::SerializeSettings(Ref<BinaryView> view, BNSettingsScope scope) { - char* settingsStr = BNSerializeSettings(m_registry.c_str(), view ? view->GetObject() : nullptr, scope); + char* settingsStr = BNSerializeSettings(m_object, view ? view->GetObject() : nullptr, scope); string settings(settingsStr); BNFreeString(settingsStr); return settings; } -bool Settings::CopyValue(const string& destRegistry, const string& id) +bool Settings::CopyValuesFrom(Ref<Settings> source, BNSettingsScope scope) { - return BNSettingsCopyValue(m_registry.c_str(), destRegistry.c_str(), id.c_str()); + return BNSettingsCopyValuesFrom(m_object, source->GetObject(), scope); } -bool Settings::Reset(const string& id, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Reset(const string& key, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsReset(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsReset(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); } bool Settings::ResetAll(Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsResetAll(m_registry.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsResetAll(m_object, view ? view->GetObject() : nullptr, scope); } -template<> bool Settings::Get<bool>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> bool Settings::Get<bool>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { - return BNSettingsGetBool(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsGetBool(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); } -template<> double Settings::Get<double>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> double Settings::Get<double>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { - return BNSettingsGetDouble(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsGetDouble(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); } -template<> int64_t Settings::Get<int64_t>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> int64_t Settings::Get<int64_t>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { - return BNSettingsGetInt64(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsGetInt64(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); } -template<> uint64_t Settings::Get<uint64_t>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> uint64_t Settings::Get<uint64_t>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { - return BNSettingsGetUInt64(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + return BNSettingsGetUInt64(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); } -template<> string Settings::Get<string>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> string Settings::Get<string>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { - char* tmpStr = BNSettingsGetString(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope); + char* tmpStr = BNSettingsGetString(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope); string result(tmpStr); BNFreeString(tmpStr); return result; } -template<> vector<string> Settings::Get<vector<string>>(const string& id, Ref<BinaryView> view, BNSettingsScope* scope) +template<> vector<string> Settings::Get<vector<string>>(const string& key, Ref<BinaryView> view, BNSettingsScope* scope) { size_t size = 0; - char** outBuffer = (char**)BNSettingsGetStringList(m_registry.c_str(), id.c_str(), view ? view->GetObject() : nullptr, scope, &size); + char** outBuffer = (char**)BNSettingsGetStringList(m_object, key.c_str(), view ? view->GetObject() : nullptr, scope, &size); vector<string> result; result.reserve(size); @@ -192,49 +220,49 @@ template<> vector<string> Settings::Get<vector<string>>(const string& id, Ref<Bi } -bool Settings::Set(const string& id, bool value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, bool value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetBool(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetBool(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, double value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, double value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetDouble(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetDouble(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, int value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, int value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetInt64(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetInt64(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, int64_t value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, int64_t value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetInt64(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetInt64(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, uint64_t value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, uint64_t value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetUInt64(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetUInt64(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, const char* value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, const char* value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetString(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value); + return BNSettingsSetString(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value); } -bool Settings::Set(const string& id, const string& value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, const string& value, Ref<BinaryView> view, BNSettingsScope scope) { - return BNSettingsSetString(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), value.c_str()); + return BNSettingsSetString(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), value.c_str()); } -bool Settings::Set(const string& id, const vector<string>& value, Ref<BinaryView> view, BNSettingsScope scope) +bool Settings::Set(const string& key, const vector<string>& value, Ref<BinaryView> view, BNSettingsScope scope) { char** buffer = new char*[value.size()]; if (!buffer) @@ -243,7 +271,7 @@ bool Settings::Set(const string& id, const vector<string>& value, Ref<BinaryView for (size_t i = 0; i < value.size(); i++) buffer[i] = BNAllocString(value[i].c_str()); - bool result = BNSettingsSetStringList(m_registry.c_str(), view ? view->GetObject() : nullptr, scope, id.c_str(), (const char**)buffer, value.size()); + bool result = BNSettingsSetStringList(m_object, view ? view->GetObject() : nullptr, scope, key.c_str(), (const char**)buffer, value.size()); BNFreeStringList(buffer, value.size()); return result; } diff --git a/suite/api_test.py b/suite/api_test.py index a2968115..63a8bb39 100644 --- a/suite/api_test.py +++ b/suite/api_test.py @@ -1,7 +1,8 @@ import unittest import platform import os -from binaryninja.settings import Settings +from binaryninja.binaryview import BinaryView, BinaryViewType +from binaryninja.settings import Settings, SettingsScope from binaryninja.metadata import Metadata from binaryninja.demangle import demangle_gnu3, get_qualified_name from binaryninja.architecture import Architecture @@ -14,66 +15,130 @@ class SettingsAPI(unittest.TestCase): @classmethod def tearDownClass(cls): - setting = Settings() - # setting.remove_setting_group("test") + pass + + def test_settings_create(self): + s1 = Settings() + s2 = Settings(None) + s3 = Settings("default") + s4 = Settings("test") + assert s1 == s2, "test_settings_create failed" + assert s1 == s3, "test_settings_create failed" + assert s1 != s4, "test_settings_create failed" + + def test_settings_defaults(self): + settings = Settings() + assert settings.contains("analysis.linearSweep.autorun"), "test_settings_defaults failed" + assert settings.contains("analysis.unicode.blocks"), "test_settings_defaults failed" + assert settings.contains("downloadClient.providerName"), "test_settings_defaults failed" + assert settings.get_bool_with_scope("analysis.linearSweep.autorun", scope=SettingsScope.SettingsDefaultScope)[0], "test_settings_defaults failed" + assert settings.get_bool_with_scope("analysis.linearSweep.autorun", scope=SettingsScope.SettingsDefaultScope)[1] == SettingsScope.SettingsDefaultScope, "test_settings_defaults failed" + + def test_settings_registration(self): + settings = Settings("test") + assert not settings.contains("testGroup.testSetting"), "test_settings_registration failed" + assert settings.register_group("testGroup", "Title"), "test_settings_registration failed" + assert settings.register_setting("testGroup.testSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "testSetting"}'), "test_settings_registration failed" + assert settings.contains("testGroup.testSetting"), "test_settings_registration failed" + + def test_settings_usage(self): + settings = Settings("test") + assert not settings.contains("testGroup.testSetting"), "test_settings_types failed" + assert settings.register_group("testGroup", "Title"), "test_settings_types failed" + assert not settings.register_setting("testGroup.boolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "boolean", "id" : "boolSetting"}'), "test_settings_types failed" + assert settings.register_setting("testGroup.boolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "boolSetting"}'), "test_settings_types failed" + assert not settings.register_setting("testGroup.doubleSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "number", "id" : "doubleSetting"}'), "test_settings_types failed" + assert settings.register_setting("testGroup.doubleSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "number", "id" : "doubleSetting"}'), "test_settings_types failed" + assert settings.register_setting("testGroup.integerSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "number", "id" : "integerSetting"}'), "test_settings_types failed" + assert not settings.register_setting("testGroup.stringSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "string", "id" : "stringSetting"}'), "test_settings_types failed" + assert settings.register_setting("testGroup.stringSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : "value", "type" : "string", "id" : "stringSetting"}'), "test_settings_types failed" + assert not settings.register_setting("testGroup.stringListSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "array", "id" : "stringListSetting"}'), "test_settings_types failed" + assert settings.register_setting("testGroup.stringListSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : ["value1", "value2"], "type" : "array", "id" : "stringListSetting"}'), "test_settings_types failed" + + assert settings.contains("testGroup.boolSetting"), "test_settings_types failed" + assert settings.contains("testGroup.doubleSetting"), "test_settings_types failed" + assert settings.contains("testGroup.integerSetting"), "test_settings_types failed" + assert settings.contains("testGroup.stringSetting"), "test_settings_types failed" + assert settings.contains("testGroup.stringListSetting"), "test_settings_types failed" + + assert settings.get_bool("testGroup.boolSetting") == True, "test_settings_types failed" + assert settings.get_double("testGroup.doubleSetting") == 500, "test_settings_types failed" + assert settings.get_integer("testGroup.integerSetting") == 500, "test_settings_types failed" + assert settings.get_string("testGroup.stringSetting") == "value", "test_settings_types failed" + assert settings.get_string_list("testGroup.stringListSetting") == ["value1", "value2"], "test_settings_types failed" + + assert settings.set_bool("testGroup.boolSetting", False), "test_settings_types failed" + assert settings.set_double("testGroup.doubleSetting", 700), "test_settings_types failed" + assert settings.set_integer("testGroup.integerSetting", 700), "test_settings_types failed" + assert settings.set_string("testGroup.stringSetting", "value_user"), "test_settings_types failed" + assert settings.set_string_list("testGroup.stringListSetting", ["value3", "value4"]), "test_settings_types failed" + + assert settings.get_bool("testGroup.boolSetting") == False, "test_settings_types failed" + assert settings.get_double("testGroup.doubleSetting") == 700, "test_settings_types failed" + assert settings.get_integer("testGroup.integerSetting") == 700, "test_settings_types failed" + assert settings.get_string("testGroup.stringSetting") == "value_user", "test_settings_types failed" + assert settings.get_string_list("testGroup.stringListSetting") == ["value3", "value4"], "test_settings_types failed" - def test_bool_settings(self): - setting = Settings() - # setting.set("bool_test_true", True) - # setting.set("bool_test_false", False) - # assert not setting.get_bool("bool_test_false"), "bool_test_false failed" - # assert setting.get_bool("bool_test_true"), "bool_test_true failed" - # assert setting.get_bool("bool_test_default_True", True), "bool_test_default_True failed" - # assert not setting.get_bool("bool_test_default_False", False), "bool_test_default_False failed" + assert settings.get_bool_with_scope("testGroup.boolSetting", scope=SettingsScope.SettingsDefaultScope)[0] == True, "test_settings_types failed" + assert settings.get_double_with_scope("testGroup.doubleSetting", scope=SettingsScope.SettingsDefaultScope)[0] == 500, "test_settings_types failed" + assert settings.get_integer_with_scope("testGroup.integerSetting", scope=SettingsScope.SettingsDefaultScope)[0] == 500, "test_settings_types failed" + assert settings.get_string_with_scope("testGroup.stringSetting", scope=SettingsScope.SettingsDefaultScope)[0] == "value", "test_settings_types failed" + assert settings.get_string_list_with_scope("testGroup.stringListSetting", scope=SettingsScope.SettingsDefaultScope)[0] == ["value1", "value2"], "test_settings_types failed" - def test_int_settings(self): - setting = Settings() - # setting.set("int_test1", 0x100) - # setting.set("int_test2", 0) - # setting.set("int_test3", -1) - # assert setting.get_integer("int_test1") == 0x100, "int_test1 failed" - # assert setting.get_integer("int_test2") == 0, "int_test2 failed" - # assert setting.get_integer("int_test3") == -1, "int_test3 failed" - # assert setting.get_integer("int_test_default_1", 1) == 1, "int_test_default_1 failed" + assert settings.get_bool_with_scope("testGroup.boolSetting", scope=SettingsScope.SettingsUserScope)[0] == False, "test_settings_types failed" + assert settings.get_double_with_scope("testGroup.doubleSetting", scope=SettingsScope.SettingsUserScope)[0] == 700, "test_settings_types failed" + assert settings.get_integer_with_scope("testGroup.integerSetting", scope=SettingsScope.SettingsUserScope)[0] == 700, "test_settings_types failed" + assert settings.get_string_with_scope("testGroup.stringSetting", scope=SettingsScope.SettingsUserScope)[0] == "value_user", "test_settings_types failed" + assert settings.get_string_list_with_scope("testGroup.stringListSetting", scope=SettingsScope.SettingsUserScope)[0] == ["value3", "value4"], "test_settings_types failed" - def test_float_settings(self): - setting = Settings() - # setting.set("float_test1", 10.5) - # setting.set("float_test2", -0.5) - # assert setting.get_double("float_test1") == 10.5, "float_test1 failed" - # assert setting.get_double("float_test2") == -0.5, "float_test1 failed" - # assert setting.get_double("float_test_default", -5.5), "float_test_default failed" + s2 = Settings("test2") + assert s2.serialize_schema() is "", "test_settings_types failed" + test_schema = settings.serialize_schema() + assert test_schema != "", "test_settings_types failed" + assert s2.deserialize_schema(test_schema), "test_settings_types failed" - def test_str_settings(self): - setting = Settings() - # setting.set("str_test1", "hi") - # setting.set("str_test2", "") - # setting.set("str_test3", "A" * 1000) - # assert setting.get_string("str_test1") == "hi", "str_test1 failed" - # assert setting.get_string("str_test2") == "", "str_test2 failed" - # assert setting.get_string("str_test3") == "A" * 1000, "str_test3 failed" - # assert setting.get_string("str_test_default", "hi") == "hi", "str_test_default failed" + assert s2.get_bool("testGroup.boolSetting") == True, "test_settings_types failed" + assert s2.get_double("testGroup.doubleSetting") == 500, "test_settings_types failed" + assert s2.get_integer("testGroup.integerSetting") == 500, "test_settings_types failed" + assert s2.get_string("testGroup.stringSetting") == "value", "test_settings_types failed" + assert s2.get_string_list("testGroup.stringListSetting") == ["value1", "value2"], "test_settings_types failed" - def test_int_list_settings(self): - setting = Settings() - # setting.set("int_list_test1", [0x100]) - # setting.set("int_list_test2", [1, 2]) - # setting.set("int_list_test3", []) - # assert setting.get_integer_list("int_list_test1") == [0x100], "int_list_test1 failed" - # assert setting.get_integer_list("int_list_test2") == [1, 2], "int_list_test2 failed" - # assert setting.get_integer_list("int_list_test3") == [], "int_list_test3 failed" - # assert setting.get_integer_list("int_list_test_default", [2, 3]), "int_list_test_default failed" + assert s2.copy_values_from(settings), "test_settings_types failed" + assert s2.get_bool("testGroup.boolSetting") == False, "test_settings_types failed" + assert s2.get_double("testGroup.doubleSetting") == 700, "test_settings_types failed" + assert s2.get_integer("testGroup.integerSetting") == 700, "test_settings_types failed" + assert s2.get_string("testGroup.stringSetting") == "value_user", "test_settings_types failed" + assert s2.get_string_list("testGroup.stringListSetting") == ["value3", "value4"], "test_settings_types failed" - def test_str_list_settings(self): - setting = Settings() - # setting.set("str_list_test1", ["hi"]) - # setting.set("str_list_test2", ["hello", "world"]) - # setting.set("str_list_test3", []) - # assert setting.get_string_list("str_list_test1") == ["hi"], "str_list_test1 failed" - # assert setting.get_string_list("str_list_test2") == ["hello", "world"], "str_list_test2 failed" - # assert setting.get_string_list("str_list_test3") == [], "str_list_test3 failed" - # assert setting.get_string_list("str_list_test_default", ["hi", "there"]), "str_list_test_default failed" + assert s2.reset_all(), "test_settings_types failed" + assert s2.get_bool("testGroup.boolSetting") == True, "test_settings_types failed" + assert s2.get_double("testGroup.doubleSetting") == 500, "test_settings_types failed" + assert s2.get_integer("testGroup.integerSetting") == 500, "test_settings_types failed" + assert s2.get_string("testGroup.stringSetting") == "value", "test_settings_types failed" + assert s2.get_string_list("testGroup.stringListSetting") == ["value1", "value2"], "test_settings_types failed" + def test_load_settings(self): + bvt_name = "Mapped (Python)" if "Mapped (Python)" in map(lambda bvt: bvt.name, list(BinaryViewType)) else "Mapped" + raw_view = BinaryView.new(b'0x55') + assert raw_view.view_type == "Raw", "test_load_settings failed" + mapped_view = BinaryViewType[bvt_name].create(raw_view) + assert mapped_view.view_type == bvt_name, "test_load_settings failed" + assert mapped_view.segments[0].start == 0, "test_load_settings failed" + assert len(mapped_view) == 4, "test_load_settings failed" + load_settings = BinaryViewType[bvt_name].get_load_settings_for_data(raw_view) + assert load_settings is not None, "test_load_settings failed" + assert load_settings.contains("abstractLoader.architecture"), "test_load_settings failed" + assert load_settings.contains("abstractLoader.platform"), "test_load_settings failed" + assert load_settings.contains("abstractLoader.imageBase"), "test_load_settings failed" + assert load_settings.contains("abstractLoader.entryPoint"), "test_load_settings failed" + load_settings.set_string("abstractLoader.architecture", 'x86_64') + load_settings.set_integer("abstractLoader.imageBase", 0x500000) + load_settings.set_integer("abstractLoader.entryPoint", 0x500000) + raw_view.set_load_settings(bvt_name, load_settings) + mapped_view = BinaryViewType[bvt_name].create(raw_view) + assert mapped_view.view_type == bvt_name, "test_load_settings failed" + assert mapped_view.segments[0].start == 0x500000, "test_load_settings failed" + assert len(mapped_view) == 4, "test_load_settings failed" class MetaddataAPI(unittest.TestCase): def test_metadata_basic_types(self): diff --git a/ui/disassemblyview.h b/ui/disassemblyview.h index dd70436c..99b88a2f 100644 --- a/ui/disassemblyview.h +++ b/ui/disassemblyview.h @@ -89,6 +89,7 @@ private: BNFunctionGraphType m_graphType; std::set<BNDisassemblyOption> m_options; DisassemblyContainer* m_container; + SettingsRef m_settings; private Q_SLOTS: void viewInHexEditor(); diff --git a/ui/uitypes.h b/ui/uitypes.h index 9859cdb2..b9917321 100644 --- a/ui/uitypes.h +++ b/ui/uitypes.h @@ -53,6 +53,7 @@ typedef BinaryNinja::Ref<BinaryNinja::ScriptingInstance> ScriptingInstanceRef; typedef BinaryNinja::Ref<BinaryNinja::ScriptingProvider> ScriptingProviderRef; typedef BinaryNinja::Ref<BinaryNinja::Section> SectionRef; typedef BinaryNinja::Ref<BinaryNinja::Segment> SegmentRef; +typedef BinaryNinja::Ref<BinaryNinja::Settings> SettingsRef; typedef BinaryNinja::Ref<BinaryNinja::Structure> StructureRef; typedef BinaryNinja::Ref<BinaryNinja::Symbol> SymbolRef; typedef BinaryNinja::Ref<BinaryNinja::Tag> TagRef; |
