summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Miller <brandon@vector35.com>2024-10-02 08:17:25 -0400
committerBrandon Miller <bkmiller89@icloud.com>2024-10-03 08:39:54 -0400
commite8488aaa64fb847ca2e639369176cf88c1bc4f8e (patch)
treed08bade433501d3c76eae26d05245122b8081437
parent1b8b9d4ee4936faa8c9091720a312bb72964d8b1 (diff)
Added IsForceLoadable method to BinaryViewType
-rw-r--r--binaryninjaapi.h9
-rw-r--r--binaryninjacore.h4
-rw-r--r--binaryviewtype.cpp20
-rw-r--r--python/binaryview.py17
-rw-r--r--rust/examples/minidump/src/view.rs4
-rw-r--r--rust/src/custombinaryview.rs19
-rw-r--r--ui/options.h1
7 files changed, 73 insertions, 1 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index bec3474f..4acb7b7e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -6910,6 +6910,7 @@ namespace BinaryNinja {
static BNBinaryView* ParseCallback(void* ctxt, BNBinaryView* data);
static bool IsValidCallback(void* ctxt, BNBinaryView* data);
static bool IsDeprecatedCallback(void* ctxt);
+ static bool IsForceLoadableCallback(void *ctxt);
static BNSettings* GetSettingsCallback(void* ctxt, BNBinaryView* data);
BinaryViewType(BNBinaryViewType* type);
@@ -7047,6 +7048,13 @@ namespace BinaryNinja {
\return Whether this BinaryViewType is valid for given data
*/
virtual bool IsTypeValidForData(BinaryView* data) = 0;
+
+ /*! Check whether this BinaryViewType can be forced to load a binary, even if IsTypeValidForData returns false
+
+ \return Whether this BinaryViewType can be forced to load a binary
+ */
+ virtual bool IsForceLoadable();
+
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data);
Ref<Settings> GetDefaultLoadSettingsForData(BinaryView* data);
@@ -7069,6 +7077,7 @@ namespace BinaryNinja {
virtual Ref<BinaryView> Parse(BinaryView* data) override;
virtual bool IsTypeValidForData(BinaryView* data) override;
virtual bool IsDeprecated() override;
+ virtual bool IsForceLoadable() override;
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) override;
};
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 94625309..248c2905 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -37,7 +37,7 @@
// 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 77
+#define BN_CURRENT_CORE_ABI_VERSION 78
// 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
@@ -1657,6 +1657,7 @@ extern "C"
BNBinaryView* (*parse)(void* ctxt, BNBinaryView* data);
bool (*isValidForData)(void* ctxt, BNBinaryView* data);
bool (*isDeprecated)(void* ctxt);
+ bool (*isForceLoadable)(void* ctxt);
BNSettings* (*getLoadSettingsForData)(void* ctxt, BNBinaryView* data);
} BNCustomBinaryViewType;
@@ -4001,6 +4002,7 @@ extern "C"
BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI BNBinaryView* BNParseBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI bool BNIsBinaryViewTypeValidForData(BNBinaryViewType* type, BNBinaryView* data);
+ BINARYNINJACOREAPI bool BNIsBinaryViewTypeForceLoadable(BNBinaryViewType* type);
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewDefaultLoadSettingsForData(
BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data);
diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp
index b1ef5226..2ee8e2ac 100644
--- a/binaryviewtype.cpp
+++ b/binaryviewtype.cpp
@@ -61,6 +61,13 @@ bool BinaryViewType::IsDeprecatedCallback(void* ctxt)
}
+bool BinaryViewType::IsForceLoadableCallback(void* ctxt)
+{
+ CallbackRef<BinaryViewType> type(ctxt);
+ return type->IsForceLoadable();
+}
+
+
BNSettings* BinaryViewType::GetSettingsCallback(void* ctxt, BNBinaryView* data)
{
CallbackRef<BinaryViewType> type(ctxt);
@@ -93,6 +100,7 @@ void BinaryViewType::Register(BinaryViewType* type)
callbacks.parse = ParseCallback;
callbacks.isValidForData = IsValidCallback;
callbacks.isDeprecated = IsDeprecatedCallback;
+ callbacks.isForceLoadable = IsForceLoadableCallback;
callbacks.getLoadSettingsForData = GetSettingsCallback;
type->AddRefForRegistration();
@@ -247,6 +255,12 @@ bool BinaryViewType::IsDeprecated()
}
+bool BinaryViewType::IsForceLoadable()
+{
+ return false;
+}
+
+
void BinaryViewType::RegisterBinaryViewFinalizationEvent(const function<void(BinaryView* view)>& callback)
{
BinaryViewEvent* event = new BinaryViewEvent;
@@ -347,6 +361,12 @@ bool CoreBinaryViewType::IsDeprecated()
}
+bool CoreBinaryViewType::IsForceLoadable()
+{
+ return BNIsBinaryViewTypeForceLoadable(m_object);
+}
+
+
Ref<Settings> CoreBinaryViewType::GetLoadSettingsForData(BinaryView* data)
{
BNSettings* settings = BNGetBinaryViewLoadSettingsForData(m_object, data->GetObject());
diff --git a/python/binaryview.py b/python/binaryview.py
index 3321a21a..8a38e819 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -1271,6 +1271,11 @@ class BinaryViewType(metaclass=_BinaryViewTypeMetaclass):
"""returns if the BinaryViewType is deprecated (read-only)"""
return core.BNIsBinaryViewTypeDeprecated(self.handle)
+ @property
+ def is_force_loadable(self) -> bool:
+ """returns if the BinaryViewType is force loadable (read-only)"""
+ return core.BNIsBinaryViewTypeForceLoadable(self.handle)
+
def create(self, data: 'BinaryView') -> Optional['BinaryView']:
view = core.BNCreateBinaryViewOfType(self.handle, data.handle)
if view is None:
@@ -2511,6 +2516,7 @@ class BinaryView:
cls._registered_cb.parse = cls._registered_cb.parse.__class__(cls._parse)
cls._registered_cb.isValidForData = cls._registered_cb.isValidForData.__class__(cls._is_valid_for_data)
cls._registered_cb.isDeprecated = cls._registered_cb.isDeprecated.__class__(cls._is_deprecated)
+ cls._registered_cb.isForceLoadable = cls._registered_cb.isForceLoadable.__class__(cls._is_force_loadable)
cls._registered_cb.getLoadSettingsForData = cls._registered_cb.getLoadSettingsForData.__class__(
cls._get_load_settings_for_data
)
@@ -2580,6 +2586,17 @@ class BinaryView:
return False
@classmethod
+ def _is_force_loadable(cls, ctxt):
+ if not callable(getattr(cls, 'is_force_loadable', None)):
+ return False
+
+ try:
+ return cls.is_force_loadable() # type: ignore
+ except:
+ log_error(traceback.format_exc())
+ return False
+
+ @classmethod
def _get_load_settings_for_data(cls, ctxt, data):
try:
attr = getattr(cls, "get_load_settings_for_data", None)
diff --git a/rust/examples/minidump/src/view.rs b/rust/examples/minidump/src/view.rs
index 6ed419a9..ddb18c77 100644
--- a/rust/examples/minidump/src/view.rs
+++ b/rust/examples/minidump/src/view.rs
@@ -48,6 +48,10 @@ impl BinaryViewTypeBase for MinidumpBinaryViewType {
false
}
+ fn is_force_loadable(&self) -> bool {
+ false
+ }
+
fn is_valid_for(&self, data: &BinaryView) -> bool {
let mut magic_number = Vec::<u8>::new();
data.read_into_vec(&mut magic_number, 0, 4);
diff --git a/rust/src/custombinaryview.rs b/rust/src/custombinaryview.rs
index 1ec0ca80..2383ce1e 100644
--- a/rust/src/custombinaryview.rs
+++ b/rust/src/custombinaryview.rs
@@ -68,6 +68,16 @@ where
})
}
+ extern "C" fn cb_force_loadable<T>(ctxt: *mut c_void) -> bool
+ where
+ T: CustomBinaryViewType,
+ {
+ ffi_wrap!("BinaryViewTypeBase::is_force_loadable", unsafe {
+ let view_type = &*(ctxt as *mut T);
+ view_type.is_force_loadable()
+ })
+ }
+
extern "C" fn cb_create<T>(ctxt: *mut c_void, data: *mut BNBinaryView) -> *mut BNBinaryView
where
T: CustomBinaryViewType,
@@ -153,6 +163,7 @@ where
parse: Some(cb_parse::<T>),
isValidForData: Some(cb_valid::<T>),
isDeprecated: Some(cb_deprecated::<T>),
+ isForceLoadable: Some(cb_force_loadable::<T>),
getLoadSettingsForData: Some(cb_load_settings::<T>),
};
@@ -182,6 +193,10 @@ pub trait BinaryViewTypeBase: AsRef<BinaryViewType> {
false
}
+ fn is_force_loadable(&self) -> bool {
+ false
+ }
+
fn default_load_settings_for_data(&self, data: &BinaryView) -> Option<Ref<Settings>> {
let settings_handle =
unsafe { BNGetBinaryViewDefaultLoadSettingsForData(self.as_ref().0, data.handle) };
@@ -296,6 +311,10 @@ impl BinaryViewTypeBase for BinaryViewType {
unsafe { BNIsBinaryViewTypeDeprecated(self.0) }
}
+ fn is_force_loadable(&self) -> bool {
+ unsafe { BNIsBinaryViewTypeForceLoadable(self.0) }
+ }
+
fn load_settings_for_data(&self, data: &BinaryView) -> Option<Ref<Settings>> {
let settings_handle = unsafe { BNGetBinaryViewLoadSettingsForData(self.0, data.handle) };
diff --git a/ui/options.h b/ui/options.h
index 6493a1df..3206fc7e 100644
--- a/ui/options.h
+++ b/ui/options.h
@@ -32,6 +32,7 @@ class BINARYNINJAUIAPI OptionsDialog : public QDialog
QString m_fileName;
QLabel* m_fileLabel;
QComboBox* m_loadAsCombo;
+ QLabel* m_loadAsLabel;
QLabel* m_objectLabel;
QComboBox* m_objectCombo;
QTabWidget* m_tab;