From 0de62768c8afc5ca27576b59d4591ca8dbbd7cee Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Sat, 24 Jun 2017 01:33:04 -0400 Subject: Adding settings system apis, and binaryview metadata apis --- metadata.cpp | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 metadata.cpp (limited to 'metadata.cpp') diff --git a/metadata.cpp b/metadata.cpp new file mode 100644 index 00000000..2f398940 --- /dev/null +++ b/metadata.cpp @@ -0,0 +1,238 @@ +#include "binaryninjaapi.h" + +using namespace std; +using namespace BinaryNinja; + +Metadata::Metadata(BNMetadata* structuredData) +{ + m_object = structuredData; +} + +Metadata::Metadata(bool data) +{ + m_object = BNCreateStructuredBooleanData(data); +} + +Metadata::Metadata(const string& data) +{ + m_object = BNCreateStructuredStringData(data.c_str()); +} + +Metadata::Metadata(uint64_t data) +{ + m_object = BNCreateStructuredUnsignedIntegerData(data); +} + +Metadata::Metadata(int64_t data) +{ + m_object = BNCreateStructuredSignedIntegerData(data); +} + +Metadata::Metadata(double data) +{ + m_object = BNCreateStructuredDoubleData(data); +} + +Metadata::Metadata(const vector& data) +{ + auto input = new bool[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = data[i]; + + m_object = BNCreateStructuredBooleanListData(input, data.size()); + delete[] input; +} + +Metadata::Metadata(const vector& data) +{ + char** input = new char*[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = BNAllocString(data[i].c_str()); + + m_object = BNCreateStructuredStringListData((const char**)input, data.size()); + + for (size_t i = 0; i < data.size(); i++) + BNFreeString(input[i]); + delete[] input; +} + +Metadata::Metadata(const vector& data) +{ + auto input = new uint64_t[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = data[i]; + + m_object = BNCreateStructuredUnsignedIntegerListData(input, data.size()); + delete[] input; +} + +Metadata::Metadata(const vector& data) +{ + auto input = new int64_t[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = data[i]; + + m_object = BNCreateStructuredSignedIntegerListData(input, data.size()); + delete[] input; +} + +Metadata::Metadata(const vector& data) +{ + auto input = new double[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = data[i]; + + m_object = BNCreateStructuredDoubleListData(input, data.size()); + delete[] input; +} + +Metadata::Metadata(const vector& data) +{ + auto input = new uint8_t[data.size()]; + for (size_t i = 0; i < data.size(); i++) + input[i] = data[i]; + + m_object = BNCreateStructuredRawData(input, data.size()); + delete[] input; +} + +MetadataType Metadata::GetType() const +{ + return BNMetadataGetType(m_object); +} + +bool Metadata::GetBoolean() const +{ + return BNMetadataGetBoolean(m_object); +} + +string Metadata::GetString() const +{ + return BNMetadataGetString(m_object); +} + +uint64_t Metadata::GetUnsignedInteger() const +{ + return BNMetadataGetUnsignedInteger(m_object); +} + +int64_t Metadata::GetSignedInteger() const +{ + return BNMetadataGetSignedInteger(m_object); +} + +double Metadata::GetDouble() const +{ + return BNMetadataGetDouble(m_object); +} + +vector Metadata::GetBooleanList() const +{ + size_t outSize; + bool* outList = BNMetadataGetBooleanList(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataBooleanList(outList); + return result; +} + +vector Metadata::GetStringList() const +{ + size_t outSize; + char** outList = BNMetadataGetStringList(m_object, &outSize); + vector result; + for (size_t i = 0; i < outSize; i++) + result.push_back(string(outList[i])); + BNFreeMetadataStringList(outList, outSize); + return result; +} + +vector Metadata::GetUnsignedIntegerList() const +{ + size_t outSize; + uint64_t* outList = BNMetadataGetUnsignedIntegerList(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataUnsignedIntegerList(outList); + return result; +} + +vector Metadata::GetSignedIntegerList() const +{ + size_t outSize; + int64_t* outList = BNMetadataGetSignedIntegerList(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataSignedIntegerList(outList); + return result; +} + +vector Metadata::GetDoubleList() const +{ + size_t outSize; + double* outList = BNMetadataGetDoubleList(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataDoubleList(outList); + return result; +} + +vector Metadata::GetRaw() const +{ + size_t outSize; + uint8_t* outList = BNMetadataGetRaw(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataRaw(outList); + return result; +} + +bool Metadata::IsBoolean() const +{ + return BNMetadataIsBoolean(m_object); +} + +bool Metadata::IsString() const +{ + return BNMetadataIsString(m_object); +} + +bool Metadata::IsUnsignedInteger() const +{ + return BNMetadataIsUnsignedInteger(m_object); +} + +bool Metadata::IsSignedInteger() const +{ + return BNMetadataIsSignedInteger(m_object); +} + +bool Metadata::IsDouble() const +{ + return BNMetadataIsDouble(m_object); +} + +bool Metadata::IsBooleanList() const +{ + return BNMetadataIsBooleanList(m_object); +} + +bool Metadata::IsStringList() const +{ + return BNMetadataIsStringList(m_object); +} + +bool Metadata::IsUnsignedIntegerList() const +{ + return BNMetadataIsUnsignedIntegerList(m_object); +} + +bool Metadata::IsSignedIntegerList() const +{ + return BNMetadataIsSignedIntegerList(m_object); +} + +bool Metadata::IsDoubleList() const +{ + return BNMetadataIsDoubleList(m_object); +} + +bool Metadata::IsRaw() const +{ + return BNMetadataIsRaw(m_object); +} -- cgit v1.3.1 From c407679358f035aa9e16e3bb740f8e6d9a73d138 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Sat, 1 Jul 2017 10:02:12 -0400 Subject: Refactor of metadata api names. modify how QueryMetadata works --- binaryninjaapi.h | 2 +- binaryninjacore.h | 24 ++++++++++++------------ binaryview.cpp | 42 ++++++++++++++++-------------------------- metadata.cpp | 26 +++++++++++++------------- settings.cpp | 1 + 5 files changed, 43 insertions(+), 52 deletions(-) (limited to 'metadata.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 426095b0..13ca3446 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1128,7 +1128,7 @@ namespace BinaryNinja std::vector GetAllocatedRanges(); void StoreMetadata(const std::string& key, Metadata* inValue); - bool QueryMetadata(const std::string& key, Metadata** outValue); + std::unique_ptr QueryMetadata(const std::string& key); std::string GetStringMetadata(const std::string& key); std::vector GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); diff --git a/binaryninjacore.h b/binaryninjacore.h index 25aa150d..0394517f 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2917,17 +2917,17 @@ extern "C" // Create Metadata of various types BINARYNINJACOREAPI BNMetadata* BNNewMetadataReference(BNMetadata* data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredBooleanData(bool data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredStringData(const char* data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredUnsignedIntegerData(uint64_t data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredSignedIntegerData(int64_t data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredDoubleData(double data); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredBooleanListData(const bool* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredStringListData(const char** data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredUnsignedIntegerListData(const uint64_t* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredSignedIntegerListData(const int64_t* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredDoubleListData(const double* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateStructuredRawData(const uint8_t* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataBooleanData(bool data); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataStringData(const char* data); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataUnsignedIntegerData(uint64_t data); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataSignedIntegerData(int64_t data); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataDoubleData(double data); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataBooleanListData(const bool* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataStringListData(const char** data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataUnsignedIntegerListData(const uint64_t* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataSignedIntegerListData(const int64_t* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataDoubleListData(const double* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataRawData(const uint8_t* data, size_t size); BINARYNINJACOREAPI void BNFreeMetadata(BNMetadata* data); BINARYNINJACOREAPI void BNFreeMetadataBooleanList(bool* data); BINARYNINJACOREAPI void BNFreeMetadataStringList(char** data, size_t size); @@ -2963,7 +2963,7 @@ extern "C" // Store/Query structured data to/from a BinaryView BINARYNINJACOREAPI void BNBinaryViewStoreMetadata(BNBinaryView* view, const char* key, BNMetadata* value); - BINARYNINJACOREAPI bool BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key, BNMetadata** value); + BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key); #ifdef __cplusplus } #endif diff --git a/binaryview.cpp b/binaryview.cpp index 6eb299a3..b330508d 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "binaryninjaapi.h" using namespace BinaryNinja; @@ -1833,48 +1834,37 @@ void BinaryView::StoreMetadata(const std::string& key, Metadata* inValue) BNBinaryViewStoreMetadata(m_object, key.c_str(), inValue->GetObject()); } - -bool BinaryView::QueryMetadata(const std::string& key, Metadata** outValue) +unique_ptr BinaryView::QueryMetadata(const std::string& key) { - BNMetadata* value = nullptr; - bool status = BNBinaryViewQueryMetadata(m_object, key.c_str(), &value); - if (!status) - { - *outValue = nullptr; - return false; - } - *outValue = new Metadata(value); - return true; + BNMetadata* value = BNBinaryViewQueryMetadata(m_object, key.c_str()); + if (!value) + return nullptr; + auto a = new Metadata(value); + return unique_ptr(a); } string BinaryView::GetStringMetadata(const string& key) { - Metadata* data; - if (!QueryMetadata(key, &data) || !data || data->IsString()) + auto data = QueryMetadata(key); + if (!data || !data->IsString()) throw QueryMetadataException("Failed to find key: " + key); - auto result = data->GetString(); - delete data; - return result; + return data->GetString(); } vector BinaryView::GetRawMetadata(const string& key) { - Metadata* data; - if (!QueryMetadata(key, &data) || !data || data->IsRaw()) + auto data = QueryMetadata(key); + if (!data || !data->IsRaw()) throw QueryMetadataException("Failed to find key: " + key); - auto result = data->GetRaw(); - delete data; - return result; + return data->GetRaw(); } uint64_t BinaryView::GetUIntMetadata(const string& key) { - Metadata* data; - if (!QueryMetadata(key, &data) || !data || data->IsUnsignedInteger()) + auto data = QueryMetadata(key); + if (!data || !data->IsUnsignedInteger()) throw QueryMetadataException("Failed to find key: " + key); - auto result = data->GetUnsignedInteger(); - delete data; - return result; + return data->GetUnsignedInteger(); } BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetObject())) diff --git a/metadata.cpp b/metadata.cpp index 2f398940..3f01f4bb 100644 --- a/metadata.cpp +++ b/metadata.cpp @@ -3,34 +3,34 @@ using namespace std; using namespace BinaryNinja; -Metadata::Metadata(BNMetadata* structuredData) +Metadata::Metadata(BNMetadata* metadata) { - m_object = structuredData; + m_object = metadata; } Metadata::Metadata(bool data) { - m_object = BNCreateStructuredBooleanData(data); + m_object = BNCreateMetadataBooleanData(data); } Metadata::Metadata(const string& data) { - m_object = BNCreateStructuredStringData(data.c_str()); + m_object = BNCreateMetadataStringData(data.c_str()); } Metadata::Metadata(uint64_t data) { - m_object = BNCreateStructuredUnsignedIntegerData(data); + m_object = BNCreateMetadataUnsignedIntegerData(data); } Metadata::Metadata(int64_t data) { - m_object = BNCreateStructuredSignedIntegerData(data); + m_object = BNCreateMetadataSignedIntegerData(data); } Metadata::Metadata(double data) { - m_object = BNCreateStructuredDoubleData(data); + m_object = BNCreateMetadataDoubleData(data); } Metadata::Metadata(const vector& data) @@ -39,7 +39,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = data[i]; - m_object = BNCreateStructuredBooleanListData(input, data.size()); + m_object = BNCreateMetadataBooleanListData(input, data.size()); delete[] input; } @@ -49,7 +49,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = BNAllocString(data[i].c_str()); - m_object = BNCreateStructuredStringListData((const char**)input, data.size()); + m_object = BNCreateMetadataStringListData((const char**)input, data.size()); for (size_t i = 0; i < data.size(); i++) BNFreeString(input[i]); @@ -62,7 +62,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = data[i]; - m_object = BNCreateStructuredUnsignedIntegerListData(input, data.size()); + m_object = BNCreateMetadataUnsignedIntegerListData(input, data.size()); delete[] input; } @@ -72,7 +72,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = data[i]; - m_object = BNCreateStructuredSignedIntegerListData(input, data.size()); + m_object = BNCreateMetadataSignedIntegerListData(input, data.size()); delete[] input; } @@ -82,7 +82,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = data[i]; - m_object = BNCreateStructuredDoubleListData(input, data.size()); + m_object = BNCreateMetadataDoubleListData(input, data.size()); delete[] input; } @@ -92,7 +92,7 @@ Metadata::Metadata(const vector& data) for (size_t i = 0; i < data.size(); i++) input[i] = data[i]; - m_object = BNCreateStructuredRawData(input, data.size()); + m_object = BNCreateMetadataRawData(input, data.size()); delete[] input; } diff --git a/settings.cpp b/settings.cpp index 97c2a232..b7e08793 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,4 +1,5 @@ #include "binaryninjaapi.h" +#include using namespace BinaryNinja; using namespace std; -- cgit v1.3.1 From 3d3b803d18f0d61b5e36367c9eb660b234cdc66e Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Wed, 12 Jul 2017 16:04:28 -0400 Subject: Metadata enhancements. Metadata objects are now serialized to the DB --- binaryninjaapi.h | 27 +++++- binaryninjacore.h | 56 ++++++------ binaryview.cpp | 7 +- metadata.cpp | 158 +++++++++++++------------------- python/__init__.py | 1 + python/binaryview.py | 67 +++++++++++++- python/metadata.py | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 435 insertions(+), 129 deletions(-) create mode 100644 python/metadata.py (limited to 'metadata.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f5850ad0..83f6b582 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -876,7 +876,7 @@ namespace BinaryNinja \param dest the address to write len number of bytes. \param offset the virtual offset to find and read len bytes from - ....\param len the number of bytes to read from offset and write to dest + \param len the number of bytes to read from offset and write to dest */ virtual size_t PerformRead(void* dest, uint64_t offset, size_t len) { (void)dest; (void)offset; (void)len; return 0; } virtual size_t PerformWrite(uint64_t offset, const void* data, size_t len) { (void)offset; (void)data; (void)len; return 0; } @@ -1128,8 +1128,8 @@ namespace BinaryNinja std::vector GetAllocatedRanges(); - void StoreMetadata(const std::string& key, Metadata* inValue); - std::unique_ptr QueryMetadata(const std::string& key); + void StoreMetadata(const std::string& key, Ref value); + Ref QueryMetadata(const std::string& key); std::string GetStringMetadata(const std::string& key); std::vector GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); @@ -2929,8 +2929,15 @@ namespace BinaryNinja Metadata(const std::vector& data); Metadata(const std::vector& data); Metadata(const std::vector& data); + Metadata(const std::vector>& data); + Metadata(const std::map>& data); + Metadata(MetadataType type); virtual ~Metadata() {} + bool operator==(const Metadata& rhs); + Ref operator[](const std::string& key); + Ref operator[](size_t idx); + MetadataType GetType() const; bool GetBoolean() const; std::string GetString() const; @@ -2943,6 +2950,18 @@ namespace BinaryNinja std::vector GetSignedIntegerList() const; std::vector GetDoubleList() const; std::vector GetRaw() const; + std::vector> GetArray(); + std::map> GetKeyValueStore(); + + //For key-value data only + Ref Get(const std::string& key); + bool SetValueForKey(const std::string& key, Ref data); + + //For array data only + Ref Get(size_t idx); + bool Append(Ref data); + + size_t Size() const; bool IsBoolean() const; bool IsString() const; @@ -2955,5 +2974,7 @@ namespace BinaryNinja bool IsSignedIntegerList() const; bool IsDoubleList() const; bool IsRaw() const; + bool IsArray() const; + bool IsKeyValueStore() const; }; } diff --git a/binaryninjacore.h b/binaryninjacore.h index eb9927ab..54691360 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1299,6 +1299,13 @@ extern "C" bool pointer, intermediate; }; + struct BNMetadataValueStore + { + size_t size; + char** keys; + BNMetadata** values; + }; + enum BNHighlightColorStyle { StandardHighlightColor = 0, @@ -1478,17 +1485,15 @@ extern "C" enum BNMetadataType { + InvalidDataType, BooleanDataType, StringDataType, UnsignedIntegerDataType, SignedIntegerDataType, DoubleDataType, - BooleanListDataType, - StringListDataType, - UnsignedIntegerListDataType, - SignedIntegerListDataType, - DoubleListDataType, - RawDataType + RawDataType, + KeyValueDataType, + ArrayDataType }; BINARYNINJACOREAPI char* BNAllocString(const char* contents); @@ -2924,18 +2929,22 @@ extern "C" BINARYNINJACOREAPI BNMetadata* BNCreateMetadataUnsignedIntegerData(uint64_t data); BINARYNINJACOREAPI BNMetadata* BNCreateMetadataSignedIntegerData(int64_t data); BINARYNINJACOREAPI BNMetadata* BNCreateMetadataDoubleData(double data); - BINARYNINJACOREAPI BNMetadata* BNCreateMetadataBooleanListData(const bool* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateMetadataStringListData(const char** data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateMetadataUnsignedIntegerListData(const uint64_t* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateMetadataSignedIntegerListData(const int64_t* data, size_t size); - BINARYNINJACOREAPI BNMetadata* BNCreateMetadataDoubleListData(const double* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataOfType(BNMetadataType type); BINARYNINJACOREAPI BNMetadata* BNCreateMetadataRawData(const uint8_t* data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataArray(BNMetadata** data, size_t size); + BINARYNINJACOREAPI BNMetadata* BNCreateMetadataValueStore(const char** keys, BNMetadata** values, size_t size); + + BINARYNINJACOREAPI bool BNMetadataIsEqual(BNMetadata* lhs, BNMetadata* rhs); + + BINARYNINJACOREAPI bool BNMetadataSetValueForKey(BNMetadata* data, const char* key, BNMetadata* md); + BINARYNINJACOREAPI BNMetadata* BNMetadataGetForKey(BNMetadata* data, const char* key); + BINARYNINJACOREAPI bool BNMetadataArrayAppend(BNMetadata* data, BNMetadata* md); + BINARYNINJACOREAPI size_t BNMetadataSize(BNMetadata* data); + BINARYNINJACOREAPI BNMetadata* BNMetadataGetForIdx(BNMetadata* data, size_t idx); + + BINARYNINJACOREAPI void BNFreeMetadataArray(BNMetadata** data); + BINARYNINJACOREAPI void BNFreeMetadataValueStore(BNMetadataValueStore* data); BINARYNINJACOREAPI void BNFreeMetadata(BNMetadata* data); - BINARYNINJACOREAPI void BNFreeMetadataBooleanList(bool* data); - BINARYNINJACOREAPI void BNFreeMetadataStringList(char** data, size_t size); - BINARYNINJACOREAPI void BNFreeMetadataUnsignedIntegerList(uint64_t* data); - BINARYNINJACOREAPI void BNFreeMetadataSignedIntegerList(int64_t* data); - BINARYNINJACOREAPI void BNFreeMetadataDoubleList(double* data); BINARYNINJACOREAPI void BNFreeMetadataRaw(uint8_t* data); // Retrieve Structured Data BINARYNINJACOREAPI bool BNMetadataGetBoolean(BNMetadata* data); @@ -2943,12 +2952,10 @@ extern "C" BINARYNINJACOREAPI uint64_t BNMetadataGetUnsignedInteger(BNMetadata* data); BINARYNINJACOREAPI int64_t BNMetadataGetSignedInteger(BNMetadata* data); BINARYNINJACOREAPI double BNMetadataGetDouble(BNMetadata* data); - BINARYNINJACOREAPI bool* BNMetadataGetBooleanList(BNMetadata* data, size_t* size); - BINARYNINJACOREAPI char** BNMetadataGetStringList(BNMetadata* data, size_t* size); - BINARYNINJACOREAPI uint64_t* BNMetadataGetUnsignedIntegerList(BNMetadata* data, size_t* size); - BINARYNINJACOREAPI int64_t* BNMetadataGetSignedIntegerList(BNMetadata* data, size_t* size); - BINARYNINJACOREAPI double* BNMetadataGetDoubleList(BNMetadata* data, size_t* size); BINARYNINJACOREAPI uint8_t* BNMetadataGetRaw(BNMetadata* data, size_t* size); + BINARYNINJACOREAPI BNMetadata** BNMetadataGetArray(BNMetadata* data, size_t* size); + BINARYNINJACOREAPI BNMetadataValueStore* BNMetadataGetValueStore(BNMetadata* data); + //Query type of Metadata BINARYNINJACOREAPI BNMetadataType BNMetadataGetType(BNMetadata* data); BINARYNINJACOREAPI bool BNMetadataIsBoolean(BNMetadata* data); @@ -2956,12 +2963,9 @@ extern "C" BINARYNINJACOREAPI bool BNMetadataIsUnsignedInteger(BNMetadata* data); BINARYNINJACOREAPI bool BNMetadataIsSignedInteger(BNMetadata* data); BINARYNINJACOREAPI bool BNMetadataIsDouble(BNMetadata* data); - BINARYNINJACOREAPI bool BNMetadataIsBooleanList(BNMetadata* data); - BINARYNINJACOREAPI bool BNMetadataIsStringList(BNMetadata* data); - BINARYNINJACOREAPI bool BNMetadataIsUnsignedIntegerList(BNMetadata* data); - BINARYNINJACOREAPI bool BNMetadataIsSignedIntegerList(BNMetadata* data); - BINARYNINJACOREAPI bool BNMetadataIsDoubleList(BNMetadata* data); BINARYNINJACOREAPI bool BNMetadataIsRaw(BNMetadata* data); + BINARYNINJACOREAPI bool BNMetadataIsArray(BNMetadata* data); + BINARYNINJACOREAPI bool BNMetadataIsKeyValueStore(BNMetadata* data); // Store/Query structured data to/from a BinaryView BINARYNINJACOREAPI void BNBinaryViewStoreMetadata(BNBinaryView* view, const char* key, BNMetadata* value); diff --git a/binaryview.cpp b/binaryview.cpp index b330508d..3f1196d0 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1827,20 +1827,19 @@ vector BinaryView::GetAllocatedRanges() } -void BinaryView::StoreMetadata(const std::string& key, Metadata* inValue) +void BinaryView::StoreMetadata(const std::string& key, Ref inValue) { if (!inValue) return; BNBinaryViewStoreMetadata(m_object, key.c_str(), inValue->GetObject()); } -unique_ptr BinaryView::QueryMetadata(const std::string& key) +Ref BinaryView::QueryMetadata(const std::string& key) { BNMetadata* value = BNBinaryViewQueryMetadata(m_object, key.c_str()); if (!value) return nullptr; - auto a = new Metadata(value); - return unique_ptr(a); + return new Metadata(value); } string BinaryView::GetStringMetadata(const string& key) diff --git a/metadata.cpp b/metadata.cpp index 3f01f4bb..18d3500b 100644 --- a/metadata.cpp +++ b/metadata.cpp @@ -33,67 +33,66 @@ Metadata::Metadata(double data) m_object = BNCreateMetadataDoubleData(data); } -Metadata::Metadata(const vector& data) +Metadata::Metadata(MetadataType type) { - auto input = new bool[data.size()]; - for (size_t i = 0; i < data.size(); i++) - input[i] = data[i]; - - m_object = BNCreateMetadataBooleanListData(input, data.size()); - delete[] input; + m_object = BNCreateMetadataOfType(type); } -Metadata::Metadata(const vector& data) +Metadata::Metadata(const vector& data) { - char** input = new char*[data.size()]; + auto input = new uint8_t[data.size()]; for (size_t i = 0; i < data.size(); i++) - input[i] = BNAllocString(data[i].c_str()); - - m_object = BNCreateMetadataStringListData((const char**)input, data.size()); + input[i] = data[i]; - for (size_t i = 0; i < data.size(); i++) - BNFreeString(input[i]); + m_object = BNCreateMetadataRawData(input, data.size()); delete[] input; } -Metadata::Metadata(const vector& data) +Metadata::Metadata(const std::vector>& data) { - auto input = new uint64_t[data.size()]; + BNMetadata** dataList = new BNMetadata*[data.size()]; for (size_t i = 0; i < data.size(); i++) - input[i] = data[i]; + dataList[i] = data[i]->m_object; - m_object = BNCreateMetadataUnsignedIntegerListData(input, data.size()); - delete[] input; + m_object = BNCreateMetadataArray(dataList, data.size()); } -Metadata::Metadata(const vector& data) +Metadata::Metadata(const std::map>& data) { - auto input = new int64_t[data.size()]; - for (size_t i = 0; i < data.size(); i++) - input[i] = data[i]; + char** keys = new char*[data.size()]; + BNMetadata** values = new BNMetadata*[data.size()]; - m_object = BNCreateMetadataSignedIntegerListData(input, data.size()); - delete[] input; + size_t i = 0; + for (auto &elm : data) + { + keys[i] = BNAllocString(elm.first.c_str()); + values[i++] = elm.second->m_object; + } + m_object = BNCreateMetadataValueStore((const char**)keys, values, data.size()); + for (size_t j = 0; j < data.size(); j++) + BNFreeString(keys[j]); + delete[] keys; + delete[] values; } -Metadata::Metadata(const vector& data) +bool Metadata::operator==(const Metadata& rhs) { - auto input = new double[data.size()]; - for (size_t i = 0; i < data.size(); i++) - input[i] = data[i]; + return BNMetadataIsEqual(m_object, rhs.m_object); +} - m_object = BNCreateMetadataDoubleListData(input, data.size()); - delete[] input; +Ref Metadata::operator[](const std::string& key) +{ + return new Metadata(BNMetadataGetForKey(m_object, key.c_str())); } -Metadata::Metadata(const vector& data) +Ref Metadata::operator[](size_t idx) { - auto input = new uint8_t[data.size()]; - for (size_t i = 0; i < data.size(); i++) - input[i] = data[i]; + return new Metadata(BNMetadataGetForIdx(m_object, idx)); +} - m_object = BNCreateMetadataRawData(input, data.size()); - delete[] input; +bool Metadata::SetValueForKey(const string& key, Ref data) +{ + return BNMetadataSetValueForKey(m_object, key.c_str(), data->m_object); } MetadataType Metadata::GetType() const @@ -126,60 +125,44 @@ double Metadata::GetDouble() const return BNMetadataGetDouble(m_object); } -vector Metadata::GetBooleanList() const -{ - size_t outSize; - bool* outList = BNMetadataGetBooleanList(m_object, &outSize); - vector result(outList, outList + outSize); - BNFreeMetadataBooleanList(outList); - return result; -} - -vector Metadata::GetStringList() const +vector Metadata::GetRaw() const { size_t outSize; - char** outList = BNMetadataGetStringList(m_object, &outSize); - vector result; - for (size_t i = 0; i < outSize; i++) - result.push_back(string(outList[i])); - BNFreeMetadataStringList(outList, outSize); + uint8_t* outList = BNMetadataGetRaw(m_object, &outSize); + vector result(outList, outList + outSize); + BNFreeMetadataRaw(outList); return result; } -vector Metadata::GetUnsignedIntegerList() const +vector> Metadata::GetArray() { - size_t outSize; - uint64_t* outList = BNMetadataGetUnsignedIntegerList(m_object, &outSize); - vector result(outList, outList + outSize); - BNFreeMetadataUnsignedIntegerList(outList); + size_t size = 0; + BNMetadata** data = BNMetadataGetArray(m_object, &size); + vector> result; + for (size_t i = 0; i < size; i++) + result.push_back(new Metadata(data[i])); return result; } -vector Metadata::GetSignedIntegerList() const +map> Metadata::GetKeyValueStore() { - size_t outSize; - int64_t* outList = BNMetadataGetSignedIntegerList(m_object, &outSize); - vector result(outList, outList + outSize); - BNFreeMetadataSignedIntegerList(outList); + BNMetadataValueStore* data = BNMetadataGetValueStore(m_object); + map> result; + for (size_t i = 0; i < data->size; i++) + { + result[data->keys[i]] = new Metadata(data->values[i]); + } return result; } -vector Metadata::GetDoubleList() const +bool Metadata::Append(Ref data) { - size_t outSize; - double* outList = BNMetadataGetDoubleList(m_object, &outSize); - vector result(outList, outList + outSize); - BNFreeMetadataDoubleList(outList); - return result; + return BNMetadataArrayAppend(m_object, data->m_object); } -vector Metadata::GetRaw() const +size_t Metadata::Size() const { - size_t outSize; - uint8_t* outList = BNMetadataGetRaw(m_object, &outSize); - vector result(outList, outList + outSize); - BNFreeMetadataRaw(outList); - return result; + return BNMetadataSize(m_object); } bool Metadata::IsBoolean() const @@ -207,32 +190,17 @@ bool Metadata::IsDouble() const return BNMetadataIsDouble(m_object); } -bool Metadata::IsBooleanList() const -{ - return BNMetadataIsBooleanList(m_object); -} - -bool Metadata::IsStringList() const -{ - return BNMetadataIsStringList(m_object); -} - -bool Metadata::IsUnsignedIntegerList() const -{ - return BNMetadataIsUnsignedIntegerList(m_object); -} - -bool Metadata::IsSignedIntegerList() const +bool Metadata::IsRaw() const { - return BNMetadataIsSignedIntegerList(m_object); + return BNMetadataIsRaw(m_object); } -bool Metadata::IsDoubleList() const +bool Metadata::IsArray() const { - return BNMetadataIsDoubleList(m_object); + return BNMetadataIsArray(m_object); } -bool Metadata::IsRaw() const +bool Metadata::IsKeyValueStore() const { - return BNMetadataIsRaw(m_object); + return BNMetadataIsKeyValueStore(m_object); } diff --git a/python/__init__.py b/python/__init__.py index ec25839b..b066e863 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -48,6 +48,7 @@ from .highlight import * from .scriptingprovider import * from .pluginmanager import * from .setting import * +from .metadata import * def shutdown(): diff --git a/python/binaryview.py b/python/binaryview.py index ad583966..d04dca86 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -26,7 +26,8 @@ import threading # Binary Ninja components import _binaryninjacore as core -from enums import AnalysisState, SymbolType, InstructionTextTokenType, Endianness, ModificationStatus, StringType, SegmentFlag +from enums import (AnalysisState, SymbolType, InstructionTextTokenType, + Endianness, ModificationStatus, StringType, SegmentFlag, MetadataType) import function import startup import architecture @@ -39,6 +40,7 @@ import databuffer import basicblock import types import lineardisassembly +import metadata class BinaryDataNotification(object): @@ -1689,11 +1691,25 @@ class BinaryView(object): return core.BNSaveToFilename(self.handle, str(dest)) def register_notification(self, notify): + """ + `register_notification` provides a mechanism for receiving callbacks for various analysis events. A full + list of callbacks can be seen in :py:Class:`BinaryDataNotification`. + + :param BinaryDataNotification notify: notify is a subclassed instance of :py:Class:`BinaryDataNotification`. + :rtype: None + """ cb = BinaryDataNotificationCallbacks(self, notify) cb._register() self.notifications[notify] = cb def unregister_notification(self, notify): + """ + `unregister_notification` unregisters the :py:Class:`BinaryDataNotification` object passed to + `register_notification` + + :param BinaryDataNotification notify: notify is a subclassed instance of :py:Class:`BinaryDataNotification`. + :rtype: None + """ if notify in self.notifications: self.notifications[notify]._unregister() del self.notifications[notify] @@ -1827,6 +1843,7 @@ class BinaryView(object): event = AnalysisCompletionEvent(self, lambda: wait.complete()) core.BNUpdateAnalysis(self.handle) wait.wait() + del event # Get rid of unused variable warning def abort_analysis(self): """ @@ -3247,6 +3264,54 @@ class BinaryView(object): core.BNFreeStringList(outgoing_names, len(name_list)) return result + def query_metadata(self, key): + """ + `query_metadata` retrieves a Metadata object stored in the current BinaryView. + + :param string key: key to query + :rtype: Metadata object + :Example: + + >>> bv.store_metadata("integer", Metadata(1337)) + >>> int(bv.query_metadata("integer")) + 1337L + >>> bv.store_metadata("list", Metadata([1,2,3])) + >>> map(int, list(bv.query_metadata("list"))) + [1L, 2L, 3L] + >>> bv.store_metadata("string", Metadata("my_data")) + >>> str(bv.query_metadata("string")) + 'my_data' + """ + md_handle = core.BNBinaryViewQueryMetadata(self.handle, key) + if md_handle is None: + raise KeyError(key) + return metadata.Metadata(handle=md_handle) + + def store_metadata(self, key, md): + """ + `store_metadata` stores a Metadata object for the given key in the current BinaryView. + Metadata objects stored using this `store_metadata` are stored in the database and can be retrieved when + the database is reopend. + + :param string key: key value to associate the Metadata object with + :param Metadata md: Metadata object to store + :rtype: None + :Example: + + >>> bv.store_metadata("integer", Metadata(1337)) + >>> int(bv.query_metadata("integer")) + 1337L + >>> bv.store_metadata("list", Metadata([1,2,3])) + >>> map(int, list(bv.query_metadata("list"))) + [1L, 2L, 3L] + >>> bv.store_metadata("string", Metadata("my_data")) + >>> str(bv.query_metadata("string")) + 'my_data' + """ + if not isinstance(md, metadata.Metadata): + raise ValueError("metadata argument must be of type Metadata") + core.BNBinaryViewStoreMetadata(self.handle, key, md.handle) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) diff --git a/python/metadata.py b/python/metadata.py new file mode 100644 index 00000000..f0e7764d --- /dev/null +++ b/python/metadata.py @@ -0,0 +1,248 @@ +# Copyright (c) 2015-2017 Vector 35 LLC +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + + +import ctypes + +# Binary Ninja components +import _binaryninjacore as core +from enums import MetadataType + + +class Metadata(object): + def __init__(self, value=None, signed=None, raw=None, handle=None): + if handle is not None: + self.handle = handle + elif isinstance(value, int): + if signed: + self.handle = core.BNCreateMetadataSignedIntegerData(value) + else: + self.handle = core.BNCreateMetadataUnsignedIntegerData(value) + elif isinstance(value, bool): + self.handle = core.BNCreateMetadataBooleanData(value) + elif isinstance(value, str): + if raw: + buffer = (ctypes.c_ubyte * len(value)).from_buffer_copy(value) + self.handle = core.BNCreateMetadataRawData(buffer, len(value)) + else: + self.handle = core.BNCreateMetadataStringData(value) + elif isinstance(value, float): + self.handle = core.BNCreateMetadataDoubleData(value) + elif isinstance(value, list): + self.handle = core.BNCreateMetadataOfType(MetadataType.ArrayDataType) + for elm in value: + md = Metadata(elm, signed, raw) + core.BNMetadataArrayAppend(self.handle, md.handle) + elif isinstance(value, dict): + self.handle = core.BNCreateMetadataOfType(MetadataType.KeyValueDataType) + for elm in value: + md = Metadata(value[elm], signed, raw) + core.BNMetadataSetValueForKey(self.handle, str(elm), md.handle) + else: + raise ValueError("List doesn't not contain type of: int, bool, str, float, list, dict") + + @property + def value(self): + if self.is_integer: + return int(self) + elif self.is_string or self.is_raw: + return str(self) + elif self.is_float: + return float(self) + elif self.is_boolean: + return bool(self) + elif self.is_array: + return list(self) + elif self.is_dict: + return dict(self) + raise NotImplementedError() + + @property + def type(self): + return MetadataType(core.BNMetadataGetType(self.handle)) + + @property + def is_integer(self): + return self.is_signed_integer or self.is_unsigned_integer + + @property + def is_signed_integer(self): + return core.BNMetadataIsSignedInteger(self.handle) + + @property + def is_unsigned_integer(self): + return core.BNMetadataIsUnsignedInteger(self.handle) + + @property + def is_float(self): + return core.BNMetadataIsDouble(self.handle) + + @property + def is_boolean(self): + return core.BNMetadataIsBoolean(self.handle) + + @property + def is_string(self): + return core.BNMetadataIsString(self.handle) + + @property + def is_raw(self): + return core.BNMetadataIsRaw(self.handle) + + @property + def is_array(self): + return core.BNMetadataIsArray(self.handle) + + @property + def is_dict(self): + return core.BNMetadataIsKeyValueStore(self.handle) + + def __len__(self): + if self.is_array or self.is_dict or self.is_string or self.is_raw: + return core.BNMetadataSize(self.handle) + raise Exception("Metadata object doesn't support len()") + + def __iter__(self): + if self.is_array: + for i in xrange(core.BNMetadataSize(self.handle)): + yield Metadata(handle=core.BNMetadataGetForIdx(self.handle, i)) + elif self.is_dict: + result = core.BNMetadataGetValueStore(self.handle) + try: + for i in xrange(result.contents.size): + yield result.contents.keys[i] + finally: + core.BNFreeMetadataValueStore(result) + else: + raise Exception("Metadata object doesn't support iteration") + + def __getitem__(self, value): + if self.is_array: + if not isinstance(value, int): + raise ValueError("Metadata object only supports integers for indexing") + if value >= len(self): + raise IndexError("Index value out of range") + return Metadata(handle=core.BNMetadataGetForIdx(self.handle, value)) + if self.is_dict: + if not isinstance(value, str): + raise ValueError("Metadata object only supports strings for indexing") + handle = core.BNMetadataGetForKey(self.handle, value) + if handle is None: + raise KeyError(value) + return Metadata(handle=handle) + + def __str__(self): + if self.is_string: + return core.BNMetadataGetString(self.handle) + if self.is_raw: + length = ctypes.c_ulonglong() + length.value = 0 + native_list = core.BNMetadataGetRaw(self.handle, ctypes.byref(length)) + out_list = [] + for i in xrange(length.value): + out_list.append(native_list[i]) + core.BNFreeMetadataRaw(native_list) + return ''.join(chr(a) for a in out_list) + + raise ValueError("Metadata object not a string or raw type") + + def __int__(self): + if self.is_signed_integer: + return core.BNMetadataGetSignedInteger(self.handle) + if self.is_unsigned_integer: + return core.BNMetadataGetUnsignedInteger(self.handle) + + raise ValueError("Metadata object not of integer type") + + def __float__(self): + if not self.is_float: + raise ValueError("Metadata object is not float type") + return core.BNMetadataGetDouble(self.handle) + + def __nonzero__(self): + if not self.is_boolean: + raise ValueError("Metadata object is not boolean type") + return core.BNMetadataGetBoolean(self.handle) + + def __eq__(self, other): + if isinstance(other, int) and self.is_integer: + return int(self) == other + elif isinstance(other, str) and (self.is_string or self.is_raw): + return str(self) == other + elif isinstance(other, float) and self.is_float: + return float(self) == other + elif isinstance(other, bool) and self.is_boolean: + return bool(self) == other + elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)): + if len(self) != len(other): + return False + for a, b in zip(self, other): + if a != b: + return False + return True + elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)): + if len(self) != len(other): + return False + for a, b in zip(self, other): + if a != b or self[a] != other[b]: + return False + return True + elif isinstance(other, Metadata) and self.is_integer and other.is_integer: + return int(self) == int(other) + elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw): + return str(self) == str(other) + elif isinstance(other, Metadata) and self.is_float and other.is_float: + return float(self) == float(other) + elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean: + return bool(self) == bool(other) + raise NotImplementedError() + + def __ne__(self, other): + if isinstance(other, int) and self.is_integer: + return int(self) != other + elif isinstance(other, str) and (self.is_string or self.is_raw): + return str(self) != other + elif isinstance(other, float) and self.is_float: + return float(self) != other + elif isinstance(other, bool): + return bool(self) != other + elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)): + if len(self) != len(other): + return True + areEqual = True + for a, b in zip(self, other): + if a != b: + areEqual = False + return not areEqual + elif self.is_dict and ((isinstance(other, Metadata) and other.is_dict) or isinstance(other, dict)): + if len(self) != len(other): + return True + for a, b in zip(self, other): + if a != b or self[a] != other[b]: + return True + return False + elif isinstance(other, Metadata) and self.is_integer and other.is_integer: + return int(self) != int(other) + elif isinstance(other, Metadata) and (self.is_string or self.is_raw) and (other.is_string or other.is_raw): + return str(self) != str(other) + elif isinstance(other, Metadata) and self.is_float and other.is_float: + return float(self) != float(other) + elif isinstance(other, Metadata) and self.is_boolean and other.is_boolean: + return bool(self) != bool(other) -- cgit v1.3.1 From 0e6019edc8c5949de4989ef9577c07913946135b Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Wed, 12 Jul 2017 22:47:12 -0400 Subject: Adding remove_metadata API to BinaryView. Add remove APIs to Metadata --- binaryninjaapi.h | 6 ++++-- binaryninjacore.h | 6 +++++- binaryview.cpp | 5 +++++ metadata.cpp | 12 +++++++++++- python/binaryview.py | 15 ++++++++++++++- python/metadata.py | 12 ++++++++++-- 6 files changed, 49 insertions(+), 7 deletions(-) (limited to 'metadata.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 83f6b582..01e5f986 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1130,6 +1130,7 @@ namespace BinaryNinja void StoreMetadata(const std::string& key, Ref value); Ref QueryMetadata(const std::string& key); + void RemoveMetadata(const std::string& key); std::string GetStringMetadata(const std::string& key); std::vector GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); @@ -2956,11 +2957,12 @@ namespace BinaryNinja //For key-value data only Ref Get(const std::string& key); bool SetValueForKey(const std::string& key, Ref data); + void RemoveKey(const std::string& key); //For array data only - Ref Get(size_t idx); + Ref Get(size_t index); bool Append(Ref data); - + void RemoveIndex(size_t index); size_t Size() const; bool IsBoolean() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 54691360..3a8b63df 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2939,8 +2939,10 @@ extern "C" BINARYNINJACOREAPI bool BNMetadataSetValueForKey(BNMetadata* data, const char* key, BNMetadata* md); BINARYNINJACOREAPI BNMetadata* BNMetadataGetForKey(BNMetadata* data, const char* key); BINARYNINJACOREAPI bool BNMetadataArrayAppend(BNMetadata* data, BNMetadata* md); + BINARYNINJACOREAPI void BNMetadataRemoveKey(BNMetadata* data, const char* key); BINARYNINJACOREAPI size_t BNMetadataSize(BNMetadata* data); - BINARYNINJACOREAPI BNMetadata* BNMetadataGetForIdx(BNMetadata* data, size_t idx); + BINARYNINJACOREAPI BNMetadata* BNMetadataGetForIndex(BNMetadata* data, size_t index); + BINARYNINJACOREAPI void BNMetadataRemoveIndex(BNMetadata* data, size_t index); BINARYNINJACOREAPI void BNFreeMetadataArray(BNMetadata** data); BINARYNINJACOREAPI void BNFreeMetadataValueStore(BNMetadataValueStore* data); @@ -2970,6 +2972,8 @@ extern "C" // Store/Query structured data to/from a BinaryView BINARYNINJACOREAPI void BNBinaryViewStoreMetadata(BNBinaryView* view, const char* key, BNMetadata* value); BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key); + BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key); + #ifdef __cplusplus } #endif diff --git a/binaryview.cpp b/binaryview.cpp index 3f1196d0..1f6820ff 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1842,6 +1842,11 @@ Ref BinaryView::QueryMetadata(const std::string& key) return new Metadata(value); } +void BinaryView::RemoveMetadata(const std::string& key) +{ + BNBinaryViewRemoveMetadata(m_object, key.c_str()); +} + string BinaryView::GetStringMetadata(const string& key) { auto data = QueryMetadata(key); diff --git a/metadata.cpp b/metadata.cpp index 18d3500b..f9c48b04 100644 --- a/metadata.cpp +++ b/metadata.cpp @@ -87,7 +87,7 @@ Ref Metadata::operator[](const std::string& key) Ref Metadata::operator[](size_t idx) { - return new Metadata(BNMetadataGetForIdx(m_object, idx)); + return new Metadata(BNMetadataGetForIndex(m_object, idx)); } bool Metadata::SetValueForKey(const string& key, Ref data) @@ -95,6 +95,11 @@ bool Metadata::SetValueForKey(const string& key, Ref data) return BNMetadataSetValueForKey(m_object, key.c_str(), data->m_object); } +void Metadata::RemoveKey(const string& key) +{ + return BNMetadataRemoveKey(m_object, key.c_str()); +} + MetadataType Metadata::GetType() const { return BNMetadataGetType(m_object); @@ -160,6 +165,11 @@ bool Metadata::Append(Ref data) return BNMetadataArrayAppend(m_object, data->m_object); } +void Metadata::RemoveIndex(size_t index) +{ + BNMetadataRemoveIndex(m_object, index); +} + size_t Metadata::Size() const { return BNMetadataSize(m_object); diff --git a/python/binaryview.py b/python/binaryview.py index d04dca86..ee019dcb 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -27,7 +27,7 @@ import threading # Binary Ninja components import _binaryninjacore as core from enums import (AnalysisState, SymbolType, InstructionTextTokenType, - Endianness, ModificationStatus, StringType, SegmentFlag, MetadataType) + Endianness, ModificationStatus, StringType, SegmentFlag) import function import startup import architecture @@ -3312,6 +3312,19 @@ class BinaryView(object): raise ValueError("metadata argument must be of type Metadata") core.BNBinaryViewStoreMetadata(self.handle, key, md.handle) + def remove_metadata(self, key): + """ + `remove_metadata` removes the Metadata object associated with key from the current BinaryView + + :param string key: key to remove from the BinaryView + :rtype: None + :Example: + + >>> bv.store_metadata("integer", Metadata(1337)) + >>> bv.remove_metadata("integer") + """ + core.BNBinaryViewRemoveMetadata(self.handle, key) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) diff --git a/python/metadata.py b/python/metadata.py index f0e7764d..2817d777 100644 --- a/python/metadata.py +++ b/python/metadata.py @@ -114,6 +114,14 @@ class Metadata(object): def is_dict(self): return core.BNMetadataIsKeyValueStore(self.handle) + def remove(self, key_or_index): + if isinstance(key_or_index, str) and self.is_dict: + core.BNMetadataRemoveKey(self.handle, key_or_index) + elif isinstance(key_or_index, int) and self.is_array: + core.BNMetadataRemoveIndex(self.handle, key_or_index) + else: + raise TypeError("remove only valid for dict and array objects") + def __len__(self): if self.is_array or self.is_dict or self.is_string or self.is_raw: return core.BNMetadataSize(self.handle) @@ -122,7 +130,7 @@ class Metadata(object): def __iter__(self): if self.is_array: for i in xrange(core.BNMetadataSize(self.handle)): - yield Metadata(handle=core.BNMetadataGetForIdx(self.handle, i)) + yield Metadata(handle=core.BNMetadataGetForIndex(self.handle, i)) elif self.is_dict: result = core.BNMetadataGetValueStore(self.handle) try: @@ -139,7 +147,7 @@ class Metadata(object): raise ValueError("Metadata object only supports integers for indexing") if value >= len(self): raise IndexError("Index value out of range") - return Metadata(handle=core.BNMetadataGetForIdx(self.handle, value)) + return Metadata(handle=core.BNMetadataGetForIndex(self.handle, value)) if self.is_dict: if not isinstance(value, str): raise ValueError("Metadata object only supports strings for indexing") -- cgit v1.3.1