diff options
| author | Rusty Wagner <rusty@vector35.com> | 2021-01-25 16:45:06 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2021-01-27 18:39:42 -0500 |
| commit | 12f916450b444427685688bf34de65e11bf849e2 (patch) | |
| tree | bd13651d872c1fc7ad5933e9a38a77da82235cd3 | |
| parent | 51d0f18eb4df16263867ef157b5293bb1b44f77a (diff) | |
Add ABI version verification for plugins
| -rw-r--r-- | binaryninjacore.h | 32 | ||||
| -rw-r--r-- | examples/breakpoint/src/breakpoint.cpp | 2 | ||||
| -rw-r--r-- | examples/triage/triage.cpp | 2 | ||||
| -rw-r--r-- | examples/uinotification/uinotification.cpp | 2 | ||||
| -rw-r--r-- | examples/x86_extension/src/x86_extension.cpp | 2 | ||||
| -rw-r--r-- | rust/binaryninjacore-sys/build.rs | 2 | ||||
| -rw-r--r-- | rust/src/lib.rs | 22 | ||||
| -rw-r--r-- | ui/uicontext.h | 1 | ||||
| -rw-r--r-- | ui/uitypes.h | 28 |
9 files changed, 93 insertions, 0 deletions
diff --git a/binaryninjacore.h b/binaryninjacore.h index f28b6a0a..a857bd79 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -25,6 +25,18 @@ #include <stddef.h> #include <stdlib.h> +// 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 1 + +// 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 1 + #ifdef __GNUC__ # ifdef BINARYNINJACORE_LIBRARY # define BINARYNINJACOREAPI __attribute__((visibility("default"))) @@ -100,6 +112,23 @@ #define DEFAULT_INTERNAL_NAMESPACE "BNINTERNALNAMESPACE" #define DEFAULT_EXTERNAL_NAMESPACE "BNEXTERNALNAMESPACE" + +// The BN_DECLARE_CORE_ABI_VERSION must be included in native plugin modules. If +// the ABI version is not declared, the core will not load the plugin. +#ifdef DEMO_VERSION +#define BN_DECLARE_CORE_ABI_VERSION +#else +#define BN_DECLARE_CORE_ABI_VERSION \ + extern "C" \ + { \ + BINARYNINJAPLUGIN uint32_t CorePluginABIVersion() \ + { \ + return BN_CURRENT_CORE_ABI_VERSION; \ + } \ + } +#endif + + #ifdef __cplusplus extern "C" { @@ -119,6 +148,7 @@ extern "C" typedef bool (*BNCorePluginInitFunction)(void); typedef void (*BNCorePluginDependencyFunction)(void); + typedef uint32_t (*BNCorePluginABIVersionFunction)(void); struct BNDataBuffer; struct BNBinaryView; @@ -2459,6 +2489,8 @@ extern "C" BINARYNINJACOREAPI char* BNGetVersionString(void); BINARYNINJACOREAPI uint32_t BNGetBuildId(void); + BINARYNINJACOREAPI uint32_t BNGetCurrentCoreABIVersion(void); + BINARYNINJACOREAPI uint32_t BNGetMinimumCoreABIVersion(void); BINARYNINJACOREAPI char* BNGetSerialNumber(void); BINARYNINJACOREAPI uint64_t BNGetLicenseExpirationTime(void); diff --git a/examples/breakpoint/src/breakpoint.cpp b/examples/breakpoint/src/breakpoint.cpp index 4fac98ac..65c8d018 100644 --- a/examples/breakpoint/src/breakpoint.cpp +++ b/examples/breakpoint/src/breakpoint.cpp @@ -25,6 +25,8 @@ void write_breakpoint(BinaryNinja::BinaryView *view, uint64_t start, uint64_t le extern "C" { + BN_DECLARE_CORE_ABI_VERSION + BINARYNINJAPLUGIN bool CorePluginInit() { // Register the plugin with Binary Ninja diff --git a/examples/triage/triage.cpp b/examples/triage/triage.cpp index efd4b80c..5d0dc1d5 100644 --- a/examples/triage/triage.cpp +++ b/examples/triage/triage.cpp @@ -6,6 +6,8 @@ extern "C" { + BN_DECLARE_UI_ABI_VERSION + #ifdef DEMO_VERSION bool TriagePluginInit() #else diff --git a/examples/uinotification/uinotification.cpp b/examples/uinotification/uinotification.cpp index ca53c560..91e9b458 100644 --- a/examples/uinotification/uinotification.cpp +++ b/examples/uinotification/uinotification.cpp @@ -93,6 +93,8 @@ void NotificationListener::OnAddressChange(UIContext* context, ViewFrame* frame, extern "C" { + BN_DECLARE_UI_ABI_VERSION + BINARYNINJAPLUGIN bool UIPluginInit() { NotificationListener::init(); diff --git a/examples/x86_extension/src/x86_extension.cpp b/examples/x86_extension/src/x86_extension.cpp index 87f2c2cb..ada7c801 100644 --- a/examples/x86_extension/src/x86_extension.cpp +++ b/examples/x86_extension/src/x86_extension.cpp @@ -47,6 +47,8 @@ public: extern "C" { + BN_DECLARE_CORE_ABI_VERSION + BINARYNINJAPLUGIN void CorePluginDependencies() { // Make sure we load after the original x86 plugin loads diff --git a/rust/binaryninjacore-sys/build.rs b/rust/binaryninjacore-sys/build.rs index 99f499ea..24be4dac 100644 --- a/rust/binaryninjacore-sys/build.rs +++ b/rust/binaryninjacore-sys/build.rs @@ -154,6 +154,8 @@ fn main() { .size_t_is_usize(true) .generate_comments(false) .whitelist_function("BN.*") + .whitelist_var("BN_CURRENT_CORE_ABI_VERSION") + .whitelist_var("BN_MINIMUM_CORE_ABI_VERSION") .rustified_enum("BN.*") .generate() .expect("Unable to generate bindings"); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index bdef8368..3d287321 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -215,3 +215,25 @@ pub mod logger { pub fn version() -> string::BnString { unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetVersionString()) } } + +pub fn plugin_abi_version() -> u32 { + binaryninjacore_sys::BN_CURRENT_CORE_ABI_VERSION +} + +pub fn plugin_abi_minimum_version() -> u32 { + binaryninjacore_sys::BN_MINIMUM_CORE_ABI_VERSION +} + +pub fn core_abi_version() -> u32 { + unsafe { binaryninjacore_sys::BNGetCurrentCoreABIVersion() } +} + +pub fn core_abi_minimum_version() -> u32 { + unsafe { binaryninjacore_sys::BNGetMinimumCoreABIVersion() } +} + +// Provide ABI version automatically so that the core can verify binary compatibility +#[cfg(not(feature = "headless"))] +#[no_mangle] +#[allow(non_snake_case)] +pub extern "C" fn CorePluginABIVersion() -> u32 { plugin_abi_version() } diff --git a/ui/uicontext.h b/ui/uicontext.h index 5fbd2ca2..df016462 100644 --- a/ui/uicontext.h +++ b/ui/uicontext.h @@ -12,6 +12,7 @@ typedef bool (*UIPluginInitFunction)(void); typedef void (*UIPluginDependencyFunction)(void); +typedef uint32_t (*UIPluginABIVersionFunction)(void); class ViewFrame; class UIActionHandler; diff --git a/ui/uitypes.h b/ui/uitypes.h index dd91d0ae..2daf6f4f 100644 --- a/ui/uitypes.h +++ b/ui/uitypes.h @@ -2,6 +2,19 @@ #include "binaryninjaapi.h" +// Current ABI version for linking to the UI API. This is incremented any time +// there are changes to the API that affect linking, including new functions, +// new types, modifications to existing functions or types, or new versions +// of the Qt libraries. +#define BN_CURRENT_UI_ABI_VERSION 1 + +// 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, or a new version of Qt. +#define BN_MINIMUM_UI_ABI_VERSION 1 + #ifdef __GNUC__ # ifdef BINARYNINJAUI_LIBRARY # define BINARYNINJAUIAPI __attribute__((visibility("default"))) @@ -28,6 +41,21 @@ #include "bindings.h" #endif +// The BN_DECLARE_UI_ABI_VERSION must be included in native UI plugin modules. If +// the ABI version is not declared, the UI will not load the plugin. +#ifdef DEMO_VERSION +#define BN_DECLARE_UI_ABI_VERSION +#else +#define BN_DECLARE_UI_ABI_VERSION \ + extern "C" \ + { \ + BINARYNINJAPLUGIN uint32_t UIPluginABIVersion() \ + { \ + return BN_CURRENT_UI_ABI_VERSION; \ + } \ + } +#endif + // The Python bindings generator does not recognize automatic conversion of API types into their // Python equivalents if using templates (Ref<*>), so we typedef all API references so that // the Python bindings can be easily generated for them. |
