Merge pull request #1764 from LG3696/fix-memory-leak
Fix Rust binding memory leak
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::Unicorn;
|
use crate::{Unicorn, UnicornInner};
|
||||||
|
|
||||||
use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query};
|
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};
|
use libc::{c_char, c_int};
|
||||||
|
|
||||||
pub type uc_handle = *mut c_void;
|
pub type uc_handle = *mut c_void;
|
||||||
@@ -89,7 +90,7 @@ extern "C" {
|
|||||||
|
|
||||||
pub struct UcHook<'a, D: 'a, F: 'a> {
|
pub struct UcHook<'a, D: 'a, F: 'a> {
|
||||||
pub callback: F,
|
pub callback: F,
|
||||||
pub uc: Unicorn<'a, D>,
|
pub uc: Weak<UnsafeCell<UnicornInner<'a, D>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IsUcHook<'a> {}
|
pub trait IsUcHook<'a> {}
|
||||||
@@ -106,8 +107,11 @@ where
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u64, usize) -> u64,
|
F: FnMut(&mut crate::Unicorn<D>, u64, usize) -> u64,
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, offset, size)
|
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<D, F>(
|
pub extern "C" fn mmio_write_callback_proxy<D, F>(
|
||||||
@@ -120,8 +124,11 @@ pub extern "C" fn mmio_write_callback_proxy<D, F>(
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u64, usize, u64),
|
F: FnMut(&mut crate::Unicorn<D>, u64, usize, u64),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, offset, size, value);
|
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<D, F>(
|
pub extern "C" fn code_hook_proxy<D, F>(
|
||||||
@@ -133,8 +140,11 @@ pub extern "C" fn code_hook_proxy<D, F>(
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u64, u32),
|
F: FnMut(&mut crate::Unicorn<D>, u64, u32),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, address, size);
|
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<D, F>(
|
pub extern "C" fn block_hook_proxy<D, F>(
|
||||||
@@ -146,8 +156,11 @@ pub extern "C" fn block_hook_proxy<D, F>(
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u64, u32),
|
F: FnMut(&mut crate::Unicorn<D>, u64, u32),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, address, size);
|
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<D, F>(
|
pub extern "C" fn mem_hook_proxy<D, F>(
|
||||||
@@ -162,8 +175,11 @@ where
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, MemType, u64, usize, i64) -> bool,
|
F: FnMut(&mut crate::Unicorn<D>, MemType, u64, usize, i64) -> bool,
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value)
|
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<D, F>(uc: uc_handle, value: u32, user_data: *mut UcHook<D, F>)
|
pub extern "C" fn intr_hook_proxy<D, F>(uc: uc_handle, value: u32, user_data: *mut UcHook<D, F>)
|
||||||
@@ -171,8 +187,11 @@ where
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u32),
|
F: FnMut(&mut crate::Unicorn<D>, u32),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, value);
|
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<D, F>(
|
pub extern "C" fn insn_in_hook_proxy<D, F>(
|
||||||
@@ -180,12 +199,16 @@ pub extern "C" fn insn_in_hook_proxy<D, F>(
|
|||||||
port: u32,
|
port: u32,
|
||||||
size: usize,
|
size: usize,
|
||||||
user_data: *mut UcHook<D, F>,
|
user_data: *mut UcHook<D, F>,
|
||||||
) where
|
) -> u32
|
||||||
|
where
|
||||||
F: FnMut(&mut crate::Unicorn<D>, u32, usize) -> u32,
|
F: FnMut(&mut crate::Unicorn<D>, u32, usize) -> u32,
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, port, size);
|
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<D, F>(uc: uc_handle, user_data: *mut UcHook<D, F>) -> bool
|
pub extern "C" fn insn_invalid_hook_proxy<D, F>(uc: uc_handle, user_data: *mut UcHook<D, F>) -> bool
|
||||||
@@ -193,8 +216,11 @@ where
|
|||||||
F: FnMut(&mut crate::Unicorn<D>) -> bool,
|
F: FnMut(&mut crate::Unicorn<D>) -> bool,
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc)
|
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<D, F>(
|
pub extern "C" fn insn_out_hook_proxy<D, F>(
|
||||||
@@ -207,8 +233,11 @@ pub extern "C" fn insn_out_hook_proxy<D, F>(
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u32, usize, u32),
|
F: FnMut(&mut crate::Unicorn<D>, u32, usize, u32),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc, port, size, value);
|
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<D, F>(uc: uc_handle, user_data: *mut UcHook<D, F>)
|
pub extern "C" fn insn_sys_hook_proxy<D, F>(uc: uc_handle, user_data: *mut UcHook<D, F>)
|
||||||
@@ -216,6 +245,9 @@ where
|
|||||||
F: FnMut(&mut crate::Unicorn<D>),
|
F: FnMut(&mut crate::Unicorn<D>),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.get_handle());
|
let mut user_data_uc = Unicorn {
|
||||||
(user_data.callback)(&mut user_data.uc);
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
|
};
|
||||||
|
debug_assert_eq!(uc, user_data_uc.get_handle());
|
||||||
|
(user_data.callback)(&mut user_data_uc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,17 +369,13 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut read_data = read_callback.map(|c| {
|
let mut read_data = read_callback.map(|c| {
|
||||||
Box::new(ffi::UcHook {
|
Box::new(ffi::UcHook {
|
||||||
callback: c,
|
callback: c,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
let mut write_data = write_callback.map(|c| {
|
let mut write_data = write_callback.map(|c| {
|
||||||
Box::new(ffi::UcHook {
|
Box::new(ffi::UcHook {
|
||||||
callback: c,
|
callback: c,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -586,7 +582,8 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
return Err(uc_error::ARCH);
|
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 {
|
if err == uc_error::OK {
|
||||||
boxed = value.into_boxed_slice();
|
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 hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -654,9 +649,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -697,9 +690,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -730,9 +721,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -763,9 +752,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -796,9 +783,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -830,9 +815,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
@@ -870,9 +853,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
let mut hook_ptr = core::ptr::null_mut();
|
let mut hook_ptr = core::ptr::null_mut();
|
||||||
let mut user_data = Box::new(ffi::UcHook {
|
let mut user_data = Box::new(ffi::UcHook {
|
||||||
callback,
|
callback,
|
||||||
uc: Unicorn {
|
uc: Rc::downgrade(&self.inner),
|
||||||
inner: self.inner.clone(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
|
|||||||
Reference in New Issue
Block a user