// Copyright (c) 2015-2026 Vector 35 Inc // // 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. #include "binaryninjaapi.h" #include using namespace BinaryNinja; SecretsProvider::SecretsProvider(const std::string& name) : m_nameForRegister(name) {} SecretsProvider::SecretsProvider(BNSecretsProvider* provider) { m_object = provider; } bool SecretsProvider::HasDataCallback(void* ctxt, const char* key) { SecretsProvider* provider = (SecretsProvider*)ctxt; return provider->HasData(key); } char* SecretsProvider::GetDataCallback(void* ctxt, const char* key) { SecretsProvider* provider = (SecretsProvider*)ctxt; std::optional data = provider->GetData(key); if (!data.has_value()) return nullptr; char* value = BNAllocString(data->c_str()); memset(data->data(), 0, data->size()); return value; } bool SecretsProvider::StoreDataCallback(void* ctxt, const char* key, const char* data) { SecretsProvider* provider = (SecretsProvider*)ctxt; std::string value = data; bool result = provider->StoreData(key, value); memset(value.data(), 0, value.size()); return result; } bool SecretsProvider::DeleteDataCallback(void* ctxt, const char* key) { SecretsProvider* provider = (SecretsProvider*)ctxt; return provider->DeleteData(key); } std::vector> SecretsProvider::GetList() { size_t count; BNSecretsProvider** list = BNGetSecretsProviderList(&count); std::vector> result; result.reserve(count); for (size_t i = 0; i < count; i++) result.push_back(new CoreSecretsProvider(list[i])); BNFreeSecretsProviderList(list); return result; } Ref SecretsProvider::GetByName(const std::string& name) { BNSecretsProvider* result = BNGetSecretsProviderByName(name.c_str()); if (!result) return nullptr; return new CoreSecretsProvider(result); } void SecretsProvider::Register(SecretsProvider* provider) { BNSecretsProviderCallbacks cb; cb.context = provider; cb.hasData = HasDataCallback; cb.getData = GetDataCallback; cb.storeData = StoreDataCallback; cb.deleteData = DeleteDataCallback; provider->m_object = BNRegisterSecretsProvider(provider->m_nameForRegister.c_str(), &cb); } CoreSecretsProvider::CoreSecretsProvider(BNSecretsProvider* provider) : SecretsProvider(provider) {} bool CoreSecretsProvider::HasData(const std::string& key) { return BNSecretsProviderHasData(m_object, key.c_str()); } std::optional CoreSecretsProvider::GetData(const std::string& key) { char* data = BNGetSecretsProviderData(m_object, key.c_str()); if (data == nullptr) return std::optional(); std::string value = data; memset(data, 0, strlen(data)); BNFreeString(data); return value; } bool CoreSecretsProvider::StoreData(const std::string& key, const std::string& data) { return BNStoreSecretsProviderData(m_object, key.c_str(), data.c_str()); } bool CoreSecretsProvider::DeleteData(const std::string& key) { return BNDeleteSecretsProviderData(m_object, key.c_str()); }