summaryrefslogtreecommitdiff
path: root/plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.cpp')
-rw-r--r--plugin.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/plugin.cpp b/plugin.cpp
new file mode 100644
index 00000000..f7f287b0
--- /dev/null
+++ b/plugin.cpp
@@ -0,0 +1,259 @@
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+
+PluginCommandContext::PluginCommandContext()
+{
+ address = length = 0;
+}
+
+
+PluginCommand::PluginCommand(const BNPluginCommand& cmd)
+{
+ m_command = cmd;
+ m_command.name = BNAllocString(cmd.name);
+ m_command.description = BNAllocString(cmd.description);
+}
+
+
+PluginCommand::PluginCommand(const PluginCommand& cmd)
+{
+ m_command = cmd.m_command;
+ m_command.name = BNAllocString(cmd.m_command.name);
+ m_command.description = BNAllocString(cmd.m_command.description);
+}
+
+
+PluginCommand::~PluginCommand()
+{
+ BNFreeString(m_command.name);
+ BNFreeString(m_command.description);
+}
+
+
+void PluginCommand::DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view)
+{
+ RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ cmd->action(viewObject);
+}
+
+
+void PluginCommand::AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr)
+{
+ RegisteredAddressCommand* cmd = (RegisteredAddressCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ cmd->action(viewObject, addr);
+}
+
+
+void PluginCommand::RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len)
+{
+ RegisteredRangeCommand* cmd = (RegisteredRangeCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ cmd->action(viewObject, addr, len);
+}
+
+
+void PluginCommand::FunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view, BNFunction* func)
+{
+ RegisteredFunctionCommand* cmd = (RegisteredFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<Function> funcObject = new Function(BNNewFunctionReference(func));
+ cmd->action(viewObject, funcObject);
+}
+
+
+bool PluginCommand::DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view)
+{
+ RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ return cmd->isValid(viewObject);
+}
+
+
+bool PluginCommand::AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr)
+{
+ RegisteredAddressCommand* cmd = (RegisteredAddressCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ return cmd->isValid(viewObject, addr);
+}
+
+
+bool PluginCommand::RangePluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len)
+{
+ RegisteredRangeCommand* cmd = (RegisteredRangeCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ return cmd->isValid(viewObject, addr, len);
+}
+
+
+bool PluginCommand::FunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, BNFunction* func)
+{
+ RegisteredFunctionCommand* cmd = (RegisteredFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<Function> funcObject = new Function(BNNewFunctionReference(func));
+ return cmd->isValid(viewObject, funcObject);
+}
+
+
+void PluginCommand::Register(const string& name, const string& description,
+ const function<void(BinaryView* view)>& action)
+{
+ Register(name, description, action, [](BinaryView*) { return true; });
+}
+
+
+void PluginCommand::Register(const string& name, const string& description,
+ const function<void(BinaryView* view)>& action,
+ const function<bool(BinaryView* view)>& isValid)
+{
+ RegisteredDefaultCommand* cmd = new RegisteredDefaultCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommand(name.c_str(), description.c_str(), DefaultPluginCommandActionCallback,
+ DefaultPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForAddress(const string& name, const string& description,
+ const function<void(BinaryView* view, uint64_t addr)>& action)
+{
+ RegisterForAddress(name, description, action, [](BinaryView*, uint64_t) { return true; });
+}
+
+
+void PluginCommand::RegisterForAddress(const string& name, const string& description,
+ const function<void(BinaryView* view, uint64_t addr)>& action,
+ const function<bool(BinaryView* view, uint64_t addr)>& isValid)
+{
+ RegisteredAddressCommand* cmd = new RegisteredAddressCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForAddress(name.c_str(), description.c_str(), AddressPluginCommandActionCallback,
+ AddressPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForRange(const string& name, const string& description,
+ const function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action)
+{
+ RegisterForRange(name, description, action, [](BinaryView*, uint64_t, uint64_t) { return true; });
+}
+
+
+void PluginCommand::RegisterForRange(const string& name, const string& description,
+ const function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action,
+ const function<bool(BinaryView* view, uint64_t addr, uint64_t len)>& isValid)
+{
+ RegisteredRangeCommand* cmd = new RegisteredRangeCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForRange(name.c_str(), description.c_str(), RangePluginCommandActionCallback,
+ RangePluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, Function* func)>& action)
+{
+ RegisterForFunction(name, description, action, [](BinaryView*, Function*) { return true; });
+}
+
+
+void PluginCommand::RegisterForFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, Function* func)>& action,
+ const function<bool(BinaryView* view, Function* func)>& isValid)
+{
+ RegisteredFunctionCommand* cmd = new RegisteredFunctionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForFunction(name.c_str(), description.c_str(), FunctionPluginCommandActionCallback,
+ FunctionPluginCommandIsValidCallback, cmd);
+}
+
+
+vector<PluginCommand> PluginCommand::GetList()
+{
+ vector<PluginCommand> result;
+ size_t count;
+ BNPluginCommand* commands = BNGetAllPluginCommands(&count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(PluginCommand(commands[i]));
+ BNFreePluginCommandList(commands);
+ return result;
+}
+
+
+vector<PluginCommand> PluginCommand::GetValidList(const PluginCommandContext& ctxt)
+{
+ vector<PluginCommand> commands = GetList();
+ vector<PluginCommand> result;
+ for (auto& i : commands)
+ {
+ if (i.IsValid(ctxt))
+ result.push_back(i);
+ }
+ return result;
+}
+
+
+bool PluginCommand::IsValid(const PluginCommandContext& ctxt)
+{
+ if (!ctxt.view)
+ return false;
+
+ switch (m_command.type)
+ {
+ case DefaultPluginCommand:
+ if (!m_command.defaultIsValid)
+ return true;
+ return m_command.defaultIsValid(m_command.context, ctxt.view->GetViewObject());
+ case AddressPluginCommand:
+ if (!m_command.addressIsValid)
+ return true;
+ return m_command.addressIsValid(m_command.context, ctxt.view->GetViewObject(), ctxt.address);
+ case RangePluginCommand:
+ if (ctxt.length == 0)
+ return false;
+ if (!m_command.rangeIsValid)
+ return true;
+ return m_command.rangeIsValid(m_command.context, ctxt.view->GetViewObject(), ctxt.address, ctxt.length);
+ case FunctionPluginCommand:
+ if (!ctxt.function)
+ return false;
+ if (!m_command.functionIsValid)
+ return true;
+ return m_command.functionIsValid(m_command.context, ctxt.view->GetViewObject(),
+ ctxt.function->GetFunctionObject());
+ default:
+ return false;
+ }
+}
+
+
+void PluginCommand::Execute(const PluginCommandContext& ctxt)
+{
+ if (!IsValid(ctxt))
+ return;
+
+ switch (m_command.type)
+ {
+ case DefaultPluginCommand:
+ m_command.defaultCommand(m_command.context, ctxt.view->GetViewObject());
+ break;
+ case AddressPluginCommand:
+ m_command.addressCommand(m_command.context, ctxt.view->GetViewObject(), ctxt.address);
+ break;
+ case RangePluginCommand:
+ m_command.rangeCommand(m_command.context, ctxt.view->GetViewObject(), ctxt.address, ctxt.length);
+ break;
+ case FunctionPluginCommand:
+ m_command.functionCommand(m_command.context, ctxt.view->GetViewObject(), ctxt.function->GetFunctionObject());
+ break;
+ default:
+ break;
+ }
+}