diff options
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | binaryninjaapi.cpp | 29 | ||||
| -rw-r--r-- | binaryninjaapi.h | 70 | ||||
| -rw-r--r-- | binaryninjacore.h | 140 | ||||
| -rw-r--r-- | pluginmanager.cpp | 190 | ||||
| m--------- | plugins/snippets | 0 | ||||
| -rw-r--r-- | python/__init__.py | 1 | ||||
| -rw-r--r-- | python/pluginmanager.py | 52 | ||||
| -rw-r--r-- | python/scriptingprovider.py | 18 | ||||
| -rw-r--r-- | rust/src/headless.rs | 6 | ||||
| -rw-r--r-- | rust/src/repository.rs | 8 | ||||
| -rw-r--r-- | rust/src/repository/manager.rs | 76 | ||||
| -rw-r--r-- | rust/src/repository/plugin.rs | 65 | ||||
| -rw-r--r-- | ui/uicontext.h | 2 | ||||
| -rw-r--r-- | ui/uitypes.h | 2 |
15 files changed, 327 insertions, 335 deletions
diff --git a/.gitmodules b/.gitmodules index 2b095e57..cb8b6811 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "arch/x86/mbuild"] path = arch/x86/mbuild url = https://github.com/intelxed/mbuild.git +[submodule "plugins/snippets"] + path = plugins/snippets + url = git@github.com:Vector35/snippets.git diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index 9a2ded1e..58a4c0cd 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -49,30 +49,23 @@ bool BinaryNinja::InitPlugins(bool allowUserPlugins) } -void BinaryNinja::InitCorePlugins() -{ - BNInitCorePlugins(); -} - - -void BinaryNinja::InitUserPlugins() -{ - BNInitUserPlugins(); -} - - -void BinaryNinja::InitRepoPlugins() +string BinaryNinja::GetBundledPluginDirectory() { - BNInitRepoPlugins(); + char* path = BNGetBundledPluginDirectory(); + if (!path) + return string(); + string result = path; + BNFreeString(path); + return result; } -string BinaryNinja::GetBundledPluginDirectory() +std::string BinaryNinja::GetBundledScriptPluginDirectory() { - char* path = BNGetBundledPluginDirectory(); + char* path = BNGetBundledScriptPluginDirectory(); if (!path) return string(); - string result = path; + std::string result = path; BNFreeString(path); return result; } @@ -298,7 +291,7 @@ uint32_t BinaryNinja::GetBuildId() } -void BinaryNinja::SetCurrentPluginLoadOrder(BNPluginLoadOrder order) +void BinaryNinja::SetCurrentPluginLoadOrder(BNPluginLoadPhase order) { BNSetCurrentPluginLoadOrder(order); } diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a36ee271..fa0a4716 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1980,20 +1980,18 @@ namespace BinaryNinja { void DisablePlugins(); bool IsPluginsEnabled(); bool InitPlugins(bool allowUserPlugins = true); - /*! - \deprecated Use `InitPlugins()` - */ - BN_DEPRECATED("Use InitPlugins", "InitPlugins") - void InitCorePlugins(); - /*! - \deprecated Use `InitPlugins()` - */ - BN_DEPRECATED("Use InitPlugins", "InitPlugins") - void InitUserPlugins(); - void InitRepoPlugins(); std::string GetBundledPluginDirectory(); + + /*! Get the directory that script plugins bundled with BinaryNinja are located. + * + * On non-Apple platforms by default this will be identical to the core plugin directory. + * + * @return std::string - Absolute path directory that script plugins bundled with BinaryNinja are located in. + */ + std::string GetBundledScriptPluginDirectory(); void SetBundledPluginDirectory(const std::string& path); + void SetBundledScriptPluginDirectory(const std::string& path); std::string GetUserDirectory(); /*! Get the Binary Ninja system cache directory @@ -2033,7 +2031,7 @@ namespace BinaryNinja { std::string GetActiveUpdateChannel(); void SetActiveUpdateChannel(const std::string& channel); - void SetCurrentPluginLoadOrder(BNPluginLoadOrder order); + void SetCurrentPluginLoadOrder(BNPluginLoadPhase order); void AddRequiredPluginDependency(const std::string& name); void AddOptionalPluginDependency(const std::string& name); @@ -19145,13 +19143,25 @@ namespace BinaryNinja { typedef BNPluginStatus PluginStatus; typedef BNPluginType PluginType; + struct ExtensionVersion + { + std::string id; + std::string version; + + std::string longDescription; + std::string changelog; + + uint64_t minimumClientVersion; + std::string created; + }; + /*! \ingroup pluginmanager */ - class RepoPlugin : public CoreRefCountObject<BNRepoPlugin, BNNewPluginReference, BNFreePlugin> + class Extension : public CoreRefCountObject<BNPlugin, BNNewPluginReference, BNFreePlugin> { public: - RepoPlugin(BNRepoPlugin* plugin); + Extension(BNPlugin* plugin); PluginStatus GetPluginStatus() const; std::vector<std::string> GetApis() const; std::vector<std::string> GetInstallPlatforms() const; @@ -19161,20 +19171,22 @@ namespace BinaryNinja { std::string GetPluginDirectory() const; std::string GetAuthor() const; std::string GetDescription() const; - std::string GetLicenseText() const; - std::string GetLongdescription() const; std::string GetName() const; std::vector<PluginType> GetPluginTypes() const; std::string GetPackageUrl() const; std::string GetProjectUrl() const; std::string GetAuthorUrl() const; - std::string GetVersion() const; + std::vector<ExtensionVersion> GetVersions() const; + ExtensionVersion GetCurrentVersion() const; + std::string GetCurrentVersionID() const; + std::string GetLatestVersionID() const; + bool IsVersionIDLessThan(const std::string& smaller, const std::string& larger) const; std::string GetCommit() const; std::string GetRepository() const; std::string GetProjectData(); VersionInfo GetMinimumVersionInfo() const; VersionInfo GetMaximumVersionInfo() const; - uint64_t GetLastUpdate(); + std::string GetCreationDate(); bool IsViewOnly() const; bool IsBeingDeleted() const; bool IsBeingUpdated() const; @@ -19188,12 +19200,12 @@ namespace BinaryNinja { bool AreDependenciesBeingInstalled() const; bool Uninstall(); - bool Install(); + bool Install(std::string versionID); bool InstallDependencies(); // `force` ignores optional checks for platform/api compliance bool Enable(bool force); bool Disable(); - bool Update(); + bool Update(std::string versionID); }; /*! @@ -19207,26 +19219,22 @@ namespace BinaryNinja { std::string GetRepoPath() const; std::string GetLocalReference() const; std::string GetRemoteReference() const; - std::vector<Ref<RepoPlugin>> GetPlugins() const; + std::vector<Ref<Extension>> GetPlugins() const; std::string GetPluginDirectory() const; - Ref<RepoPlugin> GetPluginByPath(const std::string& pluginPath); + Ref<Extension> GetPluginByPath(const std::string& pluginPath); std::string GetFullPath() const; }; /*! \ingroup pluginmanager */ - class RepositoryManager : - public CoreRefCountObject<BNRepositoryManager, BNNewRepositoryManagerReference, BNFreeRepositoryManager> + class RepositoryManager { public: - RepositoryManager(const std::string& enabledPluginsPath); - RepositoryManager(BNRepositoryManager* repoManager); - RepositoryManager(); - bool CheckForUpdates(); - std::vector<Ref<Repository>> GetRepositories(); - Ref<Repository> GetRepositoryByPath(const std::string& repoName); - bool AddRepository(const std::string& url, // URL to raw plugins.json file + static bool CheckForUpdates(); + static std::vector<Ref<Repository>> GetRepositories(); + static Ref<Repository> GetRepositoryByPath(const std::string& repoName); + static bool AddRepository(const std::string& url, // URL to raw plugins.json file const std::string& repoPath); // Relative path within the repositories directory Ref<Repository> GetDefaultRepository(); }; diff --git a/binaryninjacore.h b/binaryninjacore.h index f140ef91..382bf1d2 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -216,11 +216,11 @@ extern "C" { #endif - BN_ENUM(uint8_t, BNPluginLoadOrder) + BN_ENUM(uint8_t, BNPluginLoadPhase) { - EarlyPluginLoadOrder, - NormalPluginLoadOrder, - LatePluginLoadOrder + NativePluginLoadPhase, + ScriptingProviderLoadPhase, + ScriptPluginLoadPhase }; BN_ENUM(uint8_t, PluginLoadStatus) @@ -231,6 +231,7 @@ extern "C" }; typedef bool (*BNCorePluginInitFunction)(void); + typedef bool (*BNScriptPluginInitFunction)(const char*, const char*); typedef void (*BNCorePluginDependencyFunction)(void); typedef uint32_t (*BNCorePluginABIVersionFunction)(void); @@ -295,8 +296,7 @@ extern "C" typedef struct BNMainThreadAction BNMainThreadAction; typedef struct BNBackgroundTask BNBackgroundTask; typedef struct BNRepository BNRepository; - typedef struct BNRepoPlugin BNRepoPlugin; - typedef struct BNRepositoryManager BNRepositoryManager; + typedef struct BNPlugin BNPlugin; typedef struct BNComponent BNComponent; typedef struct BNSettings BNSettings; typedef struct BNMetadata BNMetadata; @@ -354,6 +354,18 @@ extern "C" typedef struct BNStringRecognizer BNStringRecognizer; typedef struct BNCustomStringType BNCustomStringType; + typedef struct BNPluginVersion + { + char* id; + char* versionString; + char* longDescription; + char* changelog; + + uint64_t minimumClientVersion; + char* created; + + } BNPluginVersion; + typedef struct BNRemoteFileSearchMatch { char* projectId; @@ -4088,15 +4100,15 @@ extern "C" // Plugin initialization BINARYNINJACOREAPI bool BNInitPlugins(bool allowUserPlugins); - BINARYNINJACOREAPI bool BNInitCorePlugins(void); // Deprecated, use BNInitPlugins BINARYNINJACOREAPI void BNDisablePlugins(void); BINARYNINJACOREAPI bool BNIsPluginsEnabled(void); - BINARYNINJACOREAPI void BNInitUserPlugins(void); // Deprecated, use BNInitPlugins - BINARYNINJACOREAPI void BNInitRepoPlugins(void); BINARYNINJACOREAPI char* BNGetInstallDirectory(void); BINARYNINJACOREAPI char* BNGetBundledPluginDirectory(void); + BINARYNINJACOREAPI char* BNGetBundledScriptPluginDirectory(void); BINARYNINJACOREAPI void BNSetBundledPluginDirectory(const char* path); + BINARYNINJACOREAPI void BNSetBundledScriptPluginDirectory(const char* path); + BINARYNINJACOREAPI char* BNGetUserDirectory(void); BINARYNINJACOREAPI char* BNGetUserPluginDirectory(void); BINARYNINJACOREAPI char* BNGetRepositoriesDirectory(void); @@ -4110,7 +4122,7 @@ extern "C" BINARYNINJACOREAPI bool BNExecuteWorkerProcess(const char* path, const char** args, BNDataBuffer* input, char** output, char** error, bool stdoutIsText, bool stderrIsText); - BINARYNINJACOREAPI void BNSetCurrentPluginLoadOrder(BNPluginLoadOrder order); + BINARYNINJACOREAPI void BNSetCurrentPluginLoadOrder(BNPluginLoadPhase order); BINARYNINJACOREAPI void BNAddRequiredPluginDependency(const char* name); BINARYNINJACOREAPI void BNAddOptionalPluginDependency(const char* name); @@ -7940,75 +7952,75 @@ extern "C" BNType** outType, BNQualifiedName* outVarName, BNBinaryView* view, bool simplify); // Plugin repository APIs - BINARYNINJACOREAPI char** BNPluginGetApis(BNRepoPlugin* p, size_t* count); - BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetDescription(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetLicenseText(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetLongdescription(BNRepoPlugin* p); - BINARYNINJACOREAPI BNVersionInfo BNPluginGetMinimumVersionInfo(BNRepoPlugin* p); - BINARYNINJACOREAPI BNVersionInfo BNPluginGetMaximumVersionInfo(BNRepoPlugin* p); + BINARYNINJACOREAPI char** BNPluginGetApis(BNPlugin* p, size_t* count); + BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetDescription(BNPlugin* p); + BINARYNINJACOREAPI BNVersionInfo BNPluginGetMinimumVersionInfo(BNPlugin* p); + BINARYNINJACOREAPI BNVersionInfo BNPluginGetMaximumVersionInfo(BNPlugin* p); BINARYNINJACOREAPI BNVersionInfo BNParseVersionString(const char* v); BINARYNINJACOREAPI bool BNVersionLessThan(const BNVersionInfo smaller, const BNVersionInfo larger); - BINARYNINJACOREAPI const char* BNPluginGetName(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetProjectUrl(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetPackageUrl(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetAuthorUrl(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetVersion(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetCommit(BNRepoPlugin* p); - BINARYNINJACOREAPI const bool BNPluginGetViewOnly(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginVersionIDLessThan(BNPlugin* p, const char* smaller, const char* larger); + BINARYNINJACOREAPI const char* BNPluginGetName(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetProjectUrl(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetPackageUrl(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetAuthorUrl(BNPlugin* p); + BINARYNINJACOREAPI BNPluginVersion* BNPluginGetVersions(BNPlugin* p, size_t* count); + BINARYNINJACOREAPI void BNFreePluginVersions(BNPluginVersion* r, size_t count); + BINARYNINJACOREAPI const char* BNPluginGetCurrentVersionID(BNPlugin* p); + BINARYNINJACOREAPI BNPluginVersion BNPluginGetCurrentVersion(BNPlugin* p); + BINARYNINJACOREAPI void BNPluginFreeVersion(BNPluginVersion v); + BINARYNINJACOREAPI const char* BNPluginGetCommit(BNPlugin* p); + BINARYNINJACOREAPI const bool BNPluginGetViewOnly(BNPlugin* p); BINARYNINJACOREAPI void BNFreePluginTypes(BNPluginType* r); - BINARYNINJACOREAPI BNRepoPlugin* BNNewPluginReference(BNRepoPlugin* r); - BINARYNINJACOREAPI void BNFreePlugin(BNRepoPlugin* plugin); - BINARYNINJACOREAPI const char* BNPluginGetPath(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetSubdir(BNRepoPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetDependencies(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsInstalled(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsEnabled(BNRepoPlugin* p); - BINARYNINJACOREAPI BNPluginStatus BNPluginGetPluginStatus(BNRepoPlugin* p); - BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNRepoPlugin* p, size_t* count); - BINARYNINJACOREAPI bool BNPluginEnable(BNRepoPlugin* p, bool force); - BINARYNINJACOREAPI bool BNPluginDisable(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginInstall(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginInstallDependencies(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginUninstall(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginUpdate(BNRepoPlugin* p); - BINARYNINJACOREAPI char** BNPluginGetPlatforms(BNRepoPlugin* p, size_t* count); + BINARYNINJACOREAPI BNPlugin* BNNewPluginReference(BNPlugin* r); + BINARYNINJACOREAPI void BNFreePlugin(BNPlugin* plugin); + BINARYNINJACOREAPI const char* BNPluginGetPath(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetSubdir(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetDependencies(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetLongdescription(BNPlugin* p); + BINARYNINJACOREAPI uint64_t BNPluginGetLastUpdate(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsInstalled(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsEnabled(BNPlugin* p); + BINARYNINJACOREAPI BNPluginStatus BNPluginGetPluginStatus(BNPlugin* p); + BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNPlugin* p, size_t* count); + BINARYNINJACOREAPI bool BNPluginEnable(BNPlugin* p, bool force); + BINARYNINJACOREAPI bool BNPluginDisable(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginInstall(BNPlugin* p, const char* versionID); + BINARYNINJACOREAPI bool BNPluginInstallDependencies(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginUninstall(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginUpdate(BNPlugin* p, const char* versionID); + BINARYNINJACOREAPI char** BNPluginGetPlatforms(BNPlugin* p, size_t* count); BINARYNINJACOREAPI void BNFreePluginPlatforms(char** platforms, size_t count); - BINARYNINJACOREAPI const char* BNPluginGetRepository(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsBeingDeleted(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsBeingUpdated(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsRunning(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsUpdatePending(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsDisablePending(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsDeletePending(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsUpdateAvailable(BNRepoPlugin* p); - BINARYNINJACOREAPI bool BNPluginAreDependenciesBeingInstalled(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetRepository(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsBeingDeleted(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsBeingUpdated(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsRunning(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsUpdatePending(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsDisablePending(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsDeletePending(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsUpdateAvailable(BNPlugin* p); + BINARYNINJACOREAPI bool BNPluginAreDependenciesBeingInstalled(BNPlugin* p); - BINARYNINJACOREAPI char* BNPluginGetProjectData(BNRepoPlugin* p); - BINARYNINJACOREAPI uint64_t BNPluginGetLastUpdate(BNRepoPlugin* p); + BINARYNINJACOREAPI char* BNPluginGetProjectData(BNPlugin* p); + BINARYNINJACOREAPI char* BNPluginGetCurrentVersionCreationDate(BNPlugin* p); BINARYNINJACOREAPI BNRepository* BNNewRepositoryReference(BNRepository* r); BINARYNINJACOREAPI void BNFreeRepository(BNRepository* r); BINARYNINJACOREAPI char* BNRepositoryGetUrl(BNRepository* r); BINARYNINJACOREAPI char* BNRepositoryGetRepoPath(BNRepository* r); - BINARYNINJACOREAPI BNRepoPlugin** BNRepositoryGetPlugins(BNRepository* r, size_t* count); - BINARYNINJACOREAPI void BNFreeRepositoryPluginList(BNRepoPlugin** r); + BINARYNINJACOREAPI BNPlugin** BNRepositoryGetPlugins(BNRepository* r, size_t* count); + BINARYNINJACOREAPI void BNFreeRepositoryPluginList(BNPlugin** r); BINARYNINJACOREAPI void BNRepositoryFreePluginDirectoryList(char** list, size_t count); - BINARYNINJACOREAPI BNRepoPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath); + BINARYNINJACOREAPI BNPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath); BINARYNINJACOREAPI const char* BNRepositoryGetPluginsPath(BNRepository* r); - 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 bool BNRepositoryManagerCheckForUpdates(); + BINARYNINJACOREAPI BNRepository** BNRepositoryManagerGetRepositories(size_t* count); BINARYNINJACOREAPI void BNFreeRepositoryManagerRepositoriesList(BNRepository** r); - BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository( - BNRepositoryManager* r, const char* url, const char* repoPath); - BINARYNINJACOREAPI BNRepository* BNRepositoryGetRepositoryByPath(BNRepositoryManager* r, const char* repoPath); - BINARYNINJACOREAPI BNRepositoryManager* BNGetRepositoryManager(void); + BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository(const char* url, const char* repoPath); + BINARYNINJACOREAPI BNRepository* BNRepositoryGetRepositoryByPath(const char* repoPath); - BINARYNINJACOREAPI BNRepository* BNRepositoryManagerGetDefaultRepository(BNRepositoryManager* r); + BINARYNINJACOREAPI BNRepository* BNRepositoryManagerGetDefaultRepository(); // Components diff --git a/pluginmanager.cpp b/pluginmanager.cpp index dd62bde7..ed409c9a 100644 --- a/pluginmanager.cpp +++ b/pluginmanager.cpp @@ -12,42 +12,42 @@ using namespace std; return result; \ } while (0) -RepoPlugin::RepoPlugin(BNRepoPlugin* plugin) +Extension::Extension(BNPlugin* plugin) { m_object = plugin; } -string RepoPlugin::GetPath() const +string Extension::GetPath() const { RETURN_STRING(BNPluginGetPath(m_object)); } -string RepoPlugin::GetSubdir() const +string Extension::GetSubdir() const { RETURN_STRING(BNPluginGetSubdir(m_object)); } -string RepoPlugin::GetDependencies() const +string Extension::GetDependencies() const { RETURN_STRING(BNPluginGetDependencies(m_object)); } -bool RepoPlugin::IsInstalled() const +bool Extension::IsInstalled() const { return BNPluginIsInstalled(m_object); } -bool RepoPlugin::IsEnabled() const +bool Extension::IsEnabled() const { return BNPluginIsEnabled(m_object); } -PluginStatus RepoPlugin::GetPluginStatus() const +PluginStatus Extension::GetPluginStatus() const { return BNPluginGetPluginStatus(m_object); } -vector<string> RepoPlugin::GetApis() const +vector<string> Extension::GetApis() const { vector<string> result; size_t count = 0; @@ -60,27 +60,17 @@ vector<string> RepoPlugin::GetApis() const return result; } -string RepoPlugin::GetAuthor() const +string Extension::GetAuthor() const { RETURN_STRING(BNPluginGetAuthor(m_object)); } -string RepoPlugin::GetDescription() const +string Extension::GetDescription() const { RETURN_STRING(BNPluginGetDescription(m_object)); } -string RepoPlugin::GetLicenseText() const -{ - RETURN_STRING(BNPluginGetLicenseText(m_object)); -} - -string RepoPlugin::GetLongdescription() const -{ - RETURN_STRING(BNPluginGetLongdescription(m_object)); -} - -VersionInfo RepoPlugin::GetMinimumVersionInfo() const +VersionInfo Extension::GetMinimumVersionInfo() const { auto coreInfo = BNPluginGetMinimumVersionInfo(m_object); VersionInfo result; @@ -92,7 +82,7 @@ VersionInfo RepoPlugin::GetMinimumVersionInfo() const return result; } -VersionInfo RepoPlugin::GetMaximumVersionInfo() const +VersionInfo Extension::GetMaximumVersionInfo() const { auto coreInfo = BNPluginGetMaximumVersionInfo(m_object); VersionInfo result; @@ -104,12 +94,12 @@ VersionInfo RepoPlugin::GetMaximumVersionInfo() const return result; } -string RepoPlugin::GetName() const +string Extension::GetName() const { RETURN_STRING(BNPluginGetName(m_object)); } -vector<PluginType> RepoPlugin::GetPluginTypes() const +vector<PluginType> Extension::GetPluginTypes() const { size_t count; BNPluginType* pluginTypesPtr = BNPluginGetPluginTypes(m_object, &count); @@ -124,49 +114,101 @@ vector<PluginType> RepoPlugin::GetPluginTypes() const } -string RepoPlugin::GetProjectUrl() const +string Extension::GetProjectUrl() const { RETURN_STRING(BNPluginGetProjectUrl(m_object)); } -string RepoPlugin::GetPackageUrl() const +string Extension::GetPackageUrl() const { RETURN_STRING(BNPluginGetPackageUrl(m_object)); } -string RepoPlugin::GetAuthorUrl() const +string Extension::GetAuthorUrl() const { RETURN_STRING(BNPluginGetAuthorUrl(m_object)); } -string RepoPlugin::GetVersion() const +std::vector<ExtensionVersion> Extension::GetVersions() const +{ + size_t count; + BNPluginVersion* versionsPtr = BNPluginGetVersions(m_object, &count); + std::vector<ExtensionVersion> versions; + for (size_t i = 0; i < count; i++) + { + ExtensionVersion version; + version.id = versionsPtr[i].id ? versionsPtr[i].id : ""; + version.version = versionsPtr[i].versionString ? versionsPtr[i].versionString : + ""; + version.longDescription = versionsPtr[i].longDescription ? versionsPtr[i].longDescription : ""; + version.changelog = versionsPtr[i].changelog ? versionsPtr[i].changelog : ""; + version.minimumClientVersion = versionsPtr[i].minimumClientVersion; + version.created = versionsPtr[i].created ? versionsPtr[i].created : ""; + versions.push_back(version); + } + BNFreePluginVersions(versionsPtr, count); + return versions; +} + + +ExtensionVersion Extension::GetCurrentVersion() const +{ + ExtensionVersion version; + BNPluginVersion currentVersion = BNPluginGetCurrentVersion(m_object); + version.id = currentVersion.id ? currentVersion.id : ""; + version.version = currentVersion.versionString ? currentVersion.versionString : ""; + version.longDescription = currentVersion.longDescription ? currentVersion.longDescription : ""; + version.changelog = currentVersion.changelog ? currentVersion.changelog : ""; + version.minimumClientVersion = currentVersion.minimumClientVersion; + version.created = currentVersion.created ? currentVersion.created : ""; + BNPluginFreeVersion(currentVersion); + return version; +} + + +std::string Extension::GetCurrentVersionID() const { - RETURN_STRING(BNPluginGetVersion(m_object)); + RETURN_STRING(BNPluginGetCurrentVersionID(m_object)); } -string RepoPlugin::GetCommit() const +std::string Extension::GetLatestVersionID() const +{ + auto versions = GetVersions(); + if (versions.empty()) + return ""; + return versions.front().id; +} + + +bool Extension::IsVersionIDLessThan(const std::string& smaller, const std::string& larger) const +{ + return BNPluginVersionIDLessThan(m_object, smaller.c_str(), larger.c_str()); +} + + +string Extension::GetCommit() const { RETURN_STRING(BNPluginGetCommit(m_object)); } -bool RepoPlugin::IsViewOnly() const +bool Extension::IsViewOnly() const { return BNPluginGetViewOnly(m_object); } -string RepoPlugin::GetRepository() const +string Extension::GetRepository() const { RETURN_STRING(BNPluginGetRepository(m_object)); } -vector<string> RepoPlugin::GetInstallPlatforms() const +vector<string> Extension::GetInstallPlatforms() const { vector<string> result; size_t count = 0; @@ -179,94 +221,100 @@ vector<string> RepoPlugin::GetInstallPlatforms() const } -bool RepoPlugin::IsBeingDeleted() const +bool Extension::IsBeingDeleted() const { return BNPluginIsBeingDeleted(m_object); } -bool RepoPlugin::IsBeingUpdated() const +bool Extension::IsBeingUpdated() const { return BNPluginIsBeingUpdated(m_object); } -bool RepoPlugin::IsRunning() const +bool Extension::IsRunning() const { return BNPluginIsRunning(m_object); } -bool RepoPlugin::IsUpdatePending() const +bool Extension::IsUpdatePending() const { return BNPluginIsUpdatePending(m_object); } -bool RepoPlugin::IsDisablePending() const +bool Extension::IsDisablePending() const { return BNPluginIsDisablePending(m_object); } -bool RepoPlugin::IsDeletePending() const +bool Extension::IsDeletePending() const { return BNPluginIsDeletePending(m_object); } -bool RepoPlugin::IsUpdateAvailable() const +bool Extension::IsUpdateAvailable() const { return BNPluginIsUpdateAvailable(m_object); } -bool RepoPlugin::AreDependenciesBeingInstalled() const +bool Extension::AreDependenciesBeingInstalled() const { return BNPluginAreDependenciesBeingInstalled(m_object); } -uint64_t RepoPlugin::GetLastUpdate() +string Extension::GetCreationDate() { - return BNPluginGetLastUpdate(m_object); + return BNPluginGetCurrentVersionCreationDate(m_object); } -string RepoPlugin::GetProjectData() +string Extension::GetProjectData() { RETURN_STRING(BNPluginGetProjectData(m_object)); } -bool RepoPlugin::Uninstall() +bool Extension::Uninstall() { return BNPluginUninstall(m_object); } -bool RepoPlugin::Install() +bool Extension::Install(std::string versionID) { - return BNPluginInstall(m_object); + char* versionIDStr = BNAllocString(versionID.c_str()); + auto success = BNPluginInstall(m_object, versionIDStr); + BNFreeString(versionIDStr); + return success; } -bool RepoPlugin::InstallDependencies() +bool Extension::InstallDependencies() { return BNPluginInstallDependencies(m_object); } -bool RepoPlugin::Enable(bool force) +bool Extension::Enable(bool force) { return BNPluginEnable(m_object, force); } -bool RepoPlugin::Update() +bool Extension::Update(std::string versionID) { - return BNPluginUpdate(m_object); + char* versionIDStr = BNAllocString(versionID.c_str()); + auto success = BNPluginUpdate(m_object, versionIDStr); + BNFreeString(versionIDStr); + return success; } -bool RepoPlugin::Disable() +bool Extension::Disable() { return BNPluginDisable(m_object); } @@ -289,22 +337,22 @@ string Repository::GetRepoPath() const } -vector<Ref<RepoPlugin>> Repository::GetPlugins() const +vector<Ref<Extension>> Repository::GetPlugins() const { - vector<Ref<RepoPlugin>> plugins; + vector<Ref<Extension>> plugins; size_t count = 0; - BNRepoPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count); + BNPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count); plugins.reserve(count); for (size_t i = 0; i < count; i++) - plugins.push_back(new RepoPlugin(BNNewPluginReference(pluginsPtr[i]))); + plugins.push_back(new Extension(BNNewPluginReference(pluginsPtr[i]))); BNFreeRepositoryPluginList(pluginsPtr); return plugins; } -Ref<RepoPlugin> Repository::GetPluginByPath(const string& pluginPath) +Ref<Extension> Repository::GetPluginByPath(const string& pluginPath) { - return new RepoPlugin(BNRepositoryGetPluginByPath(m_object, pluginPath.c_str())); + return new Extension(BNRepositoryGetPluginByPath(m_object, pluginPath.c_str())); } string Repository::GetFullPath() const @@ -312,32 +360,16 @@ string Repository::GetFullPath() const RETURN_STRING(BNRepositoryGetPluginsPath(m_object)); } -RepositoryManager::RepositoryManager(const string& enabledPluginsPath) -{ - m_object = BNCreateRepositoryManager(enabledPluginsPath.c_str()); -} - -RepositoryManager::RepositoryManager(BNRepositoryManager* mgr) -{ - m_object = mgr; -} - -RepositoryManager::RepositoryManager() -{ - m_object = BNGetRepositoryManager(); -} - bool RepositoryManager::CheckForUpdates() { - return BNRepositoryManagerCheckForUpdates(m_object); + return BNRepositoryManagerCheckForUpdates(); } vector<Ref<Repository>> RepositoryManager::GetRepositories() { vector<Ref<Repository>> repos; size_t count = 0; - BNRepository** reposPtr = BNRepositoryManagerGetRepositories(m_object, &count); - repos.reserve(count); + BNRepository** reposPtr = BNRepositoryManagerGetRepositories(&count); for (size_t i = 0; i < count; i++) repos.push_back(new Repository(BNNewRepositoryReference(reposPtr[i]))); BNFreeRepositoryManagerRepositoriesList(reposPtr); @@ -347,15 +379,15 @@ vector<Ref<Repository>> RepositoryManager::GetRepositories() bool RepositoryManager::AddRepository(const std::string& url, const std::string& repoPath) // Relative path within the repositories directory { - return BNRepositoryManagerAddRepository(m_object, url.c_str(), repoPath.c_str()); + return BNRepositoryManagerAddRepository(url.c_str(), repoPath.c_str()); } Ref<Repository> RepositoryManager::GetRepositoryByPath(const std::string& repoPath) { - return new Repository(BNRepositoryGetRepositoryByPath(m_object, repoPath.c_str())); + return new Repository(BNRepositoryGetRepositoryByPath(repoPath.c_str())); } Ref<Repository> RepositoryManager::GetDefaultRepository() { - return new Repository(BNRepositoryManagerGetDefaultRepository(m_object)); + return new Repository(BNRepositoryManagerGetDefaultRepository()); } diff --git a/plugins/snippets b/plugins/snippets new file mode 160000 +Subproject 1f528e946bed410bb287f14a66a12493d70c408 diff --git a/python/__init__.py b/python/__init__.py index 8790ac8f..cafea2e8 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -263,7 +263,6 @@ def _init_plugins(): if _enable_default_log and is_headless_init_once and min_level in LogLevel.__members__ and not core_ui_enabled( ) and sys.stderr.isatty(): log_to_stderr(LogLevel[min_level]) - core.BNInitRepoPlugins() if core.BNIsLicenseValidated(): _plugin_init = True else: diff --git a/python/pluginmanager.py b/python/pluginmanager.py index 27360dbe..5e32a79f 100644 --- a/python/pluginmanager.py +++ b/python/pluginmanager.py @@ -29,9 +29,9 @@ from . import deprecation from .enums import PluginType -class RepoPlugin: +class Extension: """ - ``RepoPlugin`` is mostly read-only, however you can install/uninstall enable/disable plugins. RepoPlugins are + ``Extension`` is mostly read-only, however you can install/uninstall enable/disable plugins. Extensions are created by parsing the plugins.json in a plugin repository. """ def __init__(self, handle: 'core.BNRepoPluginHandle'): @@ -70,10 +70,10 @@ class RepoPlugin: """Boolean True if the plugin is installed, False otherwise""" return core.BNPluginIsInstalled(self.handle) - def install(self) -> bool: + def install(self, version_id=None) -> bool: """Attempt to install the given plugin""" self.install_dependencies() - return core.BNPluginInstall(self.handle) + return core.BNPluginInstall(self.handle, version_id) def uninstall(self) -> bool: """Attempt to uninstall the given plugin""" @@ -83,7 +83,7 @@ class RepoPlugin: def installed(self, state: bool): if state: self.install_dependencies() - core.BNPluginInstall(self.handle) + core.BNPluginInstall(self.handle, None) else: core.BNPluginUninstall(self.handle) @@ -126,14 +126,16 @@ class RepoPlugin: core.BNFreePluginPlatforms(platforms, count.value) @property + @deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`current_version` in combination with :py:attr:`versions` instead.') def description(self) -> Optional[str]: """String short description of the plugin""" return core.BNPluginGetDescription(self.handle) @property + @deprecation.deprecated(deprecated_in="5.3", details='This field will be removed.') def license_text(self) -> Optional[str]: """String complete license text for the given plugin""" - return core.BNPluginGetLicenseText(self.handle) + return '' @property def long_description(self) -> Optional[str]: @@ -185,6 +187,7 @@ class RepoPlugin: return core.BNPluginGetProjectUrl(self.handle) @property + @deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`current_version` in combination with :py:attr:`versions` instead.') def package_url(self) -> Optional[str]: """String URL of the plugin's zip file""" return core.BNPluginGetPackageUrl(self.handle) @@ -200,9 +203,17 @@ class RepoPlugin: return core.BNPluginGetAuthor(self.handle) @property + @deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`current_version` in combination with :py:attr:`versions` instead.') def version(self) -> Optional[str]: """String version of the plugin""" - return core.BNPluginGetVersion(self.handle) + version: core.BNPluginVersion = core.BNPluginGetCurrentVersion(self.handle) + try: + version_string = version.versionString + except AttributeError: + version_string = "" + finally: + core.BNPluginFreeVersion(version) + return version_string @property def install_platforms(self) -> List[str]: @@ -259,6 +270,7 @@ class RepoPlugin: return core.BNPluginAreDependenciesBeingInstalled(self.handle) @property + @deprecation.deprecated(deprecated_in="5.3", details='This field will be removed.') def project_data(self) -> Dict: """Gets a json object of the project data field""" data = core.BNPluginGetProjectData(self.handle) @@ -266,11 +278,18 @@ class RepoPlugin: return json.loads(data) @property + @deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`versions` in combination with :py:attr:`current_version` to check for updates instead.') def last_update(self) -> date: """Returns a datetime object representing the plugins last update""" return datetime.fromtimestamp(core.BNPluginGetLastUpdate(self.handle)) +@deprecation.deprecated(deprecated_in="5.3", details='Use :py:class:`binaryninja.Extension` instead.') +class RepoPlugin(Extension): + def __init__(self, handle: 'core.BNRepoPluginHandle'): + super().__init__(handle) + + class Repository: """ ``Repository`` is a read-only class. Use RepositoryManager to Enable/Disable/Install/Uninstall plugins. @@ -313,8 +332,8 @@ class Repository: return result @property - def plugins(self) -> List[RepoPlugin]: - """List of RepoPlugin objects contained within this repository""" + def plugins(self) -> List[Extension]: + """List of Extension objects contained within this repository""" pluginlist = [] count = ctypes.c_ulonglong(0) result = core.BNRepositoryGetPlugins(self.handle, count) @@ -323,7 +342,7 @@ class Repository: for i in range(count.value): plugin_ref = core.BNNewPluginReference(result[i]) assert plugin_ref is not None, "core.BNNewPluginReference returned None" - pluginlist.append(RepoPlugin(plugin_ref)) + pluginlist.append(Extension(plugin_ref)) return pluginlist finally: core.BNFreeRepositoryPluginList(result) @@ -337,7 +356,6 @@ class RepositoryManager: """ def __init__(self): binaryninja._init_plugins() - self.handle = core.BNGetRepositoryManager() def __getitem__(self, repo_path: str) -> Repository: for repo in self.repositories: @@ -347,14 +365,14 @@ class RepositoryManager: def check_for_updates(self) -> bool: """Check for updates for all managed Repository objects""" - return core.BNRepositoryManagerCheckForUpdates(self.handle) + return core.BNRepositoryManagerCheckForUpdates() @property def repositories(self) -> List[Repository]: """List of Repository objects being managed""" result = [] count = ctypes.c_ulonglong(0) - repos = core.BNRepositoryManagerGetRepositories(self.handle, count) + repos = core.BNRepositoryManagerGetRepositories(count) assert repos is not None, "core.BNRepositoryManagerGetRepositories returned None" try: for i in range(count.value): @@ -366,8 +384,8 @@ class RepositoryManager: core.BNFreeRepositoryManagerRepositoriesList(repos) @property - def plugins(self) -> Dict[str, List[RepoPlugin]]: - """List of all RepoPlugins in each repository""" + def plugins(self) -> Dict[str, List[Extension]]: + """List of all Extensions in each repository""" plugin_list = {} for repo in self.repositories: plugin_list[repo.path] = repo.plugins @@ -376,7 +394,7 @@ class RepositoryManager: @property def default_repository(self) -> Repository: """Gets the default Repository""" - repo_handle = core.BNRepositoryManagerGetDefaultRepository(self.handle) + repo_handle = core.BNRepositoryManagerGetDefaultRepository() assert repo_handle is not None, "core.BNRepositoryManagerGetDefaultRepository returned None" repo_handle_ref = core.BNNewRepositoryReference(repo_handle) assert repo_handle_ref is not None, "core.BNNewRepositoryReference returned None" @@ -406,4 +424,4 @@ class RepositoryManager: if not isinstance(url, str) or not isinstance(repopath, str): raise ValueError("Expected url or repopath to be of type str.") - return core.BNRepositoryManagerAddRepository(self.handle, url, repopath) + return core.BNRepositoryManagerAddRepository(url, repopath) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index dbeef1cb..3b6718af 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -53,6 +53,7 @@ from .pluginmanager import RepositoryManager from .enums import ScriptingProviderExecuteResult, ScriptingProviderInputReadyState from .settings import Settings from .enums import SettingsScope +import json _WARNING_REGEX = re.compile(r'^\S+:\d+: \w+Warning: ') @@ -1086,12 +1087,8 @@ class PythonScriptingProvider(ScriptingProvider): plugin = repo[module] if not force and self.apiName not in plugin.api: - raise ValueError(f"Plugin API name is not {self.name}") + raise ValueError(f"Plugin '{plugin.name}' API name '{plugin.api}' is not {self.name}") - if not force and core.core_platform not in plugin.install_platforms: - raise ValueError( - f"Current platform {core.core_platform} isn't in list of valid platforms for this plugin {plugin.install_platforms}" - ) if not plugin.installed: plugin.installed = True @@ -1218,8 +1215,13 @@ class PythonScriptingProvider(ScriptingProvider): def _install_modules(self, ctx, _modules: bytes) -> bool: # This callback should not be called directly - modules = _modules.decode("utf-8") - if len(modules.strip()) == 0: + dependencies_json = json.loads(_modules.decode("utf-8")) + modules = "" + if "pip" in dependencies_json: + if len(dependencies_json["pip"].strip()) == 0: + return True + modules = [line.split('#', 1)[0].strip() for line in dependencies_json["pip"].split('\n') if line.split('#', 1)[0].strip()] + if len(modules) == 0: return True python_lib = settings.Settings().get_string("python.interpreter") python_bin_override = settings.Settings().get_string("python.binaryOverride") @@ -1267,7 +1269,7 @@ class PythonScriptingProvider(ScriptingProvider): ) / f"python{sys.version_info.major}{sys.version_info.minor}" / "site-packages" site_package_dir.mkdir(parents=True, exist_ok=True) args.extend(["--target", str(site_package_dir)]) - args.extend(list(filter(len, modules.split("\n")))) + args.extend(list(filter(len, modules))) logger.log_info(f"Running pip {args}") status, result = self._run_args(args, env=python_env) if status: diff --git a/rust/src/headless.rs b/rust/src/headless.rs index 73bc2396..b134c8fe 100644 --- a/rust/src/headless.rs +++ b/rust/src/headless.rs @@ -26,7 +26,7 @@ use crate::enterprise::EnterpriseCheckoutStatus; use crate::main_thread::{MainThreadAction, MainThreadHandler}; use crate::progress::ProgressCallback; use crate::rc::Ref; -use binaryninjacore_sys::{BNInitPlugins, BNInitRepoPlugins}; +use binaryninjacore_sys::{BNInitPlugins}; use std::sync::mpsc::Sender; use std::sync::Mutex; use std::thread::JoinHandle; @@ -221,10 +221,6 @@ pub fn init_with_opts(options: InitializationOptions) -> Result<(), Initializati unsafe { BNInitPlugins(options.user_plugins); - if options.repo_plugins { - // We are allowed to initialize repo plugins, so do it! - BNInitRepoPlugins(); - } } if !is_license_validated() { diff --git a/rust/src/repository.rs b/rust/src/repository.rs index b7d61cac..2f1ab267 100644 --- a/rust/src/repository.rs +++ b/rust/src/repository.rs @@ -11,7 +11,7 @@ use std::ptr::NonNull; use binaryninjacore_sys::*; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::repository::plugin::RepositoryPlugin; +use crate::repository::plugin::Extension; use crate::string::{BnString, IntoCStr}; pub use manager::RepositoryManager; @@ -49,17 +49,17 @@ impl Repository { } /// List of RepoPlugin objects contained within this repository - pub fn plugins(&self) -> Array<RepositoryPlugin> { + pub fn plugins(&self) -> Array<Extension> { let mut count = 0; let result = unsafe { BNRepositoryGetPlugins(self.handle.as_ptr(), &mut count) }; assert!(!result.is_null()); unsafe { Array::new(result, count, ()) } } - pub fn plugin_by_path(&self, path: &Path) -> Option<Ref<RepositoryPlugin>> { + pub fn plugin_by_path(&self, path: &Path) -> Option<Ref<Extension>> { let path = path.to_cstr(); let result = unsafe { BNRepositoryGetPluginByPath(self.handle.as_ptr(), path.as_ptr()) }; - NonNull::new(result).map(|h| unsafe { RepositoryPlugin::ref_from_raw(h) }) + NonNull::new(result).map(|h| unsafe { Extension::ref_from_raw(h) }) } /// String full path the repository diff --git a/rust/src/repository/manager.rs b/rust/src/repository/manager.rs index cf0118ad..d20539c4 100644 --- a/rust/src/repository/manager.rs +++ b/rust/src/repository/manager.rs @@ -1,11 +1,10 @@ -use crate::rc::{Array, Ref, RefCountable}; +use crate::rc::{Array, Ref}; use crate::repository::Repository; use crate::string::IntoCStr; use binaryninjacore_sys::{ - BNCreateRepositoryManager, BNFreeRepositoryManager, BNGetRepositoryManager, - BNNewRepositoryManagerReference, BNRepositoryGetRepositoryByPath, BNRepositoryManager, - BNRepositoryManagerAddRepository, BNRepositoryManagerCheckForUpdates, - BNRepositoryManagerGetDefaultRepository, BNRepositoryManagerGetRepositories, + BNRepositoryGetRepositoryByPath, BNRepositoryManagerAddRepository, + BNRepositoryManagerCheckForUpdates, BNRepositoryManagerGetDefaultRepository, + BNRepositoryManagerGetRepositories, }; use std::fmt::Debug; use std::path::Path; @@ -13,38 +12,18 @@ use std::ptr::NonNull; /// Keeps track of all the repositories and keeps the `enabled_plugins.json` /// file coherent with the plugins that are installed/uninstalled enabled/disabled -#[repr(transparent)] -pub struct RepositoryManager { - handle: NonNull<BNRepositoryManager>, -} +pub struct RepositoryManager; impl RepositoryManager { - #[allow(clippy::should_implement_trait)] - pub fn default() -> Ref<Self> { - let result = unsafe { BNGetRepositoryManager() }; - unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } - } - - pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepositoryManager>) -> Ref<Self> { - Ref::new(Self { handle }) - } - - pub fn new(plugins_path: &str) -> Ref<Self> { - let plugins_path = plugins_path.to_cstr(); - let result = unsafe { BNCreateRepositoryManager(plugins_path.as_ptr()) }; - unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } - } - /// Check for updates for all managed [`Repository`] objects - pub fn check_for_updates(&self) -> bool { - unsafe { BNRepositoryManagerCheckForUpdates(self.handle.as_ptr()) } + pub fn check_for_updates() -> bool { + unsafe { BNRepositoryManagerCheckForUpdates() } } /// List of [`Repository`] objects being managed - pub fn repositories(&self) -> Array<Repository> { + pub fn repositories() -> Array<Repository> { let mut count = 0; - let result = - unsafe { BNRepositoryManagerGetRepositories(self.handle.as_ptr(), &mut count) }; + let result = unsafe { BNRepositoryManagerGetRepositories(&mut count) }; assert!(!result.is_null()); unsafe { Array::new(result, count, ()) } } @@ -60,24 +39,21 @@ impl RepositoryManager { /// * `repository_path` - path to where the repository will be stored on disk locally /// /// Returns true if the repository was successfully added, false otherwise. - pub fn add_repository(&self, url: &str, repository_path: &Path) -> bool { + pub fn add_repository(url: &str, repository_path: &Path) -> bool { let url = url.to_cstr(); let repo_path = repository_path.to_cstr(); - unsafe { - BNRepositoryManagerAddRepository(self.handle.as_ptr(), url.as_ptr(), repo_path.as_ptr()) - } + unsafe { BNRepositoryManagerAddRepository(url.as_ptr(), repo_path.as_ptr()) } } - pub fn repository_by_path(&self, path: &Path) -> Option<Repository> { + pub fn repository_by_path(path: &Path) -> Option<Repository> { let path = path.to_cstr(); - let result = - unsafe { BNRepositoryGetRepositoryByPath(self.handle.as_ptr(), path.as_ptr()) }; + let result = unsafe { BNRepositoryGetRepositoryByPath(path.as_ptr()) }; NonNull::new(result).map(|raw| unsafe { Repository::from_raw(raw) }) } /// Gets the default [`Repository`] - pub fn default_repository(&self) -> Ref<Repository> { - let result = unsafe { BNRepositoryManagerGetDefaultRepository(self.handle.as_ptr()) }; + pub fn default_repository() -> Ref<Repository> { + let result = unsafe { BNRepositoryManagerGetDefaultRepository() }; assert!(!result.is_null()); unsafe { Repository::ref_from_raw(NonNull::new(result).unwrap()) } } @@ -86,27 +62,7 @@ impl RepositoryManager { impl Debug for RepositoryManager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("RepositoryManager") - .field("repositories", &self.repositories().to_vec()) + .field("repositories", &RepositoryManager::repositories().to_vec()) .finish() } } - -impl ToOwned for RepositoryManager { - type Owned = Ref<Self>; - - fn to_owned(&self) -> Self::Owned { - unsafe { RefCountable::inc_ref(self) } - } -} - -unsafe impl RefCountable for RepositoryManager { - unsafe fn inc_ref(handle: &Self) -> Ref<Self> { - Self::ref_from_raw( - NonNull::new(BNNewRepositoryManagerReference(handle.handle.as_ptr())).unwrap(), - ) - } - - unsafe fn dec_ref(handle: &Self) { - BNFreeRepositoryManager(handle.handle.as_ptr()) - } -} diff --git a/rust/src/repository/plugin.rs b/rust/src/repository/plugin.rs index e0ab9679..ba95c29c 100644 --- a/rust/src/repository/plugin.rs +++ b/rust/src/repository/plugin.rs @@ -1,25 +1,24 @@ use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::repository::{PluginStatus, PluginType}; -use crate::string::BnString; +use crate::string::{BnString, IntoCStr}; use crate::VersionInfo; use binaryninjacore_sys::*; use std::ffi::c_char; use std::fmt::Debug; use std::path::PathBuf; use std::ptr::NonNull; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; #[repr(transparent)] -pub struct RepositoryPlugin { - handle: NonNull<BNRepoPlugin>, +pub struct Extension { + handle: NonNull<BNPlugin>, } -impl RepositoryPlugin { - pub(crate) unsafe fn from_raw(handle: NonNull<BNRepoPlugin>) -> Self { +impl Extension { + pub(crate) unsafe fn from_raw(handle: NonNull<BNPlugin>) -> Self { Self { handle } } - pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepoPlugin>) -> Ref<Self> { + pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNPlugin>) -> Ref<Self> { Ref::new(Self { handle }) } @@ -45,20 +44,6 @@ impl RepositoryPlugin { unsafe { BnString::into_string(result as *mut c_char) } } - /// String complete license text for the given plugin - pub fn license_text(&self) -> String { - let result = unsafe { BNPluginGetLicenseText(self.handle.as_ptr()) }; - assert!(!result.is_null()); - unsafe { BnString::into_string(result as *mut c_char) } - } - - /// String long description of the plugin - pub fn long_description(&self) -> String { - let result = unsafe { BNPluginGetLongdescription(self.handle.as_ptr()) }; - assert!(!result.is_null()); - unsafe { BnString::into_string(result as *mut c_char) } - } - /// Minimum version info the plugin was tested on pub fn minimum_version_info(&self) -> VersionInfo { let result = unsafe { BNPluginGetMinimumVersionInfo(self.handle.as_ptr()) }; @@ -98,12 +83,6 @@ impl RepositoryPlugin { assert!(!result.is_null()); unsafe { BnString::into_string(result as *mut c_char) } } - /// String version of the plugin - pub fn version(&self) -> String { - let result = unsafe { BNPluginGetVersion(self.handle.as_ptr()) }; - assert!(!result.is_null()); - unsafe { BnString::into_string(result as *mut c_char) } - } /// String of the commit of this plugin git repository pub fn commit(&self) -> String { @@ -168,8 +147,9 @@ impl RepositoryPlugin { } /// Attempt to install the given plugin - pub fn install(&self) -> bool { - unsafe { BNPluginInstall(self.handle.as_ptr()) } + pub fn install(&self, version_id: &str) -> bool { + let version_id_raw = version_id.to_cstr(); + unsafe { BNPluginInstall(self.handle.as_ptr(), version_id_raw.as_ptr()) } } pub fn install_dependencies(&self) -> bool { @@ -181,8 +161,9 @@ impl RepositoryPlugin { unsafe { BNPluginUninstall(self.handle.as_ptr()) } } - pub fn updated(&self) -> bool { - unsafe { BNPluginUpdate(self.handle.as_ptr()) } + pub fn updated(&self, version_id: &str) -> bool { + let version_id_raw = version_id.to_cstr(); + unsafe { BNPluginUpdate(self.handle.as_ptr(), version_id_raw.as_ptr()) } } /// List of platforms this plugin can execute on @@ -245,30 +226,22 @@ impl RepositoryPlugin { assert!(!result.is_null()); unsafe { BnString::into_string(result) } } - - /// Returns a datetime object representing the plugins last update - pub fn last_update(&self) -> SystemTime { - let result = unsafe { BNPluginGetLastUpdate(self.handle.as_ptr()) }; - UNIX_EPOCH + Duration::from_secs(result) - } } -impl Debug for RepositoryPlugin { +impl Debug for Extension { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RepositoryPlugin") + f.debug_struct("Extension") .field("name", &self.name()) - .field("version", &self.version()) .field("author", &self.author()) .field("description", &self.description()) .field("minimum_version_info", &self.minimum_version_info()) .field("maximum_version_info", &self.maximum_version_info()) - .field("last_update", &self.last_update()) .field("status", &self.status()) .finish() } } -impl ToOwned for RepositoryPlugin { +impl ToOwned for Extension { type Owned = Ref<Self>; fn to_owned(&self) -> Self::Owned { @@ -276,7 +249,7 @@ impl ToOwned for RepositoryPlugin { } } -unsafe impl RefCountable for RepositoryPlugin { +unsafe impl RefCountable for Extension { unsafe fn inc_ref(handle: &Self) -> Ref<Self> { Self::ref_from_raw(NonNull::new(BNNewPluginReference(handle.handle.as_ptr())).unwrap()) } @@ -286,13 +259,13 @@ unsafe impl RefCountable for RepositoryPlugin { } } -impl CoreArrayProvider for RepositoryPlugin { - type Raw = *mut BNRepoPlugin; +impl CoreArrayProvider for Extension { + type Raw = *mut BNPlugin; type Context = (); type Wrapped<'a> = Guard<'a, Self>; } -unsafe impl CoreArrayProviderInner for RepositoryPlugin { +unsafe impl CoreArrayProviderInner for Extension { unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) { BNFreeRepositoryPluginList(raw) } diff --git a/ui/uicontext.h b/ui/uicontext.h index fcb77479..3cd4116c 100644 --- a/ui/uicontext.h +++ b/ui/uicontext.h @@ -673,7 +673,7 @@ void BINARYNINJAUIAPI InitUIViews(); void BINARYNINJAUIAPI InitUIActions(); void BINARYNINJAUIAPI InitUIPlugins(); -void BINARYNINJAUIAPI SetCurrentUIPluginLoadOrder(BNPluginLoadOrder order); +void BINARYNINJAUIAPI SetCurrentUIPluginLoadOrder(BNPluginLoadPhase order); void BINARYNINJAUIAPI AddRequiredUIPluginDependency(const std::string& name); void BINARYNINJAUIAPI AddOptionalUIPluginDependency(const std::string& name); diff --git a/ui/uitypes.h b/ui/uitypes.h index f01ed988..dde77c4a 100644 --- a/ui/uitypes.h +++ b/ui/uitypes.h @@ -116,7 +116,7 @@ typedef BinaryNinja::Ref<BinaryNinja::TypeLibrary> TypeLibraryRef; typedef BinaryNinja::Ref<BinaryNinja::WebsocketClient> WebsocketClientRef; typedef BinaryNinja::Ref<BinaryNinja::WebsocketProvider> WebsocketProviderRef; typedef BinaryNinja::Ref<BinaryNinja::Workflow> WorkflowRef; -typedef BinaryNinja::Ref<BinaryNinja::RepoPlugin> RepoPluginRef; +typedef BinaryNinja::Ref<BinaryNinja::Extension> ExtensionRef; typedef BinaryNinja::Ref<BinaryNinja::Repository> RepositoryRef; typedef BinaryNinja::Ref<BinaryNinja::RepositoryManager> RepositoryManagerRef; typedef BinaryNinja::Ref<BinaryNinja::Logger> LoggerRef; |
