Skip to content

Commit ddd7aa4

Browse files
committed
Add a hook to allow BinaryView subclasses to run code after snapshot data is applied
Snapshot data is applied when loading from a database, rebasing the view, etc.
1 parent 20adc82 commit ddd7aa4

File tree

5 files changed

+45
-2
lines changed

5 files changed

+45
-2
lines changed

binaryninjaapi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5773,13 +5773,23 @@ namespace BinaryNinja {
57735773
void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc);
57745774
void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref<Symbol> sym, uint64_t reloc);
57755775

5776+
/*! OnAfterSnapshotDataApplied is called when loading a view from a database, after snapshot data has been applied to it.
5777+
5778+
\note This method **may** be overridden by custom BinaryViews.
5779+
5780+
\warning This method **must not** be called directly.
5781+
5782+
*/
5783+
virtual void OnAfterSnapshotDataApplied() {}
5784+
57765785
public:
57775786
void NotifyDataWritten(uint64_t offset, size_t len);
57785787
void NotifyDataInserted(uint64_t offset, size_t len);
57795788
void NotifyDataRemoved(uint64_t offset, uint64_t len);
57805789

57815790
private:
57825791
static bool InitCallback(void* ctxt);
5792+
static void OnAfterSnapshotDataAppliedCallback(void* ctxt);
57835793
static void FreeCallback(void* ctxt);
57845794
static size_t ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len);
57855795
static size_t WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len);

binaryninjacore.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 162
40+
#define BN_CURRENT_CORE_ABI_VERSION 163
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 161
47+
#define BN_MINIMUM_CORE_ABI_VERSION 163
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -1847,6 +1847,7 @@ extern "C"
18471847
bool (*isRelocatable)(void* ctxt);
18481848
size_t (*getAddressSize)(void* ctxt);
18491849
bool (*save)(void* ctxt, BNFileAccessor* accessor);
1850+
void (*onAfterSnapshotDataApplied)(void* ctxt);
18501851
} BNCustomBinaryView;
18511852

18521853
typedef struct BNCustomBinaryViewType

binaryview.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,7 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi
13651365
view.isRelocatable = IsRelocatableCallback;
13661366
view.getAddressSize = GetAddressSizeCallback;
13671367
view.save = SaveCallback;
1368+
view.onAfterSnapshotDataApplied = OnAfterSnapshotDataAppliedCallback;
13681369
m_file = file;
13691370
AddRefForRegistration();
13701371
m_object = BNCreateCustomBinaryView(
@@ -1388,6 +1389,13 @@ bool BinaryView::InitCallback(void* ctxt)
13881389
}
13891390

13901391

1392+
void BinaryView::OnAfterSnapshotDataAppliedCallback(void* ctxt)
1393+
{
1394+
CallbackRef<BinaryView> view(ctxt);
1395+
view->OnAfterSnapshotDataApplied();
1396+
}
1397+
1398+
13911399
void BinaryView::FreeCallback(void* ctxt)
13921400
{
13931401
BinaryView* view = (BinaryView*)ctxt;

python/binaryview.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3173,6 +3173,7 @@ def __init__(
31733173
self._cb.isRelocatable = self._cb.isRelocatable.__class__(self._is_relocatable)
31743174
self._cb.getAddressSize = self._cb.getAddressSize.__class__(self._get_address_size)
31753175
self._cb.save = self._cb.save.__class__(self._save)
3176+
self._cb.onAfterSnapshotDataApplied = self._cb.onAfterSnapshotDataApplied.__class__(self._on_after_snapshot_data_applied)
31763177
if file_metadata is None:
31773178
raise Exception("Attempting to create a BinaryView with FileMetadata which is None")
31783179
self._file = file_metadata
@@ -4482,6 +4483,15 @@ def _save(self, ctxt, file_accessor):
44824483
log_error_for_exception("Unhandled Python exception in BinaryView._save")
44834484
return False
44844485

4486+
def _on_after_snapshot_data_applied(self, ctxt):
4487+
try:
4488+
self.perform_on_after_snapshot_data_applied()
4489+
except:
4490+
log_error_for_exception("Unhandled Python exception in BinaryView._on_after_snapshot_data_applied")
4491+
4492+
def perform_on_after_snapshot_data_applied(self) -> None:
4493+
pass
4494+
44854495
def init(self) -> bool:
44864496
return True
44874497

rust/src/custom_binary_view.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ pub unsafe trait CustomBinaryView: 'static + BinaryViewBase + Sync + Sized {
460460

461461
fn new(handle: &BinaryView, args: &Self::Args) -> Result<Self>;
462462
fn init(&mut self, args: Self::Args) -> Result<()>;
463+
fn on_after_snapshot_data_applied(&mut self) {}
463464
}
464465

465466
/// Represents a partially initialized custom `BinaryView` that should be returned to the core
@@ -600,6 +601,18 @@ impl<'a, T: CustomBinaryViewType> CustomViewBuilder<'a, T> {
600601
})
601602
}
602603

604+
extern "C" fn cb_on_after_snapshot_data_applied<V>(ctxt: *mut c_void)
605+
where
606+
V: CustomBinaryView,
607+
{
608+
ffi_wrap!("BinaryViewBase::onAfterSnapshotDataApplied", unsafe {
609+
let context = &mut *(ctxt as *mut CustomViewContext<V>);
610+
if let CustomViewContextState::Initialized { view } = &mut context.state {
611+
view.on_after_snapshot_data_applied();
612+
}
613+
})
614+
}
615+
603616
extern "C" fn cb_free_object<V>(ctxt: *mut c_void)
604617
where
605618
V: CustomBinaryView,
@@ -890,6 +903,7 @@ impl<'a, T: CustomBinaryViewType> CustomViewBuilder<'a, T> {
890903
isRelocatable: Some(cb_relocatable::<V>),
891904
getAddressSize: Some(cb_address_size::<V>),
892905
save: Some(cb_save::<V>),
906+
onAfterSnapshotDataApplied: Some(cb_on_after_snapshot_data_applied::<V>),
893907
};
894908

895909
let view_name = view_name.to_cstr();

0 commit comments

Comments
 (0)