Skip to content

Commit 36888c5

Browse files
committed
Add PluginCommand for projects and hide non-contextual commands in linear/graph view
1 parent 45e8f93 commit 36888c5

File tree

7 files changed

+220
-30
lines changed

7 files changed

+220
-30
lines changed

binaryninjaapi.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14741,6 +14741,7 @@ namespace BinaryNinja {
1474114741
Ref<LowLevelILFunction> lowLevelILFunction;
1474214742
Ref<MediumLevelILFunction> mediumLevelILFunction;
1474314743
Ref<HighLevelILFunction> highLevelILFunction;
14744+
Ref<Project> project;
1474414745

1474514746
PluginCommandContext();
1474614747
};
@@ -14817,6 +14818,12 @@ namespace BinaryNinja {
1481714818
std::function<bool(BinaryView*, const HighLevelILInstruction&)> isValid;
1481814819
};
1481914820

14821+
struct RegisteredProjectCommand
14822+
{
14823+
std::function<void(Project*)> action;
14824+
std::function<bool(Project*)> isValid;
14825+
};
14826+
1482014827
static void DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view);
1482114828
static void AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
1482214829
static void RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
@@ -14833,6 +14840,7 @@ namespace BinaryNinja {
1483314840
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
1483414841
static void HighLevelILInstructionPluginCommandActionCallback(
1483514842
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
14843+
static void ProjectPluginCommandActionCallback(void* ctxt, BNProject* project);
1483614844

1483714845
static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view);
1483814846
static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
@@ -14850,6 +14858,7 @@ namespace BinaryNinja {
1485014858
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
1485114859
static bool HighLevelILInstructionPluginCommandIsValidCallback(
1485214860
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
14861+
static bool ProjectPluginCommandIsValidCallback(void* ctxt, BNProject* project);
1485314862

1485414863
public:
1485514864
PluginCommand(const BNPluginCommand& cmd);
@@ -15676,6 +15685,13 @@ namespace BinaryNinja {
1567615685
const std::function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action,
1567715686
const std::function<bool(BinaryView* view, const HighLevelILInstruction& instr)>& isValid);
1567815687

15688+
static void RegisterForProject(const std::string& name, const std::string& description,
15689+
const std::function<void(Project* project)>& action);
15690+
15691+
static void RegisterForProject(const std::string& name, const std::string& description,
15692+
const std::function<void(Project* project)>& action,
15693+
const std::function<bool(Project* project)>& isValid);
15694+
1567915695
/*! Get the list of registered PluginCommands
1568015696

1568115697
\return The list of registered PluginCommands

binaryninjacore.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2593,7 +2593,8 @@ extern "C"
25932593
MediumLevelILFunctionPluginCommand,
25942594
MediumLevelILInstructionPluginCommand,
25952595
HighLevelILFunctionPluginCommand,
2596-
HighLevelILInstructionPluginCommand
2596+
HighLevelILInstructionPluginCommand,
2597+
ProjectPluginCommand
25972598
} BNPluginCommandType;
25982599

25992600
typedef struct BNPluginCommand
@@ -2615,6 +2616,7 @@ extern "C"
26152616
void (*highLevelILFunctionCommand)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
26162617
void (*highLevelILInstructionCommand)(
26172618
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
2619+
void (*projectCommand)(void* ctxt, BNProject* view);
26182620

26192621
bool (*defaultIsValid)(void* ctxt, BNBinaryView* view);
26202622
bool (*addressIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr);
@@ -2628,6 +2630,7 @@ extern "C"
26282630
bool (*highLevelILFunctionIsValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
26292631
bool (*highLevelILInstructionIsValid)(
26302632
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
2633+
bool (*projectIsValid)(void* ctxt, BNProject* view);
26312634
} BNPluginCommand;
26322635

26332636
typedef struct BNCustomCallingConvention
@@ -6973,6 +6976,8 @@ extern "C"
69736976
BINARYNINJACOREAPI void BNRegisterPluginCommandForHighLevelILInstruction(const char* name, const char* description,
69746977
void (*action)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr),
69756978
bool (*isValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr), void* context);
6979+
BINARYNINJACOREAPI void BNRegisterPluginCommandForProject(const char* name, const char* description,
6980+
void (*action)(void* ctxt, BNProject* project), bool (*isValid)(void* ctxt, BNProject* project), void* context);
69766981

69776982
BINARYNINJACOREAPI BNPluginCommand* BNGetAllPluginCommands(size_t* count);
69786983
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommands(BNBinaryView* view, size_t* count);
@@ -6994,6 +6999,7 @@ extern "C"
69946999
BNBinaryView* view, BNHighLevelILFunction* func, size_t* count);
69957000
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForHighLevelILInstruction(
69967001
BNBinaryView* view, BNHighLevelILFunction* func, size_t instr, size_t* count);
7002+
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForProject(BNProject* project, size_t* count);
69977003
BINARYNINJACOREAPI void BNFreePluginCommandList(BNPluginCommand* commands);
69987004

69997005
// Calling conventions

plugin.cpp

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ void PluginCommand::HighLevelILInstructionPluginCommandActionCallback(
164164
}
165165

166166

167+
void PluginCommand::ProjectPluginCommandActionCallback(void *ctxt, BNProject* project)
168+
{
169+
RegisteredProjectCommand* cmd = (RegisteredProjectCommand*)ctxt;
170+
Ref<Project> projectObject = new Project(BNNewProjectReference(project));
171+
return cmd->action(projectObject);
172+
}
173+
174+
167175
bool PluginCommand::DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view)
168176
{
169177
RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
@@ -260,6 +268,14 @@ bool PluginCommand::HighLevelILInstructionPluginCommandIsValidCallback(
260268
}
261269

262270

271+
bool PluginCommand::ProjectPluginCommandIsValidCallback(void* ctxt, BNProject* project)
272+
{
273+
RegisteredProjectCommand* cmd = (RegisteredProjectCommand*)ctxt;
274+
Ref<Project> projectObject = new Project(BNNewProjectReference(project));
275+
return cmd->isValid(projectObject);
276+
}
277+
278+
263279
void PluginCommand::Register(
264280
const string& name, const string& description, const function<void(BinaryView* view)>& action)
265281
{
@@ -452,6 +468,22 @@ void PluginCommand::RegisterForHighLevelILInstruction(const string& name, const
452468
HighLevelILInstructionPluginCommandActionCallback, HighLevelILInstructionPluginCommandIsValidCallback, cmd);
453469
}
454470

471+
void PluginCommand::RegisterForProject(const std::string &name, const std::string &description,
472+
const std::function<void(Project *project)> &action)
473+
{
474+
RegisterForProject(name, description, action, [](Project*) { return true; });
475+
}
476+
477+
void PluginCommand::RegisterForProject(const std::string &name, const std::string &description,
478+
const std::function<void(Project* project)> &action, const std::function<bool(Project* project)> &isValid)
479+
{
480+
RegisteredProjectCommand* cmd = new RegisteredProjectCommand;
481+
cmd->action = action;
482+
cmd->isValid = isValid;
483+
BNRegisterPluginCommandForProject(name.c_str(), description.c_str(), ProjectPluginCommandActionCallback,
484+
ProjectPluginCommandIsValidCallback, cmd);
485+
}
486+
455487

456488
vector<PluginCommand> PluginCommand::GetList()
457489
{
@@ -481,40 +513,41 @@ vector<PluginCommand> PluginCommand::GetValidList(const PluginCommandContext& ct
481513

482514
bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
483515
{
484-
if (!ctxt.binaryView)
485-
return false;
486-
487516
switch (m_command.type)
488517
{
489518
case DefaultPluginCommand:
519+
if (!ctxt.binaryView)
520+
return false;
490521
if (!m_command.defaultIsValid)
491522
return true;
492523
return m_command.defaultIsValid(m_command.context, ctxt.binaryView->GetObject());
493524
case AddressPluginCommand:
525+
if (!ctxt.binaryView)
526+
return false;
494527
if (!m_command.addressIsValid)
495528
return true;
496529
return m_command.addressIsValid(m_command.context, ctxt.binaryView->GetObject(), ctxt.address);
497530
case RangePluginCommand:
498-
if (ctxt.length == 0)
531+
if (ctxt.length == 0 || !ctxt.binaryView)
499532
return false;
500533
if (!m_command.rangeIsValid)
501534
return true;
502535
return m_command.rangeIsValid(m_command.context, ctxt.binaryView->GetObject(), ctxt.address, ctxt.length);
503536
case FunctionPluginCommand:
504-
if (!ctxt.function)
537+
if (!ctxt.function || !ctxt.binaryView)
505538
return false;
506539
if (!m_command.functionIsValid)
507540
return true;
508541
return m_command.functionIsValid(m_command.context, ctxt.binaryView->GetObject(), ctxt.function->GetObject());
509542
case LowLevelILFunctionPluginCommand:
510-
if (!ctxt.lowLevelILFunction)
543+
if (!ctxt.lowLevelILFunction || !ctxt.binaryView)
511544
return false;
512545
if (!m_command.lowLevelILFunctionIsValid)
513546
return true;
514547
return m_command.lowLevelILFunctionIsValid(
515548
m_command.context, ctxt.binaryView->GetObject(), ctxt.lowLevelILFunction->GetObject());
516549
case LowLevelILInstructionPluginCommand:
517-
if (!ctxt.lowLevelILFunction)
550+
if (!ctxt.lowLevelILFunction || !ctxt.binaryView)
518551
return false;
519552
if (ctxt.instrIndex == BN_INVALID_EXPR)
520553
return false;
@@ -523,14 +556,14 @@ bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
523556
return m_command.lowLevelILInstructionIsValid(
524557
m_command.context, ctxt.binaryView->GetObject(), ctxt.lowLevelILFunction->GetObject(), ctxt.instrIndex);
525558
case MediumLevelILFunctionPluginCommand:
526-
if (!ctxt.mediumLevelILFunction)
559+
if (!ctxt.mediumLevelILFunction || !ctxt.binaryView)
527560
return false;
528561
if (!m_command.mediumLevelILFunctionIsValid)
529562
return true;
530563
return m_command.mediumLevelILFunctionIsValid(
531564
m_command.context, ctxt.binaryView->GetObject(), ctxt.mediumLevelILFunction->GetObject());
532565
case MediumLevelILInstructionPluginCommand:
533-
if (!ctxt.mediumLevelILFunction)
566+
if (!ctxt.mediumLevelILFunction || !ctxt.binaryView)
534567
return false;
535568
if (ctxt.instrIndex == BN_INVALID_EXPR)
536569
return false;
@@ -539,21 +572,27 @@ bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
539572
return m_command.mediumLevelILInstructionIsValid(
540573
m_command.context, ctxt.binaryView->GetObject(), ctxt.mediumLevelILFunction->GetObject(), ctxt.instrIndex);
541574
case HighLevelILFunctionPluginCommand:
542-
if (!ctxt.highLevelILFunction)
575+
if (!ctxt.highLevelILFunction || !ctxt.binaryView)
543576
return false;
544577
if (!m_command.highLevelILFunctionIsValid)
545578
return true;
546579
return m_command.highLevelILFunctionIsValid(
547580
m_command.context, ctxt.binaryView->GetObject(), ctxt.highLevelILFunction->GetObject());
548581
case HighLevelILInstructionPluginCommand:
549-
if (!ctxt.highLevelILFunction)
582+
if (!ctxt.highLevelILFunction || !ctxt.binaryView)
550583
return false;
551584
if (ctxt.instrIndex == BN_INVALID_EXPR)
552585
return false;
553586
if (!m_command.highLevelILInstructionIsValid)
554587
return true;
555588
return m_command.highLevelILInstructionIsValid(
556589
m_command.context, ctxt.binaryView->GetObject(), ctxt.highLevelILFunction->GetObject(), ctxt.instrIndex);
590+
case ProjectPluginCommand:
591+
if (!m_command.projectIsValid)
592+
return true;
593+
if (!ctxt.project)
594+
return false;
595+
return m_command.projectIsValid(m_command.context, ctxt.project->GetObject());
557596
default:
558597
return false;
559598
}
@@ -603,6 +642,9 @@ void PluginCommand::Execute(const PluginCommandContext& ctxt) const
603642
m_command.highLevelILInstructionCommand(
604643
m_command.context, ctxt.binaryView->GetObject(), ctxt.highLevelILFunction->GetObject(), ctxt.instrIndex);
605644
break;
645+
case ProjectPluginCommand:
646+
m_command.projectCommand(m_command.context, ctxt.project->GetObject());
647+
break;
606648
default:
607649
break;
608650
}

0 commit comments

Comments
 (0)