From a0132eed82d28d4408a2475847e1804a157b3dc1 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Sat, 4 Mar 2017 18:11:43 -0500 Subject: Adding repo manager APIs --- pluginmanager.cpp | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 pluginmanager.cpp (limited to 'pluginmanager.cpp') diff --git a/pluginmanager.cpp b/pluginmanager.cpp new file mode 100644 index 00000000..24f6f09f --- /dev/null +++ b/pluginmanager.cpp @@ -0,0 +1,261 @@ +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + +#define RETURN_STRING(s) do { \ + char* contents = (char*)(s); \ + string result(contents); \ + BNFreeString(contents); \ + return result; \ +}while(0) + +RepoPlugin::RepoPlugin(const string& path, + bool installed, + bool enabled, + const string& api, + const string& author, + const string& description, + const string& license, + const string& licenseText, + const string& longdescription, + const string& minimimVersions, + const string& name, + const vector& pluginTypes, + const string& url, + const string& version) +{ + m_object = BNCreatePlugin(path.c_str(), + installed, + enabled, + api.c_str(), + author.c_str(), + description.c_str(), + license.c_str(), + licenseText.c_str(), + longdescription.c_str(), + minimimVersions.c_str(), + name.c_str(), + &pluginTypes[0], + pluginTypes.size(), + url.c_str(), + version.c_str()); +} + +RepoPlugin::RepoPlugin(BNRepoPlugin* plugin) +{ + m_object = plugin; +} + +string RepoPlugin::GetPath() const +{ + RETURN_STRING(BNPluginGetPath(m_object)); +} + +bool RepoPlugin::IsInstalled() const +{ + return BNPluginIsInstalled(m_object); +} + +void RepoPlugin::SetEnabled(bool enabled) +{ + return BNPluginSetEnabled(m_object, enabled); +} + +bool RepoPlugin::IsEnabled() const +{ + return BNPluginIsEnabled(m_object); +} + +PluginUpdateStatus RepoPlugin::GetPluginUpdateStatus() const +{ + return BNPluginGetPluginUpdateStatus(m_object); +} + +string RepoPlugin::GetApi() const +{ + RETURN_STRING(BNPluginGetApi(m_object)); +} + +string RepoPlugin::GetAuthor() const +{ + RETURN_STRING(BNPluginGetAuthor(m_object)); +} + +string RepoPlugin::GetDescription() const +{ + RETURN_STRING(BNPluginGetDescription(m_object)); +} + +string RepoPlugin::GetLicense() const +{ + RETURN_STRING(BNPluginGetLicense(m_object)); +} + +string RepoPlugin::GetLicenseText() const +{ + RETURN_STRING(BNPluginGetLicenseText(m_object)); +} + +string RepoPlugin::GetLongdescription() const +{ + RETURN_STRING(BNPluginGetLongdescription(m_object)); +} + +string RepoPlugin::GetMinimimVersions() const +{ + RETURN_STRING(BNPluginGetMinimimVersions(m_object)); +} + +string RepoPlugin::GetName() const +{ + RETURN_STRING(BNPluginGetName(m_object)); +} + +vector RepoPlugin::GetPluginTypes() const +{ + size_t count; + BNPluginType* pluginTypesPtr = BNPluginGetPluginTypes(m_object, &count); + vector pluginTypes; + for (size_t i = 0; i < count; i++) + { + pluginTypes.push_back((PluginType)pluginTypesPtr[i]); + } + BNFreePluginTypes(pluginTypesPtr); + return pluginTypes; +} + +string RepoPlugin::GetUrl() const +{ + RETURN_STRING(BNPluginGetUrl(m_object)); +} + +string RepoPlugin::GetVersion() const +{ + RETURN_STRING(BNPluginGetVersion(m_object)); +} + +Repository::Repository(const string& url, + const string& repoPath, + const string& repoManifest, + const string& localReference, + const string& remoteReference) +{ + m_object = BNCreateRepository(url.c_str(), + repoPath.c_str(), + localReference.c_str(), + remoteReference.c_str()); +} + +Repository::Repository(BNRepository* r) +{ + m_object = r; +} + +Repository::~Repository() +{ + BNFreeRepository(m_object); +} +string Repository::GetUrl() const +{ + RETURN_STRING(BNRepositoryGetUrl(m_object)); +} +string Repository::GetRepoPath() const +{ + RETURN_STRING(BNRepositoryGetRepoPath(m_object)); +} + +string Repository::GetLocalReference() const +{ + RETURN_STRING(BNRepositoryGetLocalReference(m_object)); +} + +string Repository::GetRemoteReference() const +{ + RETURN_STRING(BNRepositoryGetRemoteReference(m_object)); +} + +vector> Repository::GetPlugins() const +{ + vector> plugins; + size_t count = 0; + BNRepoPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count); + for (size_t i = 0; i < count; i++) + plugins.push_back(new RepoPlugin(BNNewPluginReference(pluginsPtr[i]))); + BNFreeRepositoryPluginList(pluginsPtr); + return plugins; +} + +bool Repository::IsInitialized() const +{ + return BNRepositoryIsInitialized(m_object); +} + +Ref Repository::GetPluginByPath(const string& pluginPath) +{ + return new RepoPlugin(BNNewPluginReference(BNRepositoryGetPluginByPath(m_object, pluginPath.c_str()))); +} + +string Repository::GetFullPath() const +{ + RETURN_STRING(BNRepositoryGetPluginsPath(m_object)); +} + +RepositoryManager::RepositoryManager(vector>& repoInfo, const string& enabledPluginsPath) + :m_core(false) +{ + BNRepository** buffer = new BNRepository*[repoInfo.size()]; + for (size_t i = 0; i < repoInfo.size(); i++) + buffer[i] = repoInfo[i]->m_object; + m_object = BNCreateRepositoryManager(buffer, repoInfo.size(), enabledPluginsPath.c_str()); + delete[] buffer; +} + +RepositoryManager::RepositoryManager(BNRepositoryManager* mgr) + :m_core(false) +{ + m_object = mgr; +} + +RepositoryManager::RepositoryManager() + :m_core(true) +{ + m_object = BNGetRepositoryManager(); +} + +RepositoryManager::~RepositoryManager() +{ + if (!m_core) + BNFreeRepositoryManager(m_object); +} + +bool RepositoryManager::CheckForUpdates() +{ + return BNRepositoryManagerCheckForUpdates(m_object); +} + +vector> RepositoryManager::GetRepositories() +{ + vector> repos; + size_t count = 0; + BNRepository** reposPtr = BNRepositoryManagerGetRepositories(m_object, &count); + for (size_t i = 0; i < count; i++) + repos.push_back(new Repository(BNNewRepositoryReference(reposPtr[i]))); + BNFreeRepositoryManagerRepositoriesList(reposPtr); + return repos; +} + +bool RepositoryManager::AddRepository(Ref repo) +{ + return BNRepositoryManagerAddRepository(m_object, repo->GetObject()); +} + +Ref RepositoryManager::GetRepositoryByPath(const std::string& repoPath) +{ + return new Repository(BNNewRepositoryReference(BNRepositoryGetRepositoryByPath(m_object, repoPath.c_str()))); +} + +Ref RepositoryManager::GetDefaultRepository() +{ + return new Repository(BNNewRepositoryReference(BNRepositoryManagerGetDefaultRepository(m_object))); +} -- cgit v1.3.1 From 1e8e975ed8100c7a6186e8b27833a067ceaf05be Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Wed, 22 Mar 2017 13:22:16 -0400 Subject: Modifications to support partial uninstallation --- binaryninjaapi.h | 4 +++- binaryninjacore.h | 8 ++++++-- pluginmanager.cpp | 8 ++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'pluginmanager.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 7ac790d1..544c2e10 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2604,7 +2604,9 @@ namespace BinaryNinja const std::string& name, const std::vector& pluginTypes, const std::string& url, - const std::string& version); + const std::string& version, + const std::string& repoPath, + const std::string& gitModulesPath); RepoPlugin(BNRepoPlugin* plugin); std::string GetPath() const; bool IsInstalled() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 7460f7c1..80fc715c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2417,7 +2417,9 @@ extern "C" const BNPluginType* pluginTypes, size_t pluginTypesSize, const char* url, - const char* version); + const char* version, + const char* repoPath, + const char* gitModulesPath); BINARYNINJACOREAPI BNRepoPlugin* BNNewPluginReference(BNRepoPlugin* r); BINARYNINJACOREAPI void BNFreePlugin(BNRepoPlugin* plugin); BINARYNINJACOREAPI const char* BNPluginGetPath(BNRepoPlugin* p); @@ -2475,8 +2477,10 @@ extern "C" BINARYNINJACOREAPI void BNLlvmServicesAssembleFree(char *outBytes, char *err); - BINARYNINJACOREAPI int BNDeleteDirectory(const char* path, int contentsOnly); + // Filesystem functionality BINARYNINJACOREAPI int BNDeleteFile(const char* path); + BINARYNINJACOREAPI int BNDeleteDirectory(const char* path, int contentsOnly); + BINARYNINJACOREAPI int BNCreateDirectory(const char* path); #ifdef __cplusplus } #endif diff --git a/pluginmanager.cpp b/pluginmanager.cpp index 24f6f09f..ab2b23ee 100644 --- a/pluginmanager.cpp +++ b/pluginmanager.cpp @@ -23,7 +23,9 @@ RepoPlugin::RepoPlugin(const string& path, const string& name, const vector& pluginTypes, const string& url, - const string& version) + const string& version, + const string& repoPath, + const string& gitModulesPath) { m_object = BNCreatePlugin(path.c_str(), installed, @@ -39,7 +41,9 @@ RepoPlugin::RepoPlugin(const string& path, &pluginTypes[0], pluginTypes.size(), url.c_str(), - version.c_str()); + version.c_str(), + repoPath.c_str(), + gitModulesPath.c_str()); } RepoPlugin::RepoPlugin(BNRepoPlugin* plugin) -- cgit v1.3.1 From e0f3069e8c01379ee6fca69c74ae98d8bf754535 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Tue, 28 Mar 2017 19:07:34 -0400 Subject: Cleanup of some of the plugin manager APIs --- binaryninjaapi.h | 28 ++++----------------- binaryninjacore.h | 36 ++++++++------------------ pluginmanager.cpp | 67 ++++++++----------------------------------------- python/pluginmanager.py | 34 +++++++++++++++++++------ 4 files changed, 53 insertions(+), 112 deletions(-) (limited to 'pluginmanager.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 544c2e10..bab26345 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2591,22 +2591,6 @@ namespace BinaryNinja class RepoPlugin: public CoreRefCountObject { public: - RepoPlugin(const std::string& path, - bool installed, - bool enabled, - const std::string& api, - const std::string& author, - const std::string& description, - const std::string& license, - const std::string& licenseText, - const std::string& longdescription, - const std::string& minimimVersions, - const std::string& name, - const std::vector& pluginTypes, - const std::string& url, - const std::string& version, - const std::string& repoPath, - const std::string& gitModulesPath); RepoPlugin(BNRepoPlugin* plugin); std::string GetPath() const; bool IsInstalled() const; @@ -2630,11 +2614,6 @@ namespace BinaryNinja class Repository: public CoreRefCountObject { public: - Repository(const std::string& url, // URL of the git repository containing the plugins - const std::string& repoPath, // Name of the directory to store this repository within the repositories directory - const std::string& repoManifest="plugins", // Name of the of the inner directory and .json file - const std::string& localReference="master", - const std::string& remoteReference="origin"); Repository(BNRepository* repository); ~Repository(); std::string GetUrl() const; @@ -2652,14 +2631,17 @@ namespace BinaryNinja { bool m_core; public: - RepositoryManager(std::vector>& repoInfo, const std::string& enabledPluginsPath); + RepositoryManager(const std::string& enabledPluginsPath); RepositoryManager(BNRepositoryManager* repoManager); RepositoryManager(); ~RepositoryManager(); bool CheckForUpdates(); std::vector> GetRepositories(); Ref GetRepositoryByPath(const std::string& repoName); - bool AddRepository(Ref repo); + bool AddRepository(const std::string& url, + const std::string& repoPath, // Relative path within the repositories directory + const std::string& localReference="master", + const std::string& remoteReference="origin"); bool EnablePlugin(const std::string& repoName, const std::string& pluginPath); bool DisablePlugin(const std::string& repoName, const std::string& pluginPath); bool InstallPlugin(const std::string& repoName, const std::string& pluginPath); diff --git a/binaryninjacore.h b/binaryninjacore.h index 80fc715c..0b2375ef 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2403,23 +2403,6 @@ extern "C" BINARYNINJACOREAPI const char* BNPluginGetUrl(BNRepoPlugin* p); BINARYNINJACOREAPI const char* BNPluginGetVersion(BNRepoPlugin* p); BINARYNINJACOREAPI void BNFreePluginTypes(BNPluginType* r); - BINARYNINJACOREAPI BNRepoPlugin* BNCreatePlugin(const char* path, - bool installed, - bool enabled, - const char* api, - const char* author, - const char* description, - const char* license, - const char* licenseText, - const char* longdescription, - const char* minimimVersions, - const char* name, - const BNPluginType* pluginTypes, - size_t pluginTypesSize, - const char* url, - const char* version, - const char* repoPath, - const char* gitModulesPath); BINARYNINJACOREAPI BNRepoPlugin* BNNewPluginReference(BNRepoPlugin* r); BINARYNINJACOREAPI void BNFreePlugin(BNRepoPlugin* plugin); BINARYNINJACOREAPI const char* BNPluginGetPath(BNRepoPlugin* p); @@ -2428,10 +2411,11 @@ extern "C" BINARYNINJACOREAPI bool BNPluginIsEnabled(BNRepoPlugin* p); BINARYNINJACOREAPI BNPluginUpdateStatus BNPluginGetPluginUpdateStatus(BNRepoPlugin* p); BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNRepoPlugin* p, size_t* count); - BINARYNINJACOREAPI BNRepository* BNCreateRepository(const char* url, - const char* repoPath, - const char* localReference, - const char* remoteReference); + BINARYNINJACOREAPI bool BNPluginEnable(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginDisable(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginInstall(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginUninstall(BNRepoPlugin* p); + BINARYNINJACOREAPI BNRepository* BNNewRepositoryReference(BNRepository* r); BINARYNINJACOREAPI void BNFreeRepository(BNRepository* r); BINARYNINJACOREAPI char* BNRepositoryGetUrl(BNRepository* r); @@ -2445,15 +2429,17 @@ extern "C" BINARYNINJACOREAPI BNRepoPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath); BINARYNINJACOREAPI const char* BNRepositoryGetPluginsPath(BNRepository* r); - BINARYNINJACOREAPI BNRepositoryManager* BNCreateRepositoryManager(BNRepository** repos, - size_t reposSize, - const char* enabledPluginsPath); + BINARYNINJACOREAPI BNRepositoryManager* BNCreateRepositoryManager(const char* enabledPluginsPath); BINARYNINJACOREAPI BNRepositoryManager* BNNewRepositoryManagerReference(BNRepositoryManager* r); BINARYNINJACOREAPI void BNFreeRepositoryManager(BNRepositoryManager* r); BINARYNINJACOREAPI bool BNRepositoryManagerCheckForUpdates(BNRepositoryManager* r); BINARYNINJACOREAPI BNRepository** BNRepositoryManagerGetRepositories(BNRepositoryManager* r, size_t* count); BINARYNINJACOREAPI void BNFreeRepositoryManagerRepositoriesList(BNRepository** r); - BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository(BNRepositoryManager* r, BNRepository* repo); + BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository(BNRepositoryManager* r, + const char* url, + const char* repoPath, + const char* localReference, + const char* remoteReference); BINARYNINJACOREAPI bool BNRepositoryManagerEnablePlugin(BNRepositoryManager* r, const char* repoName, const char* pluginPath); BINARYNINJACOREAPI bool BNRepositoryManagerDisablePlugin(BNRepositoryManager* r, const char* repoName, const char* pluginPath); BINARYNINJACOREAPI bool BNRepositoryManagerInstallPlugin(BNRepositoryManager* r, const char* repoName, const char* pluginPath); diff --git a/pluginmanager.cpp b/pluginmanager.cpp index ab2b23ee..95c8ea15 100644 --- a/pluginmanager.cpp +++ b/pluginmanager.cpp @@ -10,42 +10,6 @@ using namespace std; return result; \ }while(0) -RepoPlugin::RepoPlugin(const string& path, - bool installed, - bool enabled, - const string& api, - const string& author, - const string& description, - const string& license, - const string& licenseText, - const string& longdescription, - const string& minimimVersions, - const string& name, - const vector& pluginTypes, - const string& url, - const string& version, - const string& repoPath, - const string& gitModulesPath) -{ - m_object = BNCreatePlugin(path.c_str(), - installed, - enabled, - api.c_str(), - author.c_str(), - description.c_str(), - license.c_str(), - licenseText.c_str(), - longdescription.c_str(), - minimimVersions.c_str(), - name.c_str(), - &pluginTypes[0], - pluginTypes.size(), - url.c_str(), - version.c_str(), - repoPath.c_str(), - gitModulesPath.c_str()); -} - RepoPlugin::RepoPlugin(BNRepoPlugin* plugin) { m_object = plugin; @@ -139,18 +103,6 @@ string RepoPlugin::GetVersion() const RETURN_STRING(BNPluginGetVersion(m_object)); } -Repository::Repository(const string& url, - const string& repoPath, - const string& repoManifest, - const string& localReference, - const string& remoteReference) -{ - m_object = BNCreateRepository(url.c_str(), - repoPath.c_str(), - localReference.c_str(), - remoteReference.c_str()); -} - Repository::Repository(BNRepository* r) { m_object = r; @@ -205,14 +157,10 @@ string Repository::GetFullPath() const RETURN_STRING(BNRepositoryGetPluginsPath(m_object)); } -RepositoryManager::RepositoryManager(vector>& repoInfo, const string& enabledPluginsPath) +RepositoryManager::RepositoryManager(const string& enabledPluginsPath) :m_core(false) { - BNRepository** buffer = new BNRepository*[repoInfo.size()]; - for (size_t i = 0; i < repoInfo.size(); i++) - buffer[i] = repoInfo[i]->m_object; - m_object = BNCreateRepositoryManager(buffer, repoInfo.size(), enabledPluginsPath.c_str()); - delete[] buffer; + m_object = BNCreateRepositoryManager(enabledPluginsPath.c_str()); } RepositoryManager::RepositoryManager(BNRepositoryManager* mgr) @@ -249,9 +197,16 @@ vector> RepositoryManager::GetRepositories() return repos; } -bool RepositoryManager::AddRepository(Ref repo) +bool RepositoryManager::AddRepository(const std::string& url, + const std::string& repoPath, // Relative path within the repositories directory + const std::string& localReference, + const std::string& remoteReference) { - return BNRepositoryManagerAddRepository(m_object, repo->GetObject()); + return BNRepositoryManagerAddRepository(m_object, + url.c_str(), + repoPath.c_str(), + localReference.c_str(), + remoteReference.c_str()); } Ref RepositoryManager::GetRepositoryByPath(const std::string& repoPath) diff --git a/python/pluginmanager.py b/python/pluginmanager.py index 348f13fb..766b9b53 100644 --- a/python/pluginmanager.py +++ b/python/pluginmanager.py @@ -28,7 +28,8 @@ import startup class RepoPlugin(object): """ - ``Plugin`` is a read-only class. Use RepositoryManager to Enable/Disable/Install/Uninstall plugins. + ``RepoPlugin` is mostly read-only, however you can install/uninstall enable/disable plugins. RepoPlugins are + created by parsing the plugins.json in a plugin repository. """ def __init__(self, handle): self.handle = core.handle_of_type(handle, core.BNRepoPlugin) @@ -49,11 +50,25 @@ class RepoPlugin(object): """Boolean True if the plugin is installed, False otherwise""" return core.BNPluginIsInstalled(self.handle) + @installed.setter + def installed(self, state): + if state: + return core.BNPluginInstall(self.handle) + else: + return core.BNPluginUninstall(self.handle) + @property def enabled(self): """Boolean True if the plugin is currently enabled, False otherwise""" return core.BNPluginIsEnabled(self.handle) + @enabled.setter + def enabled(self, state): + if state: + return core.BNPluginEnable(self.handle) + else: + return core.BNPluginDisable(self.handle) + @property def api(self): """string indicating the api used by the plugin""" @@ -151,7 +166,7 @@ class Repository(object): @property def plugins(self): - """List of Plugin objects contained within this repository""" + """List of RepoPlugin objects contained within this repository""" pluginlist = [] count = ctypes.c_ulonglong(0) result = core.BNRepositoryGetPlugins(self.handle, count) @@ -168,6 +183,10 @@ class Repository(object): class RepositoryManager(object): + """ + ``RepositoryManager`` Keeps track of all the repositories and keeps the enabled_plugins.json file coherent with + the plugins that are installed/unstalled enabled/disabled + """ def __init__(self, handle=None): self.handle = core.BNGetRepositoryManager() @@ -236,7 +255,7 @@ class RepositoryManager(object): ``disable_plugin`` Disable the specified plugin, pluginpath :param Repository or str repo: Repository containing the plugin to disable - :param Plugin or str plugin: Plugin to disable + :param RepoPlugin or str plugin: RepoPlugin to disable :return: Boolean value True if the plugin was successfully disabled, False otherwise :rtype: Boolean :Example: @@ -261,7 +280,7 @@ class RepositoryManager(object): ``install_plugin`` install the specified plugin, pluginpath :param Repository or str repo: Repository containing the plugin to install - :param Plugin or str plugin: Plugin to install + :param RepoPlugin or str plugin: RepoPlugin to install :return: Boolean value True if the plugin was successfully installed, False otherwise :rtype: Boolean :Example: @@ -286,7 +305,7 @@ class RepositoryManager(object): ``uninstall_plugin`` uninstall the specified plugin, pluginpath :param Repository or str repo: Repository containing the plugin to uninstall - :param Plugin or str plugin: Plugin to uninstall + :param RepoPlugin or str plugin: RepoPlugin to uninstall :return: Boolean value True if the plugin was successfully uninstalled, False otherwise :rtype: Boolean :Example: @@ -311,7 +330,7 @@ class RepositoryManager(object): ``update_plugin`` update the specified plugin, pluginpath :param Repository or str repo: Repository containing the plugin to update - :param Plugin or str plugin: Plugin to update + :param RepoPlugin or str plugin: RepoPlugin to update :return: Boolean value True if the plugin was successfully updated, False otherwise :rtype: Boolean :Example: @@ -354,6 +373,5 @@ class RepositoryManager(object): if not (isinstance(url, str) and isinstance(repopath, str) and isinstance(localreference, str) and isinstance(remotereference, str)): raise ValueError("Parameter is incorrect type") - repo = core.BNCreateRepository(url, repopath, localreference, remotereference) - return core.BNRepositoryManagerAddRepository(self.handle, repo) + return core.BNRepositoryManagerAddRepository(self.handle, url, repopath, localreference, remotereference) -- cgit v1.3.1