binaryninja/
object_destructor.rs1use crate::binary_view::BinaryView;
4use crate::file_metadata::FileMetadata;
5use crate::function::Function;
6use binaryninjacore_sys::*;
7use std::ffi::c_void;
8
9#[must_use = "The destructor will be unregistered when the handle is dropped"]
15pub fn register_object_destructor<'a, D: ObjectDestructor>(
16 destructor: D,
17) -> ObjectDestructorHandle<'a, D> {
18 let destructor = Box::leak(Box::new(destructor));
19 let callbacks = BNObjectDestructionCallbacks {
20 context: destructor as *mut _ as *mut c_void,
21 destructBinaryView: Some(cb_destruct_binary_view::<D>),
22 destructFileMetadata: Some(cb_destruct_file_metadata::<D>),
23 destructFunction: Some(cb_destruct_function::<D>),
24 };
25 let mut handle = ObjectDestructorHandle {
26 callbacks,
27 _life: std::marker::PhantomData,
28 };
29 unsafe { BNRegisterObjectDestructionCallbacks(&mut handle.callbacks) };
30 handle
31}
32
33pub struct ObjectDestructorHandle<'a, D: ObjectDestructor> {
37 callbacks: BNObjectDestructionCallbacks,
38 _life: std::marker::PhantomData<&'a D>,
39}
40
41impl<D: ObjectDestructor> Drop for ObjectDestructorHandle<'_, D> {
42 fn drop(&mut self) {
43 unsafe { BNUnregisterObjectDestructionCallbacks(&mut self.callbacks) };
44 let _ = unsafe { Box::from_raw(self.callbacks.context as *mut D) };
45 }
46}
47
48pub trait ObjectDestructor: 'static + Sync + Sized {
52 fn destruct_view(&self, _view: &BinaryView) {}
54
55 fn destruct_file_metadata(&self, _metadata: &FileMetadata) {}
57
58 fn destruct_function(&self, _func: &Function) {}
60}
61
62unsafe extern "C" fn cb_destruct_binary_view<D: ObjectDestructor>(
63 ctxt: *mut c_void,
64 view: *mut BNBinaryView,
65) {
66 ffi_wrap!("ObjectDestructor::destruct_view", {
67 let destructor = &*(ctxt as *mut D);
68 let view = BinaryView { handle: view };
69 destructor.destruct_view(&view);
70 })
71}
72
73unsafe extern "C" fn cb_destruct_file_metadata<D: ObjectDestructor>(
74 ctxt: *mut c_void,
75 file: *mut BNFileMetadata,
76) {
77 ffi_wrap!("ObjectDestructor::destruct_file_metadata", {
78 let destructor = &*(ctxt as *mut D);
79 let file = FileMetadata::from_raw(file);
80 destructor.destruct_file_metadata(&file);
81 })
82}
83
84unsafe extern "C" fn cb_destruct_function<D: ObjectDestructor>(
85 ctxt: *mut c_void,
86 func: *mut BNFunction,
87) {
88 ffi_wrap!("ObjectDestructor::destruct_function", {
89 let destructor = &*(ctxt as *mut D);
90 let func = Function { handle: func };
91 destructor.destruct_function(&func);
92 })
93}