Skip to content

Commit ba6d081

Browse files
committed
Add PluginCommand for projects and hide non-contextual commands in linear/graph view
1 parent 00686df commit ba6d081

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
@@ -14757,6 +14757,7 @@ namespace BinaryNinja {
1475714757
Ref<LowLevelILFunction> lowLevelILFunction;
1475814758
Ref<MediumLevelILFunction> mediumLevelILFunction;
1475914759
Ref<HighLevelILFunction> highLevelILFunction;
14760+
Ref<Project> project;
1476014761

1476114762
PluginCommandContext();
1476214763
};
@@ -14833,6 +14834,12 @@ namespace BinaryNinja {
1483314834
std::function<bool(BinaryView*, const HighLevelILInstruction&)> isValid;
1483414835
};
1483514836

14837+
struct RegisteredProjectCommand
14838+
{
14839+
std::function<void(Project*)> action;
14840+
std::function<bool(Project*)> isValid;
14841+
};
14842+
1483614843
static void DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view);
1483714844
static void AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
1483814845
static void RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
@@ -14849,6 +14856,7 @@ namespace BinaryNinja {
1484914856
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
1485014857
static void HighLevelILInstructionPluginCommandActionCallback(
1485114858
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
14859+
static void ProjectPluginCommandActionCallback(void* ctxt, BNProject* project);
1485214860

1485314861
static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view);
1485414862
static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
@@ -14866,6 +14874,7 @@ namespace BinaryNinja {
1486614874
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
1486714875
static bool HighLevelILInstructionPluginCommandIsValidCallback(
1486814876
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
14877+
static bool ProjectPluginCommandIsValidCallback(void* ctxt, BNProject* project);
1486914878

1487014879
public:
1487114880
PluginCommand(const BNPluginCommand& cmd);
@@ -15692,6 +15701,13 @@ namespace BinaryNinja {
1569215701
const std::function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action,
1569315702
const std::function<bool(BinaryView* view, const HighLevelILInstruction& instr)>& isValid);
1569415703

15704+
static void RegisterForProject(const std::string& name, const std::string& description,
15705+
const std::function<void(Project* project)>& action);
15706+
15707+
static void RegisterForProject(const std::string& name, const std::string& description,
15708+
const std::function<void(Project* project)>& action,
15709+
const std::function<bool(Project* project)>& isValid);
15710+
1569515711
/*! Get the list of registered PluginCommands
1569615712

1569715713
\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
@@ -6987,6 +6990,8 @@ extern "C"
69876990
BINARYNINJACOREAPI void BNRegisterPluginCommandForHighLevelILInstruction(const char* name, const char* description,
69886991
void (*action)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr),
69896992
bool (*isValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr), void* context);
6993+
BINARYNINJACOREAPI void BNRegisterPluginCommandForProject(const char* name, const char* description,
6994+
void (*action)(void* ctxt, BNProject* project), bool (*isValid)(void* ctxt, BNProject* project), void* context);
69906995

69916996
BINARYNINJACOREAPI BNPluginCommand* BNGetAllPluginCommands(size_t* count);
69926997
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommands(BNBinaryView* view, size_t* count);
@@ -7008,6 +7013,7 @@ extern "C"
70087013
BNBinaryView* view, BNHighLevelILFunction* func, size_t* count);
70097014
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForHighLevelILInstruction(
70107015
BNBinaryView* view, BNHighLevelILFunction* func, size_t instr, size_t* count);
7016+
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForProject(BNProject* project, size_t* count);
70117017
BINARYNINJACOREAPI void BNFreePluginCommandList(BNPluginCommand* commands);
70127018

70137019
// 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)