Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6b711b4
[Rust] Provide setters useful for creating NTR references
emesare Jan 29, 2026
18f9b65
[Rust] Improve API surrounding binary view type libraries
emesare Jan 29, 2026
6eb4ee7
[Rust] Pass `type_reference` by ref to `TypeBuilder::named_type`
emesare Jan 29, 2026
43a3c6f
[Rust] Add `BinaryViewExt::type_libraries`
emesare Feb 5, 2026
96295e1
[Rust] Impl `Debug` for `BinaryViewType`
emesare Feb 5, 2026
6717f12
[Rust] Add `Symbol::ordinal`
emesare Feb 5, 2026
4057131
[Rust] Fix UB when passing include directories to `CoreTypeParser`
emesare Feb 5, 2026
a95533f
[Rust] Impl `Send` and `Sync` for `TypeLibrary`
emesare Feb 5, 2026
d2b0946
[Rust] Fix plugins being referenced in `cargo about` output
emesare Feb 6, 2026
7d33f6a
[Rust] Fix rust version in `binaryninja` crate being outdated
emesare Feb 6, 2026
dc37fc1
[Rust] Misc documentation improvements
emesare Feb 6, 2026
4a6e745
[Rust] Fix unbalanced ref returned in `RemoteFile::core_file`
emesare Feb 10, 2026
81cc330
[Rust] Impl `From<BnString>` for `QualifiedName`
emesare Feb 10, 2026
3201d5b
[Rust] Use `PathBuf` instead of `String` for include directories para…
emesare Feb 10, 2026
3bf24c5
[Rust] Fix clippy lints
emesare Feb 12, 2026
4a81036
[Rust] Impl `Debug` for `RemoteProject`
emesare Feb 10, 2026
b521436
[Rust] Impl `Debug` for `RemoteFolder`
emesare Feb 10, 2026
99d97b1
[Rust] Refactor `FileMetadata` file information
emesare Feb 12, 2026
a3e7fda
[Rust] Impl `Send` and `Sync` for `RemoteFile`
emesare Feb 12, 2026
4cefbd8
[Rust] Impl `Send` and `Sync` for `RemoteFolder`
emesare Feb 12, 2026
c2c66a3
[Rust] Impl `Send` and `Sync` for `RemoteProject`
emesare Feb 12, 2026
f86d035
[Rust] Add a precondition check to make sure metadata has been pulled…
emesare Feb 12, 2026
89dfe76
[Rust] Add `OwnedBackgroundTaskGuard` for finishing background task a…
emesare Feb 12, 2026
a9b281e
[Rust] Add `load_project_file` and `load_project_file_with_progress`
emesare Feb 18, 2026
4c89033
[Rust] Update allowed licenses
emesare Feb 12, 2026
6f37417
[Python] Add missing `TypeLibrary.duplicate` API
emesare Feb 14, 2026
27d4356
[BNTL] Add API to remove data
emesare Feb 15, 2026
69e9a4e
[Python] Add `TypeLibrary.remove_named_object` and `TypeLibrary.remov…
emesare Feb 14, 2026
01cce5d
[Rust] Misc TypeLibrary API improvements
emesare Feb 14, 2026
6094925
[Rust] Add `TypeLibrary::remove_named_object` and `TypeLibrary::remov…
emesare Feb 14, 2026
082fdfd
[BNTL] Allow decompressing standalone TypeLibrary objects
emesare Feb 18, 2026
4959d20
[Rust] Misc documentation cleanup
emesare Feb 18, 2026
b6e3148
Add BNTL utility plugin
emesare Feb 12, 2026
20407e2
[BNTL Utils] Fix misc clippy lints
emesare Feb 18, 2026
4b236da
[BNTL] Misc improvements
emesare Feb 19, 2026
4c5adeb
[Rust] Misc type library doc improvements
emesare Feb 19, 2026
ba9c3c5
[Rust] Fix `OwnedBackgroundTaskGuard` requiring mutable self
emesare Feb 19, 2026
b2ed663
[Rust] Ensure proper lifetime management of `WebsocketClientCallback`…
emesare Feb 20, 2026
d35ce9b
[Rust] Misc documentation and cleanup
emesare Feb 23, 2026
1b555c2
[BNTL] Misc improvements
emesare Feb 23, 2026
f041c02
Add global plugin command type
emesare Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
554 changes: 520 additions & 34 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ members = [
"plugins/warp/examples/headless",
"plugins/workflow_objc",
"plugins/workflow_objc/demo",
"plugins/bntl_utils",
"plugins/bntl_utils/cli",
]

[workspace.dependencies]
Expand Down
1 change: 1 addition & 0 deletions about.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ accepted = [
"LicenseRef-scancode-google-patent-license-fuchsia",
"MPL-2.0",
"LicenseRef-scancode-unknown-license-reference",
"BSD-2-Clause"
]
1 change: 1 addition & 0 deletions arch/msp430/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["jrozner"]
edition = "2021"
license = "Apache-2.0"
publish = false

[dependencies]
binaryninja.workspace = true
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Ryan Snyder <ryan.snyder.or@gmail.com>"]
edition = "2021"
license = "Apache-2.0"
publish = false

[dependencies]
binaryninja.workspace = true
Expand Down
100 changes: 83 additions & 17 deletions binaryninjaapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -16502,6 +16502,12 @@ namespace BinaryNinja {
{
BNPluginCommand m_command;

struct RegisteredGlobalCommand
{
std::function<void()> action;
std::function<bool()> isValid;
};

struct RegisteredDefaultCommand
{
std::function<void(BinaryView*)> action;
Expand Down Expand Up @@ -16568,6 +16574,7 @@ namespace BinaryNinja {
std::function<bool(Project*)> isValid;
};

static void GlobalPluginCommandActionCallback(void* ctxt);
static void DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view);
static void AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
static void RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
Expand All @@ -16586,6 +16593,7 @@ namespace BinaryNinja {
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
static void ProjectPluginCommandActionCallback(void* ctxt, BNProject* project);

static bool GlobalPluginCommandIsValidCallback(void* ctxt);
static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view);
static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
static bool RangePluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
Expand All @@ -16611,9 +16619,74 @@ namespace BinaryNinja {

PluginCommand& operator=(const PluginCommand& cmd);

/*! Register a command.

This will appear in the top menu.

\code{.cpp}

// Registering a command using a lambda expression
PluginCommand::RegisterGlobal("MyPlugin\\MyAction", "Perform an action", []() { });

// Registering a command using a standard static function
// This also works with functions in the global namespace, e.g. "void myCommand()"
void MyPlugin::MyCommand()
{
// Perform an action
}

PluginCommand::Register("MyPlugin\\MySecondAction", "Perform an action", MyPlugin::MyCommand);
\endcode

\param name
\parblock
Name of the command to register. This will appear in the top menu.

You can register submenus to an item by separating names with a \c "\\". The base (farthest right) name will
be the item which upon being clicked will perform the action.
\endparblock
\param description Description of the command
\param action Action to perform
*/
static void RegisterGlobal(const std::string& name, const std::string& description, const std::function<void()>& action);

/*! Register a command globally, with a validity check.

This will appear in the top menu.

\code{.cpp}

// Registering a command using lambda expressions
PluginCommand::Register("MyPlugin\\MyAction", "Perform an action", [](){ }, [](){ });

// Registering a command using a standard static function, and a lambda for the isValid check
// This also works with functions in the global namespace, e.g. "void myCommand()"
void MyPlugin::MyCommand(BinaryView* view)
{
// Perform an action
}

PluginCommand::Register("MyPlugin\\MySecondAction", "Perform an action", MyPlugin::MyCommand,
[](){ return true; });
\endcode

\param name
\parblock
Name of the command to register. This will appear in the top menu and the context menu.

You can register submenus to an item by separating names with a \c "\\". The base (farthest right) name will
be the item which upon being clicked will perform the action.
\endparblock
\param description Description of the command
\param action Action to perform
\param isValid Function that returns whether the command is allowed to be performed.
*/
static void RegisterGlobal(const std::string& name, const std::string& description,
const std::function<void()>& action, const std::function<bool()>& isValid);

/*! Register a command for a given BinaryView.

This will appear in the top menu and the right-click context menu.
This will appear in the top menu.

\code{.cpp}

Expand Down Expand Up @@ -16649,7 +16722,7 @@ namespace BinaryNinja {

/*! Register a command for a given BinaryView, with a validity check.

This will appear in the top menu and the right-click context menu.
This will appear in the top menu.

\code{.cpp}

Expand Down Expand Up @@ -19934,21 +20007,6 @@ namespace BinaryNinja {
*/
TypeLibrary(Ref<Architecture> arch, const std::string& name);

/*! Decompresses a type library from a file

\param path
\return The string contents of the decompressed type library
*/
std::string Decompress(const std::string& path);

/*! Decompresses a type library from a file

\param path
\param output
\return True if the type library was successfully decompressed
*/
static bool DecompressToFile(const std::string& path, const std::string& output);

/*! Loads a finalized type library instance from file

\param path
Expand Down Expand Up @@ -19976,9 +20034,17 @@ namespace BinaryNinja {
/*! Saves a finalized type library instance to file

\param path
\return True if the type library was successfully written to the file
*/
bool WriteToFile(const std::string& path);

/*! Decompresses the type library to a JSON file

\param path
\return True if the type library was successfully decompressed
*/
bool DecompressToFile(const std::string& path);

/*! The Architecture this type library is associated with

\return
Expand Down
17 changes: 13 additions & 4 deletions binaryninjacore.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
#define BN_CURRENT_CORE_ABI_VERSION 157
#define BN_CURRENT_CORE_ABI_VERSION 158

// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
// will require rebuilding. The minimum version is increased when there are
// incompatible changes that break binary compatibility, such as changes to
// existing types or functions.
#define BN_MINIMUM_CORE_ABI_VERSION 157
#define BN_MINIMUM_CORE_ABI_VERSION 158

#ifdef __GNUC__
#ifdef BINARYNINJACORE_LIBRARY
Expand Down Expand Up @@ -2784,7 +2784,8 @@ extern "C"
MediumLevelILInstructionPluginCommand,
HighLevelILFunctionPluginCommand,
HighLevelILInstructionPluginCommand,
ProjectPluginCommand
ProjectPluginCommand,
GlobalPluginCommand
};

typedef struct BNPluginCommand
Expand All @@ -2794,6 +2795,7 @@ extern "C"
BNPluginCommandType type;
void* context;

void (*globalCommand)(void* ctxt);
void (*defaultCommand)(void* ctxt, BNBinaryView* view);
void (*addressCommand)(void* ctxt, BNBinaryView* view, uint64_t addr);
void (*rangeCommand)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
Expand All @@ -2808,6 +2810,7 @@ extern "C"
void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
void (*projectCommand)(void* ctxt, BNProject* view);

bool (*globalIsValid)(void* ctxt);
bool (*defaultIsValid)(void* ctxt, BNBinaryView* view);
bool (*addressIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr);
bool (*rangeIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
Expand Down Expand Up @@ -6816,7 +6819,7 @@ extern "C"
BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibraryReference(BNTypeLibrary* lib);
BINARYNINJACOREAPI BNTypeLibrary* BNDuplicateTypeLibrary(BNTypeLibrary* lib);
BINARYNINJACOREAPI BNTypeLibrary* BNLoadTypeLibraryFromFile(const char* path);
BINARYNINJACOREAPI bool BNTypeLibraryDecompressToFile(const char* file, const char* output);
BINARYNINJACOREAPI bool BNTypeLibraryDecompressToFile(BNTypeLibrary* lib, const char* output);
BINARYNINJACOREAPI void BNFreeTypeLibrary(BNTypeLibrary* lib);

BINARYNINJACOREAPI BNTypeLibrary* BNLookupTypeLibraryByName(BNArchitecture* arch, const char* name);
Expand Down Expand Up @@ -6853,11 +6856,14 @@ extern "C"
BINARYNINJACOREAPI BNTypeContainer* BNGetTypeLibraryTypeContainer(BNTypeLibrary* lib);

BINARYNINJACOREAPI void BNAddTypeLibraryNamedObject(BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
BINARYNINJACOREAPI void BNRemoveTypeLibraryNamedObject(BNTypeLibrary* lib, BNQualifiedName* name);
BINARYNINJACOREAPI void BNAddTypeLibraryNamedType(BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
BINARYNINJACOREAPI void BNRemoveTypeLibraryNamedType(BNTypeLibrary* lib, BNQualifiedName* name);
BINARYNINJACOREAPI void BNAddTypeLibraryNamedTypeSource(BNTypeLibrary* lib, BNQualifiedName* name, const char* source);

BINARYNINJACOREAPI BNType* BNGetTypeLibraryNamedObject(BNTypeLibrary* lib, BNQualifiedName* name);
BINARYNINJACOREAPI BNType* BNGetTypeLibraryNamedType(BNTypeLibrary* lib, BNQualifiedName* name);
BINARYNINJACOREAPI char* BNGetTypeLibraryNamedTypeSource(BNTypeLibrary* lib, BNQualifiedName* name);

BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetTypeLibraryNamedObjects(BNTypeLibrary* lib, size_t* count);
BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetTypeLibraryNamedTypes(BNTypeLibrary* lib, size_t* count);
Expand Down Expand Up @@ -7423,6 +7429,8 @@ extern "C"
BINARYNINJACOREAPI void BNInstallPendingUpdate(char** errors);

// Plugin commands
BINARYNINJACOREAPI void BNRegisterPluginCommandGlobal(const char* name, const char* description,
void (*action)(void* ctxt), bool (*isValid)(void* ctxt), void* context);
BINARYNINJACOREAPI void BNRegisterPluginCommand(const char* name, const char* description,
void (*action)(void* ctxt, BNBinaryView* view), bool (*isValid)(void* ctxt, BNBinaryView* view), void* context);
BINARYNINJACOREAPI void BNRegisterPluginCommandForAddress(const char* name, const char* description,
Expand Down Expand Up @@ -7457,6 +7465,7 @@ extern "C"
void (*action)(void* ctxt, BNProject* project), bool (*isValid)(void* ctxt, BNProject* project), void* context);

BINARYNINJACOREAPI BNPluginCommand* BNGetAllPluginCommands(size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsGlobal(size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommands(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForAddress(
BNBinaryView* view, uint64_t addr, size_t* count);
Expand Down
38 changes: 38 additions & 0 deletions plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ PluginCommand& PluginCommand::operator=(const PluginCommand& cmd)
}


void PluginCommand::GlobalPluginCommandActionCallback(void* ctxt)
{
RegisteredGlobalCommand* cmd = (RegisteredGlobalCommand*)ctxt;
cmd->action();
}


void PluginCommand::DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view)
{
RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
Expand Down Expand Up @@ -172,6 +179,13 @@ void PluginCommand::ProjectPluginCommandActionCallback(void *ctxt, BNProject* pr
}


bool PluginCommand::GlobalPluginCommandIsValidCallback(void* ctxt)
{
RegisteredGlobalCommand* cmd = (RegisteredGlobalCommand*)ctxt;
return cmd->isValid();
}


bool PluginCommand::DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view)
{
RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
Expand Down Expand Up @@ -276,6 +290,23 @@ bool PluginCommand::ProjectPluginCommandIsValidCallback(void* ctxt, BNProject* p
}


void PluginCommand::RegisterGlobal(const string& name, const string& description, const function<void()>& action)
{
RegisterGlobal(name, description, action, []() { return true; });
}


void PluginCommand::RegisterGlobal(const string& name, const string& description,
const function<void()>& action, const function<bool()>& isValid)
{
RegisteredGlobalCommand* cmd = new RegisteredGlobalCommand;
cmd->action = action;
cmd->isValid = isValid;
BNRegisterPluginCommandGlobal(name.c_str(), description.c_str(), GlobalPluginCommandActionCallback,
GlobalPluginCommandIsValidCallback, cmd);
}


void PluginCommand::Register(
const string& name, const string& description, const function<void(BinaryView* view)>& action)
{
Expand Down Expand Up @@ -515,6 +546,10 @@ bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
{
switch (m_command.type)
{
case GlobalPluginCommand:
if (!m_command.globalIsValid)
return true;
return m_command.globalIsValid(m_command.context);
case DefaultPluginCommand:
if (!ctxt.binaryView)
return false;
Expand Down Expand Up @@ -606,6 +641,9 @@ void PluginCommand::Execute(const PluginCommandContext& ctxt) const

switch (m_command.type)
{
case GlobalPluginCommand:
m_command.globalCommand(m_command.context);
break;
case DefaultPluginCommand:
m_command.defaultCommand(m_command.context, ctxt.binaryView->GetObject());
break;
Expand Down
Loading
Loading