summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2021-01-25 16:45:06 -0500
committerRusty Wagner <rusty@vector35.com>2021-01-27 18:39:42 -0500
commit12f916450b444427685688bf34de65e11bf849e2 (patch)
treebd13651d872c1fc7ad5933e9a38a77da82235cd3
parent51d0f18eb4df16263867ef157b5293bb1b44f77a (diff)
Add ABI version verification for plugins
-rw-r--r--binaryninjacore.h32
-rw-r--r--examples/breakpoint/src/breakpoint.cpp2
-rw-r--r--examples/triage/triage.cpp2
-rw-r--r--examples/uinotification/uinotification.cpp2
-rw-r--r--examples/x86_extension/src/x86_extension.cpp2
-rw-r--r--rust/binaryninjacore-sys/build.rs2
-rw-r--r--rust/src/lib.rs22
-rw-r--r--ui/uicontext.h1
-rw-r--r--ui/uitypes.h28
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.