summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2019-05-14 21:34:57 -0700
committerPeter LaFosse <peter@vector35.com>2019-07-08 23:14:30 -0400
commitad37832dd4ffa112b10b523a151d3fa9b86b6c9d (patch)
tree364641f60f878150bb010c4b51f088e49c8ba058
parent7e7f0b41548057093fb48f1d8985712b619e9438 (diff)
PluginManager refactor for supporting plugin installation ui
Expose additional PluginManager APIs and update documentation
-rw-r--r--binaryninjaapi.cpp13
-rw-r--r--binaryninjaapi.h49
-rw-r--r--binaryninjacore.h67
-rw-r--r--pluginmanager.cpp181
-rw-r--r--python/__init__.py60
-rw-r--r--python/binaryview.py20
-rw-r--r--python/downloadprovider.py7
-rw-r--r--python/generator.cpp7
-rw-r--r--python/pluginmanager.py284
-rw-r--r--ui/uitypes.h3
10 files changed, 385 insertions, 306 deletions
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp
index 66ddbffd..5dcc3ad1 100644
--- a/binaryninjaapi.cpp
+++ b/binaryninjaapi.cpp
@@ -368,3 +368,16 @@ map<string, uint64_t> BinaryNinja::GetMemoryUsageInfo()
BNFreeMemoryUsageInfo(info, count);
return result;
}
+
+
+vector<string> BinaryNinja::GetRegisteredPluginLoaders()
+{
+ size_t count = 0;
+ char** loaders = BNGetRegisteredPluginLoaders(&count);
+ vector<string> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(loaders[i]);
+ BNFreeRegisteredPluginLoadersList(loaders, count);
+ return result;
+}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 258d1d8a..b3be594a 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -707,6 +707,7 @@ namespace BinaryNinja
std::string GetUniqueIdentifierString();
std::map<std::string, uint64_t> GetMemoryUsageInfo();
+ std::vector<std::string> GetRegisteredPluginLoaders();
class DataBuffer
{
@@ -4263,30 +4264,51 @@ namespace BinaryNinja
};
typedef BNPluginOrigin PluginOrigin;
- typedef BNPluginUpdateStatus PluginUpdateStatus;
+ typedef BNPluginStatus PluginStatus;
typedef BNPluginType PluginType;
class RepoPlugin: public CoreRefCountObject<BNRepoPlugin, BNNewPluginReference, BNFreePlugin>
{
public:
RepoPlugin(BNRepoPlugin* plugin);
+ PluginStatus GetPluginStatus() const;
+ std::vector<std::string> GetApis() const;
+ std::vector<std::string> GetInstallPlatforms() const;
std::string GetPath() const;
- bool IsInstalled() const;
std::string GetPluginDirectory() const;
- void SetEnabled(bool enabled);
- bool IsEnabled() const;
- PluginUpdateStatus GetPluginUpdateStatus() const;
- std::string GetApi() const;
std::string GetAuthor() const;
std::string GetDescription() const;
std::string GetLicense() const;
std::string GetLicenseText() const;
std::string GetLongdescription() const;
- std::string GetMinimimVersions() const;
std::string GetName() const;
std::vector<PluginType> GetPluginTypes() const;
- std::string GetUrl() const;
+ std::string GetPackageUrl() const;
+ std::string GetProjectUrl() const;
+ std::string GetAuthorUrl() const;
std::string GetVersion() const;
+ std::string GetCommit() const;
+ std::string GetRepository() const;
+ std::string GetProjectData();
+ std::string GetInstallInstructions(const std::string& platform) const;
+ uint64_t GetMinimimVersion() const;
+ uint64_t GetLastUpdate();
+ bool IsBeingDeleted() const;
+ bool IsBeingUpdated() const;
+ bool IsInstalled() const;
+ bool IsEnabled() const;
+ bool IsRunning() const;
+ bool IsUpdatePending() const;
+ bool IsDisablePending() const;
+ bool IsDeletePending() const;
+ bool IsUpdateAvailable() const;
+
+ bool Uninstall();
+ bool Install();
+ // `force` ignores optional checks for platform/api compliance
+ bool Enable(bool force);
+ bool Disable();
+ bool Update();
};
class Repository: public CoreRefCountObject<BNRepository, BNNewRepositoryReference, BNFreeRepository>
@@ -4298,7 +4320,6 @@ namespace BinaryNinja
std::string GetLocalReference() const;
std::string GetRemoteReference() const;
std::vector<Ref<RepoPlugin>> GetPlugins() const;
- bool IsInitialized() const;
std::string GetPluginDirectory() const;
Ref<RepoPlugin> GetPluginByPath(const std::string& pluginPath);
std::string GetFullPath() const;
@@ -4313,14 +4334,8 @@ namespace BinaryNinja
bool CheckForUpdates();
std::vector<Ref<Repository>> GetRepositories();
Ref<Repository> GetRepositoryByPath(const std::string& repoName);
- 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);
- bool UninstallPlugin(const std::string& repoName, const std::string& pluginPath);
+ 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 c4b90f7e..842a2a50 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -161,7 +161,7 @@ extern "C"
struct BNDataRendererContainer;
struct BNDisassemblyTextRenderer;
- typedef bool (*BNLoadPluginCallback)(const char* repoPath, const char* pluginPath, void* ctx);
+ typedef bool (*BNLoadPluginCallback)(const char* repoPath, const char* pluginPath, bool force, void* ctx);
//! Console log levels
enum BNLogLevel
@@ -779,10 +779,18 @@ extern "C"
OtherPluginOrigin
};
- enum BNPluginUpdateStatus
+ enum BNPluginStatus
{
- UpToDatePluginStatus,
- UpdatesAvailablePluginStatus
+ NotInstalledPluginStatus = 0x00000000,
+ InstalledPluginStatus = 0x00000001,
+ EnabledPluginStatus = 0x00000002,
+ UpdateAvailablePluginStatus = 0x00000010,
+ DeletePendingPluginStatus = 0x00000020,
+ UpdatePendingPluginStatus = 0x00000040,
+ DisablePendingPluginStatus = 0x00000080,
+ PendingRestartPluginStatus = 0x00000200,
+ BeingUpdatedPluginStatus = 0x00000400,
+ BeingDeletedPluginStatus = 0x00000800
};
enum BNPluginType
@@ -790,7 +798,8 @@ extern "C"
CorePluginType,
UiPluginType,
ArchitecturePluginType,
- BinaryViewPluginType
+ BinaryViewPluginType,
+ HelperPluginType
};
struct BNLookupTableEntry
@@ -3717,39 +3726,53 @@ extern "C"
BINARYNINJACOREAPI void BNFreeDemangledName(char*** name, size_t nameElements);
// Plugin repository APIs
- BINARYNINJACOREAPI const char* BNPluginGetApi(BNRepoPlugin* p);
+ BINARYNINJACOREAPI char** BNPluginGetApis(BNRepoPlugin* p, size_t* count);
BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNRepoPlugin* p);
BINARYNINJACOREAPI const char* BNPluginGetDescription(BNRepoPlugin* p);
BINARYNINJACOREAPI const char* BNPluginGetLicense(BNRepoPlugin* p);
BINARYNINJACOREAPI const char* BNPluginGetLicenseText(BNRepoPlugin* p);
BINARYNINJACOREAPI const char* BNPluginGetLongdescription(BNRepoPlugin* p);
- BINARYNINJACOREAPI const char* BNPluginGetMinimimVersions(BNRepoPlugin* p);
+ BINARYNINJACOREAPI uint64_t BNPluginGetMinimimVersion(BNRepoPlugin* p);
BINARYNINJACOREAPI const char* BNPluginGetName(BNRepoPlugin* p);
- BINARYNINJACOREAPI const char* BNPluginGetUrl(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 void BNFreePluginTypes(BNPluginType* r);
BINARYNINJACOREAPI BNRepoPlugin* BNNewPluginReference(BNRepoPlugin* r);
BINARYNINJACOREAPI void BNFreePlugin(BNRepoPlugin* plugin);
BINARYNINJACOREAPI const char* BNPluginGetPath(BNRepoPlugin* p);
BINARYNINJACOREAPI bool BNPluginIsInstalled(BNRepoPlugin* p);
- BINARYNINJACOREAPI void BNPluginSetEnabled(BNRepoPlugin* p, bool enabled);
BINARYNINJACOREAPI bool BNPluginIsEnabled(BNRepoPlugin* p);
- BINARYNINJACOREAPI BNPluginUpdateStatus BNPluginGetPluginUpdateStatus(BNRepoPlugin* p);
+ BINARYNINJACOREAPI BNPluginStatus BNPluginGetPluginStatus(BNRepoPlugin* p);
BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNRepoPlugin* p, size_t* count);
- BINARYNINJACOREAPI bool BNPluginEnable(BNRepoPlugin* p);
+ BINARYNINJACOREAPI bool BNPluginEnable(BNRepoPlugin* p, bool force);
BINARYNINJACOREAPI bool BNPluginDisable(BNRepoPlugin* p);
BINARYNINJACOREAPI bool BNPluginInstall(BNRepoPlugin* p);
BINARYNINJACOREAPI bool BNPluginUninstall(BNRepoPlugin* p);
+ BINARYNINJACOREAPI bool BNPluginUpdate(BNRepoPlugin* p);
+ BINARYNINJACOREAPI char* BNPluginGetInstallInstructions(BNRepoPlugin* p, const char* platform);
+ BINARYNINJACOREAPI char** BNPluginGetPlatforms(BNRepoPlugin* 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 char* BNPluginGetProjectData(BNRepoPlugin* p);
+ BINARYNINJACOREAPI uint64_t BNPluginGetLastUpdate(BNRepoPlugin* p);
BINARYNINJACOREAPI BNRepository* BNNewRepositoryReference(BNRepository* r);
BINARYNINJACOREAPI void BNFreeRepository(BNRepository* r);
BINARYNINJACOREAPI char* BNRepositoryGetUrl(BNRepository* r);
BINARYNINJACOREAPI char* BNRepositoryGetRepoPath(BNRepository* r);
- BINARYNINJACOREAPI char* BNRepositoryGetLocalReference(BNRepository* r);
- BINARYNINJACOREAPI char* BNRepositoryGetRemoteReference(BNRepository* r);
BINARYNINJACOREAPI BNRepoPlugin** BNRepositoryGetPlugins(BNRepository* r, size_t* count);
BINARYNINJACOREAPI void BNFreeRepositoryPluginList(BNRepoPlugin** r);
- BINARYNINJACOREAPI bool BNRepositoryIsInitialized(BNRepository* r);
BINARYNINJACOREAPI void BNRepositoryFreePluginDirectoryList(char** list, size_t count);
BINARYNINJACOREAPI BNRepoPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath);
BINARYNINJACOREAPI const char* BNRepositoryGetPluginsPath(BNRepository* r);
@@ -3762,23 +3785,18 @@ extern "C"
BINARYNINJACOREAPI void BNFreeRepositoryManagerRepositoriesList(BNRepository** r);
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);
- BINARYNINJACOREAPI bool BNRepositoryManagerUninstallPlugin(BNRepositoryManager* r, const char* repoName, const char* pluginPath);
- BINARYNINJACOREAPI bool BNRepositoryManagerUpdatePlugin(BNRepositoryManager* r, const char* repoName, const char* pluginPath);
+ const char* repoPath);
BINARYNINJACOREAPI BNRepository* BNRepositoryGetRepositoryByPath(BNRepositoryManager* r, const char* repoPath);
BINARYNINJACOREAPI BNRepositoryManager* BNGetRepositoryManager();
BINARYNINJACOREAPI BNRepository* BNRepositoryManagerGetDefaultRepository(BNRepositoryManager* r);
BINARYNINJACOREAPI void BNRegisterForPluginLoading(
const char* pluginApiName,
- bool (*cb)(const char* repoPath, const char* pluginPath, void* ctx),
+ bool (*cb)(const char* repoPath, const char* pluginPath, bool force, void* ctx), // BNLoadPluginCallback
void* ctx);
- BINARYNINJACOREAPI bool BNLoadPluginForApi(const char* pluginApiName, const char* repoPath, const char* pluginPath);
+ BINARYNINJACOREAPI bool BNLoadPluginForApi(const char* pluginApiName, const char* repoPath, const char* pluginPath, bool force);
+ BINARYNINJACOREAPI char** BNGetRegisteredPluginLoaders(size_t* count);
+ BINARYNINJACOREAPI void BNFreeRegisteredPluginLoadersList(char** pluginLoaders, size_t count);
// LLVM Services APIs
BINARYNINJACOREAPI void BNLlvmServicesInit(void);
@@ -3796,6 +3814,7 @@ extern "C"
BINARYNINJACOREAPI bool BNIsPathDirectory(const char* path);
BINARYNINJACOREAPI bool BNIsPathRegularFile(const char* path);
BINARYNINJACOREAPI bool BNFileSize(const char* path, uint64_t* size);
+ BINARYNINJACOREAPI bool BNRenameFile(const char* source, const char* dest);
// Settings APIs
BINARYNINJACOREAPI bool BNSettingsRegisterGroup(const char* registry, const char* group, const char* title);
diff --git a/pluginmanager.cpp b/pluginmanager.cpp
index be0d0d9d..9572d362 100644
--- a/pluginmanager.cpp
+++ b/pluginmanager.cpp
@@ -25,24 +25,27 @@ 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
+PluginStatus RepoPlugin::GetPluginStatus() const
{
- return BNPluginGetPluginUpdateStatus(m_object);
+ return BNPluginGetPluginStatus(m_object);
}
-string RepoPlugin::GetApi() const
+vector<string> RepoPlugin::GetApis() const
{
- RETURN_STRING(BNPluginGetApi(m_object));
+ vector<string> result;
+ size_t count = 0;
+ char** apis = BNPluginGetApis(m_object, &count);
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(apis[i]);
+
+ BNFreeStringList(apis, count);
+ return result;
}
string RepoPlugin::GetAuthor() const
@@ -70,9 +73,9 @@ string RepoPlugin::GetLongdescription() const
RETURN_STRING(BNPluginGetLongdescription(m_object));
}
-string RepoPlugin::GetMinimimVersions() const
+uint64_t RepoPlugin::GetMinimimVersion() const
{
- RETURN_STRING(BNPluginGetMinimimVersions(m_object));
+ return BNPluginGetMinimimVersion(m_object);
}
string RepoPlugin::GetName() const
@@ -93,16 +96,142 @@ vector<PluginType> RepoPlugin::GetPluginTypes() const
return pluginTypes;
}
-string RepoPlugin::GetUrl() const
+
+string RepoPlugin::GetProjectUrl() const
{
- RETURN_STRING(BNPluginGetUrl(m_object));
+ RETURN_STRING(BNPluginGetProjectUrl(m_object));
}
+
+string RepoPlugin::GetPackageUrl() const
+{
+ RETURN_STRING(BNPluginGetPackageUrl(m_object));
+}
+
+
+string RepoPlugin::GetAuthorUrl() const
+{
+ RETURN_STRING(BNPluginGetAuthorUrl(m_object));
+}
+
+
string RepoPlugin::GetVersion() const
{
RETURN_STRING(BNPluginGetVersion(m_object));
}
+
+string RepoPlugin::GetCommit() const
+{
+ RETURN_STRING(BNPluginGetCommit(m_object));
+}
+
+
+string RepoPlugin::GetRepository() const
+{
+ RETURN_STRING(BNPluginGetRepository(m_object));
+}
+
+
+vector<string> RepoPlugin::GetInstallPlatforms() const
+{
+ vector<string> result;
+ size_t count = 0;
+ char** platforms = BNPluginGetPlatforms(m_object, &count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(platforms[i]);
+ BNFreeStringList(platforms, count);
+ return result;
+}
+
+
+std::string RepoPlugin::GetInstallInstructions(const std::string& platform) const
+{
+ RETURN_STRING(BNPluginGetInstallInstructions(m_object, platform.c_str()));
+}
+
+
+bool RepoPlugin::IsBeingDeleted() const
+{
+ return BNPluginIsBeingDeleted(m_object);
+}
+
+bool RepoPlugin::IsBeingUpdated() const
+{
+ return BNPluginIsBeingUpdated(m_object);
+}
+
+bool RepoPlugin::IsRunning() const
+{
+ return BNPluginIsRunning(m_object);
+}
+
+
+bool RepoPlugin::IsUpdatePending() const
+{
+ return BNPluginIsUpdatePending(m_object);
+}
+
+
+bool RepoPlugin::IsDisablePending() const
+{
+ return BNPluginIsDisablePending(m_object);
+}
+
+
+bool RepoPlugin::IsDeletePending() const
+{
+ return BNPluginIsDeletePending(m_object);
+}
+
+
+bool RepoPlugin::IsUpdateAvailable() const
+{
+ return BNPluginIsUpdateAvailable(m_object);
+}
+
+
+uint64_t RepoPlugin::GetLastUpdate()
+{
+ return BNPluginGetLastUpdate(m_object);
+}
+
+string RepoPlugin::GetProjectData()
+{
+ RETURN_STRING(BNPluginGetProjectData(m_object));
+}
+
+
+bool RepoPlugin::Uninstall()
+{
+ return BNPluginUninstall(m_object);
+}
+
+
+bool RepoPlugin::Install()
+{
+ return BNPluginInstall(m_object);
+}
+
+
+bool RepoPlugin::Enable(bool force)
+{
+ return BNPluginEnable(m_object, force);
+}
+
+
+bool RepoPlugin::Update()
+{
+ return BNPluginUpdate(m_object);
+}
+
+
+bool RepoPlugin::Disable()
+{
+ return BNPluginDisable(m_object);
+}
+
+
Repository::Repository(BNRepository* r)
{
m_object = r;
@@ -112,36 +241,26 @@ 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<Ref<RepoPlugin>> Repository::GetPlugins() const
{
vector<Ref<RepoPlugin>> plugins;
size_t count = 0;
BNRepoPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count);
+ plugins.reserve(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<RepoPlugin> Repository::GetPluginByPath(const string& pluginPath)
{
@@ -185,15 +304,9 @@ vector<Ref<Repository>> RepositoryManager::GetRepositories()
}
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)
+ const std::string& repoPath) // Relative path within the repositories directory
{
- return BNRepositoryManagerAddRepository(m_object,
- url.c_str(),
- repoPath.c_str(),
- localReference.c_str(),
- remoteReference.c_str());
+ return BNRepositoryManagerAddRepository(m_object, url.c_str(), repoPath.c_str());
}
Ref<Repository> RepositoryManager::GetRepositoryByPath(const std::string& repoPath)
diff --git a/python/__init__.py b/python/__init__.py
index bdc6bdd7..f572bdef 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -24,7 +24,7 @@ import atexit
import sys
import ctypes
from time import gmtime
-
+import os
# 2-3 compatibility
PY2 = sys.version_info[0] == 2
@@ -92,37 +92,7 @@ def pyNativeStr(arg):
# Binary Ninja components
import binaryninja._binaryninjacore as core
-# __all__ = [
-# "enums",
-# "databuffer",
-# "filemetadata",
-# "fileaccessor",
-# "binaryview",
-# "transform",
-# "architecture",
-# "basicblock",
-# "function",
-# "log",
-# "lowlevelil",
-# "mediumlevelil",
-# "types",
-# "functionrecognizer",
-# "update",
-# "plugin",
-# "callingconvention",
-# "platform",
-# "demangle",
-# "mainthread",
-# "interaction",
-# "lineardisassembly",
-# "undoaction",
-# "highlight",
-# "scriptingprovider",
-# "pluginmanager",
-# "setting",
-# "metadata",
-# "flowgraph",
-# ]
+
from binaryninja.enums import *
from binaryninja.databuffer import *
from binaryninja.filemetadata import *
@@ -179,34 +149,42 @@ def get_install_directory():
return core.BNGetInstallDirectory()
-_plugin_api_name = "python2"
+_plugin_api_name = "python{}".format(sys.version_info.major)
class PluginManagerLoadPluginCallback(object):
- """Callback for BNLoadPluginForApi("python2", ...), dynamically loads python plugins."""
+ """Callback for BNLoadPluginForApi("python{version}", ...), dynamically loads python plugins."""
def __init__(self):
self.cb = ctypes.CFUNCTYPE(
ctypes.c_bool,
ctypes.c_char_p,
ctypes.c_char_p,
+ ctypes.c_bool,
ctypes.c_void_p)(self._load_plugin)
- def _load_plugin(self, repo_path, plugin_path, ctx):
+ def _load_plugin(self, repo_path, plugin_path, force, ctx):
try:
+ repo_path = repo_path.decode("utf-8")
+ plugin_path = plugin_path.decode("utf-8")
repo = RepositoryManager()[repo_path]
plugin = repo[plugin_path]
- if plugin.api != _plugin_api_name:
+ if not force and _plugin_api_name not in plugin.api:
raise ValueError("Plugin API name is not " + _plugin_api_name)
+ if not force and core.core_platform not in plugin.install_platforms:
+ raise ValueError("Current platform {} ins't in list of valid platforms for this plugin {}".format(
+ core.core_platform, plugin.install_platforms))
if not plugin.installed:
plugin.installed = True
+ plugin_full_path = os.path.join(repo.full_path, plugin.path)
if repo.full_path not in sys.path:
sys.path.append(repo.full_path)
+ if plugin_full_path not in sys.path:
+ sys.path.append(plugin_full_path)
- __import__(plugin.path)
- log_info("Successfully loaded plugin: {}/{}: ".format(repo_path, plugin_path))
+ __import__(plugin_path)
return True
except KeyError:
log_error("Failed to find python plugin: {}/{}".format(repo_path, plugin_path))
@@ -284,12 +262,12 @@ def core_version():
def core_build_id():
"""
- ``core_build_id`` returns a string containing the current build id
+ ``core_build_id`` returns a integer containing the current build id
:return: current build id
- :rtype: str, or None on failure
+ :rtype: int
"""
- core.BNGetBuildId()
+ return core.BNGetBuildId()
def core_serial():
"""
diff --git a/python/binaryview.py b/python/binaryview.py
index 4ffe197e..4f146adc 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -645,7 +645,8 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
:rtype: BinaryView or None
"""
sqlite = b"SQLite format 3"
- if filename.endswith(".bndb"):
+ isDatabase = filename.endswith(".bndb")
+ if isDatabase:
f = open(filename, 'rb')
if f is None or f.read(len(sqlite)) != sqlite:
return None
@@ -658,18 +659,21 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
return None
for available in view.available_view_types:
if available.name != "Raw":
- if filename.endswith(".bndb"):
+ if isDatabase:
bv = view.get_view_of_type(available.name)
else:
bv = cls[available.name].open(filename)
+ break
+ else:
+ if isDatabase:
+ bv = view.get_view_of_type("Raw")
+ else:
+ bv = cls["Raw"].open(filename)
- if bv is None:
- raise Exception("Unknown Architecture/Architecture Not Found (check plugins folder)")
+ if bv is not None and update_analysis:
+ bv.update_analysis_and_wait()
+ return bv
- if update_analysis:
- bv.update_analysis_and_wait()
- return bv
- return None
def is_valid_for_data(self, data):
return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle)
diff --git a/python/downloadprovider.py b/python/downloadprovider.py
index 8d3718b9..27f007ff 100644
--- a/python/downloadprovider.py
+++ b/python/downloadprovider.py
@@ -79,9 +79,6 @@ class DownloadInstance(object):
def perform_request(self, ctxt, url):
raise NotImplementedError
- def perform_request(self, url, callbacks):
- return core.BNPerformDownloadRequest(self.handle, url, callbacks)
-
class _DownloadProviderMetaclass(type):
@property
@@ -165,11 +162,9 @@ if (sys.platform != "win32") and (sys.version_info >= (2, 7, 9)):
def __init__(self, provider):
super(PythonDownloadInstance, self).__init__(provider)
- @abc.abstractmethod
def perform_destroy_instance(self):
pass
- @abc.abstractmethod
def perform_request(self, url):
try:
proxy_setting = Settings().get_string('downloadClient.httpsProxy')
@@ -223,11 +218,9 @@ else:
def __init__(self, provider):
super(PythonDownloadInstance, self).__init__(provider)
- @abc.abstractmethod
def perform_destroy_instance(self):
pass
- @abc.abstractmethod
def perform_request(self, url):
try:
proxy_setting = Settings().get_string('downloadClient.httpsProxy')
diff --git a/python/generator.cpp b/python/generator.cpp
index dbb44253..8186647a 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -188,13 +188,14 @@ int main(int argc, char* argv[])
fprintf(out, "import platform\n");
fprintf(out, "core = None\n");
fprintf(out, "_base_path = None\n");
- fprintf(out, "if platform.system() == \"Darwin\":\n");
+ fprintf(out, "core_platform = platform.system()\n");
+ fprintf(out, "if core_platform == \"Darwin\":\n");
fprintf(out, "\t_base_path = os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"..\", \"MacOS\")\n");
fprintf(out, "\tcore = ctypes.CDLL(os.path.join(_base_path, \"libbinaryninjacore.dylib\"))\n\n");
- fprintf(out, "elif platform.system() == \"Linux\":\n");
+ fprintf(out, "elif core_platform == \"Linux\":\n");
fprintf(out, "\t_base_path = os.path.join(os.path.dirname(__file__), \"..\", \"..\")\n");
fprintf(out, "\tcore = ctypes.CDLL(os.path.join(_base_path, \"libbinaryninjacore.so.1\"))\n\n");
- fprintf(out, "elif platform.system() == \"Windows\":\n");
+ fprintf(out, "elif core_platform == \"Windows\":\n");
fprintf(out, "\t_base_path = os.path.join(os.path.dirname(__file__), \"..\", \"..\")\n");
fprintf(out, "\tcore = ctypes.CDLL(os.path.join(_base_path, \"binaryninjacore.dll\"))\n");
fprintf(out, "else:\n");
diff --git a/python/pluginmanager.py b/python/pluginmanager.py
index 3f75d68b..73fe0db6 100644
--- a/python/pluginmanager.py
+++ b/python/pluginmanager.py
@@ -19,10 +19,13 @@
# IN THE SOFTWARE.
import ctypes
+import json
+from datetime import datetime
# Binary Ninja components
+import binaryninja
from binaryninja import _binaryninjacore as core
-
+from binaryninja.enums import PluginType, PluginStatus
# 2-3 compatibility
from binaryninja import range
@@ -32,9 +35,7 @@ class RepoPlugin(object):
``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.
"""
- from binaryninja.enums import PluginType, PluginUpdateStatus
def __init__(self, handle):
- raise Exception("RepoPlugin temporarily disabled!")
self.handle = core.handle_of_type(handle, core.BNRepoPlugin)
def __del__(self):
@@ -68,14 +69,29 @@ class RepoPlugin(object):
@enabled.setter
def enabled(self, state):
if state:
- return core.BNPluginEnable(self.handle)
+ return core.BNPluginEnable(self.handle, False)
else:
return core.BNPluginDisable(self.handle)
+ def enable(self, force=False):
+ """
+ Enable this plugin, optionally trying to force it.
+ Force loading a plugin with ignore platform and api constraints.
+ (e.g. The plugin author says the plugin will only work on Linux-python3 but you'd like to
+ attempt to load it on Macos-python2)
+ """
+ return core.BNPluginEnable(self.handle, force)
+
@property
def api(self):
"""string indicating the API used by the plugin"""
- return core.BNPluginGetApi(self.handle)
+ result = []
+ count = ctypes.c_ulonglong(0)
+ platforms = core.BNPluginGetApis(self.handle, count)
+ for i in range(count.value):
+ result.append(platforms[i])
+ core.BNFreePluginPlatforms(platforms, count)
+ return result
@property
def description(self):
@@ -100,7 +116,7 @@ class RepoPlugin(object):
@property
def minimum_version(self):
"""String minimum version the plugin was tested on"""
- return core.BNPluginGetMinimimVersions(self.handle)
+ return core.BNPluginGetMinimimVersion(self.handle)
@property
def name(self):
@@ -119,34 +135,109 @@ class RepoPlugin(object):
return result
@property
- def url(self):
+ def project_url(self):
"""String URL of the plugin's git repository"""
- return core.BNPluginGetUrl(self.handle)
+ return core.BNPluginGetProjectUrl(self.handle)
+
+ @property
+ def package_url(self):
+ """String URL of the plugin's zip file"""
+ return core.BNPluginGetPackageUrl(self.handle)
+
+ @property
+ def author_url(self):
+ """String URL of the plugin author's url"""
+ return core.BNPluginGetAuthorUrl(self.handle)
+
+ @property
+ def author(self):
+ """String of the plugin author"""
+ return core.BNPluginGetAuthor(self.handle)
@property
def version(self):
"""String version of the plugin"""
return core.BNPluginGetVersion(self.handle)
+
+ def install_instructions(self, platform):
+ """
+ Installation instructions for the given platform
+
+ :param str platform: One of the valid platforms "Windows", "Linux", "Darwin"
+ :return: String of the installation instructions for the provided platform
+ :rtype: str
+ """
+ return core.BNPluginGetInstallInstructions(self.handle, platform)
+
@property
- def update_status(self):
- """PluginUpdateStatus enumeration indicating if the plugin is up to date or not"""
- return PluginUpdateStatus(core.BNPluginGetPluginUpdateStatus(self.handle))
+ def install_platforms(self):
+ """List of platforms this plugin can execute on"""
+ result = []
+ count = ctypes.c_ulonglong(0)
+ platforms = core.BNPluginGetPlatforms(self.handle, count)
+ for i in range(count.value):
+ result.append(platforms[i])
+ core.BNFreePluginPlatforms(platforms, count)
+ return result
+ @property
+ def being_deleted(self):
+ """Boolean status indicating that the plugin is being deleted"""
+ return core.BNPluginIsBeingDeleted(self.handle)
+
+ @property
+ def being_updated(self):
+ """Boolean status indicating that the plugin is being updated"""
+ return core.BNPluginIsBeingUpdated(self.handle)
+
+ @property
+ def running(self):
+ """Boolean status indicating that the plugin is currently running"""
+ return core.BNPluginIsRunning(self.handle)
+
+ @property
+ def update_pending(self):
+ """Boolean status indicating that the plugin has updates will be installed after the next restart"""
+ return core.BNPluginIsUpdatePending(self.handle)
+
+ @property
+ def disable_pending(self):
+ """Boolean status indicating that the plugin will be disabled after the next restart"""
+ return core.BNPluginIsDisablePending(self.handle)
+
+ @property
+ def delete_pending(self):
+ """Boolean status indicating that the plugin will be deleted after the next restart"""
+ return core.BNPluginIsDeletePending(self.handle)
+
+ @property
+ def update_available(self):
+ """Boolean status indicating that the plugin has updates available"""
+ return core.BNPluginIsUpdateAvailable(self.handle)
+
+ @property
+ def project_data(self):
+ """Gets a json object of the project data field"""
+ return json.loads(core.BNPluginGetProjectData(self.handle))
+
+ @property
+ def last_update(self):
+ """Returns a datetime object representing the plugins last update"""
+ return datetime.fromtimestamp(core.BNPluginGetLastUpdate(self.handle))
class Repository(object):
"""
``Repository`` is a read-only class. Use RepositoryManager to Enable/Disable/Install/Uninstall plugins.
"""
def __init__(self, handle):
- raise Exception("Repository temporarily disabled!")
self.handle = core.handle_of_type(handle, core.BNRepository)
def __del__(self):
core.BNFreeRepository(self.handle)
def __repr__(self):
- return "<{} - {}/{}>".format(self.path, self.remote_reference, self.local_reference)
+ return "<{}>".format(self.path)
def __getitem__(self, plugin_path):
for plugin in self.plugins:
@@ -170,32 +261,17 @@ class Repository(object):
return core.BNRepositoryGetPluginsPath(self.handle)
@property
- def local_reference(self):
- """String for the local git reference (ie 'master')"""
- return core.BNRepositoryGetLocalReference(self.handle)
-
- @property
- def remote_reference(self):
- """String for the remote git reference (ie 'origin')"""
- return core.BNRepositoryGetRemoteReference(self.handle)
-
- @property
def plugins(self):
"""List of RepoPlugin objects contained within this repository"""
pluginlist = []
count = ctypes.c_ulonglong(0)
result = core.BNRepositoryGetPlugins(self.handle, count)
for i in range(count.value):
- pluginlist.append(RepoPlugin(handle=result[i]))
+ pluginlist.append(RepoPlugin(core.BNNewPluginReference(result[i])))
core.BNFreeRepositoryPluginList(result, count.value)
del result
return pluginlist
- @property
- def initialized(self):
- """Boolean True when the repository has been initialized"""
- return core.BNRepositoryIsInitialized(self.handle)
-
class RepositoryManager(object):
"""
@@ -203,7 +279,6 @@ class RepositoryManager(object):
the plugins that are installed/uninstalled enabled/disabled
"""
def __init__(self, handle=None):
- raise Exception("RepositoryManager temporarily disabled!")
self.handle = core.BNGetRepositoryManager()
def __getitem__(self, repo_path):
@@ -223,7 +298,7 @@ class RepositoryManager(object):
count = ctypes.c_ulonglong(0)
repos = core.BNRepositoryManagerGetRepositories(self.handle, count)
for i in range(count.value):
- result.append(Repository(handle=repos[i]))
+ result.append(Repository(core.BNNewRepositoryReference(repos[i])))
core.BNFreeRepositoryManagerRepositoriesList(repos)
return result
@@ -239,160 +314,25 @@ class RepositoryManager(object):
def default_repository(self):
"""Gets the default Repository"""
binaryninja._init_plugins()
- return Repository(handle=core.BNRepositoryManagerGetDefaultRepository(self.handle))
-
- def enable_plugin(self, plugin, install=True, repo=None):
- """
- ``enable_plugin`` Enables the installed plugin 'plugin', optionally installing the plugin if `install` is set to
- True (default), and optionally using the non-default repository.
+ return Repository(core.BNNewRepositoryReference(core.BNRepositoryManagerGetDefaultRepository(self.handle)))
- :param str name: Name of the plugin to enable
- :param Boolean install: Optionally install the repo, defaults to True.
- :param str repo: Optional, specify a repository other than the default repository.
- :return: Boolean value True if the plugin was successfully enabled, False otherwise
- :rtype: Boolean
- :Example:
-
- >>> mgr = RepositoryManager()
- >>> mgr.enable_plugin('binaryninja-bookmarks')
- True
- >>>
- """
- if install:
- if not self.install_plugin(plugin, repo):
- return False
-
- if repo is None:
- repo = self.default_repository
- repopath = repo
- pluginpath = plugin
- if not isinstance(repo, str):
- repopath = repo.path
- if not isinstance(plugin, str):
- pluginpath = plugin.path
- return core.BNRepositoryManagerEnablePlugin(self.handle, repopath, pluginpath)
-
- def disable_plugin(self, plugin, repo=None):
- """
- ``disable_plugin`` Disable the specified plugin, pluginpath
-
- :param Repository or str repo: Repository containing the 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:
-
- >>> mgr = RepositoryManager()
- >>> mgr.disable_plugin('binaryninja-bookmarks')
- True
- >>>
- """
- if repo is None:
- repo = self.default_repository
- repopath = repo
- pluginpath = plugin
- if not isinstance(repo, str):
- repopath = repo.path
- if not isinstance(plugin, str):
- pluginpath = plugin.path
- return core.BNRepositoryManagerDisablePlugin(self.handle, repopath, pluginpath)
-
- def install_plugin(self, plugin, repo=None):
- """
- ``install_plugin`` install the specified plugin, pluginpath
-
- :param Repository or str repo: Repository containing the 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:
-
- >>> mgr = RepositoryManager()
- >>> mgr.install_plugin('binaryninja-bookmarks')
- True
- >>>
- """
- if repo is None:
- repo = self.default_repository
- repopath = repo
- pluginpath = plugin
- if not isinstance(repo, str):
- repopath = repo.path
- if not isinstance(plugin, str):
- pluginpath = plugin.path
- return core.BNRepositoryManagerInstallPlugin(self.handle, repopath, pluginpath)
-
- def uninstall_plugin(self, plugin, repo=None):
- """
- ``uninstall_plugin`` uninstall the specified plugin, pluginpath
-
- :param Repository or str repo: Repository containing the 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:
-
- >>> mgr = RepositoryManager()
- >>> mgr.uninstall_plugin('binaryninja-bookmarks')
- True
- >>>
- """
- if repo is None:
- repo = self.default_repository
- repopath = repo
- pluginpath = plugin
- if not isinstance(repo, str):
- repopath = repo.path
- if not isinstance(plugin, str):
- pluginpath = plugin.path
- return core.BNRepositoryManagerUninstallPlugin(self.handle, repopath, pluginpath)
-
- def update_plugin(self, plugin, repo=None):
- """
- ``update_plugin`` update the specified plugin, pluginpath
-
- :param Repository or str repo: Repository containing the 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:
-
- >>> mgr = RepositoryManager()
- >>> mgr.update_plugin('binaryninja-bookmarks')
- True
- >>>
- """
- if repo is None:
- repo = self.default_repository
- repopath = repo
- pluginpath = plugin
- if not isinstance(repo, str):
- repopath = repo.path
- if not isinstance(plugin, str):
- pluginpath = plugin.path
- return core.BNRepositoryManagerUpdatePlugin(self.handle, repopath, pluginpath)
- def add_repository(self, url=None, repopath=None, localreference="master", remotereference="origin"):
+ def add_repository(self, url=None, repopath=None):
"""
``add_repository`` adds a new plugin repository for the manager to track.
- :param str url: URL to the git repository where the plugins are stored.
+ :param str url: URL to the plugins.json containing the records for this repository
:param str repopath: path to where the repository will be stored on disk locally
- :param str localreference: Optional reference to the local tracking branch typically "master"
- :param str remotereference: Optional reference to the remote tracking branch typically "origin"
:return: Boolean value True if the repository was successfully added, False otherwise.
:rtype: Boolean
:Example:
>>> mgr = RepositoryManager()
- >>> mgr.add_repository(url="https://github.com/vector35/community-plugins.git",
- repopath="myrepo",
- localreference="master", remotereference="origin")
+ >>> mgr.add_repository("https://raw.githubusercontent.com/Vector35/community-plugins/master/plugins.json", "community")
True
>>>
"""
- if not (isinstance(url, str) and isinstance(repopath, str) and
- isinstance(localreference, str) and isinstance(remotereference, str)):
+ if not isinstance(url, str) or not isinstance(repopath, str):
raise ValueError("Parameter is incorrect type")
- return core.BNRepositoryManagerAddRepository(self.handle, url, repopath, localreference, remotereference)
+ return core.BNRepositoryManagerAddRepository(self.handle, url, repopath)
diff --git a/ui/uitypes.h b/ui/uitypes.h
index ed93d0c6..557063f3 100644
--- a/ui/uitypes.h
+++ b/ui/uitypes.h
@@ -58,3 +58,6 @@ typedef BinaryNinja::Ref<BinaryNinja::Symbol> SymbolRef;
typedef BinaryNinja::Ref<BinaryNinja::TemporaryFile> TemporaryFileRef;
typedef BinaryNinja::Ref<BinaryNinja::Transform> TransformRef;
typedef BinaryNinja::Ref<BinaryNinja::Type> TypeRef;
+typedef BinaryNinja::Ref<BinaryNinja::RepoPlugin> RepoPluginRef;
+typedef BinaryNinja::Ref<BinaryNinja::Repository> RepositoryRef;
+typedef BinaryNinja::Ref<BinaryNinja::RepositoryManager> RepositoryManagerRef;