diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index a4624a02c4..1aea7c20ce 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -1,10 +1,11 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -use crate::Unicorn; +use crate::{Unicorn, UnicornInner}; use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query}; -use core::ffi::c_void; +use alloc::rc::Weak; +use core::{cell::UnsafeCell, ffi::c_void}; use libc::{c_char, c_int}; pub type uc_handle = *mut c_void; @@ -89,7 +90,7 @@ extern "C" { pub struct UcHook<'a, D: 'a, F: 'a> { pub callback: F, - pub uc: Unicorn<'a, D>, + pub uc: Weak>>, } pub trait IsUcHook<'a> {} @@ -106,8 +107,11 @@ where F: FnMut(&mut crate::Unicorn, u64, usize) -> u64, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size) } pub extern "C" fn mmio_write_callback_proxy( @@ -120,8 +124,11 @@ pub extern "C" fn mmio_write_callback_proxy( F: FnMut(&mut crate::Unicorn, u64, usize, u64), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size, value); } pub extern "C" fn code_hook_proxy( @@ -133,8 +140,11 @@ pub extern "C" fn code_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn block_hook_proxy( @@ -146,8 +156,11 @@ pub extern "C" fn block_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn mem_hook_proxy( @@ -162,8 +175,11 @@ where F: FnMut(&mut crate::Unicorn, MemType, u64, usize, i64) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, mem_type, address, size as usize, value) } pub extern "C" fn intr_hook_proxy(uc: uc_handle, value: u32, user_data: *mut UcHook) @@ -171,8 +187,11 @@ where F: FnMut(&mut crate::Unicorn, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, value); } pub extern "C" fn insn_in_hook_proxy( @@ -184,8 +203,11 @@ pub extern "C" fn insn_in_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize) -> u32, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size); } pub extern "C" fn insn_invalid_hook_proxy(uc: uc_handle, user_data: *mut UcHook) -> bool @@ -193,8 +215,11 @@ where F: FnMut(&mut crate::Unicorn) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc) } pub extern "C" fn insn_out_hook_proxy( @@ -207,8 +232,11 @@ pub extern "C" fn insn_out_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size, value); } pub extern "C" fn insn_sys_hook_proxy(uc: uc_handle, user_data: *mut UcHook) @@ -216,6 +244,9 @@ where F: FnMut(&mut crate::Unicorn), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc); } diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 7959e2d5de..a71b99960e 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -369,17 +369,13 @@ impl<'a, D> Unicorn<'a, D> { let mut read_data = read_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); let mut write_data = write_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); @@ -586,7 +582,8 @@ impl<'a, D> Unicorn<'a, D> { return Err(uc_error::ARCH); } - let err: uc_error = unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; + let err: uc_error = + unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; if err == uc_error::OK { boxed = value.into_boxed_slice(); @@ -622,9 +619,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -654,9 +649,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -697,9 +690,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -730,9 +721,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -763,9 +752,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -796,9 +783,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -830,9 +815,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -870,9 +853,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe {