rust: Add get_handle
to expose unicorn handle
This commit is contained in:
parent
2977c9ca47
commit
394f25b1fa
@ -106,7 +106,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, offset, size)
|
(user_data.callback)(&mut user_data.uc, offset, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, offset, size, value);
|
(user_data.callback)(&mut user_data.uc, offset, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, address, size);
|
(user_data.callback)(&mut user_data.uc, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, address, size);
|
(user_data.callback)(&mut user_data.uc, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value)
|
(user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, value);
|
(user_data.callback)(&mut user_data.uc, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ pub extern "C" fn insn_in_hook_proxy<D, F>(
|
|||||||
F: FnMut(&mut crate::Unicorn<D>, u32, usize),
|
F: FnMut(&mut crate::Unicorn<D>, u32, usize),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = unsafe { &mut *user_data };
|
||||||
debug_assert_eq!(uc, user_data.uc.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, port, size);
|
(user_data.callback)(&mut user_data.uc, port, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc, port, size, value);
|
(user_data.callback)(&mut user_data.uc, port, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +207,6 @@ 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.inner().uc);
|
debug_assert_eq!(uc, user_data.uc.get_handle());
|
||||||
(user_data.callback)(&mut user_data.uc);
|
(user_data.callback)(&mut user_data.uc);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl<'a> MmioCallbackScope<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnicornInner<'a, D> {
|
pub struct UnicornInner<'a, D> {
|
||||||
pub uc: uc_handle,
|
pub handle: uc_handle,
|
||||||
pub ffi: bool,
|
pub ffi: bool,
|
||||||
pub arch: Arch,
|
pub arch: Arch,
|
||||||
/// to keep ownership over the hook for this uc instance's lifetime
|
/// to keep ownership over the hook for this uc instance's lifetime
|
||||||
@ -140,10 +140,10 @@ pub struct UnicornInner<'a, D> {
|
|||||||
/// Drop UC
|
/// Drop UC
|
||||||
impl<'a, D> Drop for UnicornInner<'a, D> {
|
impl<'a, D> Drop for UnicornInner<'a, D> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !self.ffi && !self.uc.is_null() {
|
if !self.ffi && !self.handle.is_null() {
|
||||||
unsafe { ffi::uc_close(self.uc) };
|
unsafe { ffi::uc_close(self.handle) };
|
||||||
}
|
}
|
||||||
self.uc = ptr::null_mut();
|
self.handle = ptr::null_mut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +158,12 @@ impl<'a> Unicorn<'a, ()> {
|
|||||||
pub fn new(arch: Arch, mode: Mode) -> Result<Unicorn<'a, ()>, uc_error> {
|
pub fn new(arch: Arch, mode: Mode) -> Result<Unicorn<'a, ()>, uc_error> {
|
||||||
Self::new_with_data(arch, mode, ())
|
Self::new_with_data(arch, mode, ())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_with_handle(handle: uc_handle) -> Result<Unicorn<'a, ()>, uc_error> {
|
impl<'a> TryFrom<uc_handle> for Unicorn<'a, ()> {
|
||||||
|
type Error = uc_error;
|
||||||
|
|
||||||
|
fn try_from(handle: uc_handle) -> Result<Unicorn<'a, ()>, uc_error> {
|
||||||
if handle == ptr::null_mut() {
|
if handle == ptr::null_mut() {
|
||||||
return Err(uc_error::HANDLE);
|
return Err(uc_error::HANDLE);
|
||||||
}
|
}
|
||||||
@ -170,7 +174,7 @@ impl<'a> Unicorn<'a, ()> {
|
|||||||
}
|
}
|
||||||
Ok(Unicorn {
|
Ok(Unicorn {
|
||||||
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
||||||
uc: handle,
|
handle,
|
||||||
ffi: true,
|
ffi: true,
|
||||||
arch: arch.try_into()?,
|
arch: arch.try_into()?,
|
||||||
data: (),
|
data: (),
|
||||||
@ -193,7 +197,7 @@ where
|
|||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(Unicorn {
|
Ok(Unicorn {
|
||||||
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
||||||
uc: handle,
|
handle,
|
||||||
ffi: false,
|
ffi: false,
|
||||||
arch,
|
arch,
|
||||||
data,
|
data,
|
||||||
@ -209,7 +213,7 @@ where
|
|||||||
|
|
||||||
impl<'a, D> core::fmt::Debug for Unicorn<'a, D> {
|
impl<'a, D> core::fmt::Debug for Unicorn<'a, D> {
|
||||||
fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
write!(formatter, "Unicorn {{ uc: {:p} }}", self.inner().uc)
|
write!(formatter, "Unicorn {{ uc: {:p} }}", self.get_handle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,11 +247,17 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
self.inner().arch
|
self.inner().arch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the handle of the current emulator.
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_handle(&self) -> uc_handle {
|
||||||
|
self.inner().handle
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a vector with the memory regions that are mapped in the emulator.
|
/// Returns a vector with the memory regions that are mapped in the emulator.
|
||||||
pub fn mem_regions(&self) -> Result<Vec<MemRegion>, uc_error> {
|
pub fn mem_regions(&self) -> Result<Vec<MemRegion>, uc_error> {
|
||||||
let mut nb_regions: u32 = 0;
|
let mut nb_regions: u32 = 0;
|
||||||
let p_regions: *const MemRegion = core::ptr::null_mut();
|
let p_regions: *const MemRegion = core::ptr::null_mut();
|
||||||
let err = unsafe { ffi::uc_mem_regions(self.inner().uc, &p_regions, &mut nb_regions) };
|
let err = unsafe { ffi::uc_mem_regions(self.get_handle(), &p_regions, &mut nb_regions) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
let mut regions = Vec::new();
|
let mut regions = Vec::new();
|
||||||
for i in 0..nb_regions {
|
for i in 0..nb_regions {
|
||||||
@ -263,7 +273,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// Read a range of bytes from memory at the specified address.
|
/// Read a range of bytes from memory at the specified address.
|
||||||
pub fn mem_read(&self, address: u64, buf: &mut [u8]) -> Result<(), uc_error> {
|
pub fn mem_read(&self, address: u64, buf: &mut [u8]) -> Result<(), uc_error> {
|
||||||
let err =
|
let err =
|
||||||
unsafe { ffi::uc_mem_read(self.inner().uc, address, buf.as_mut_ptr(), buf.len()) };
|
unsafe { ffi::uc_mem_read(self.get_handle(), address, buf.as_mut_ptr(), buf.len()) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -274,7 +284,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// Return a range of bytes from memory at the specified address as vector.
|
/// Return a range of bytes from memory at the specified address as vector.
|
||||||
pub fn mem_read_as_vec(&self, address: u64, size: usize) -> Result<Vec<u8>, uc_error> {
|
pub fn mem_read_as_vec(&self, address: u64, size: usize) -> Result<Vec<u8>, uc_error> {
|
||||||
let mut buf = vec![0; size];
|
let mut buf = vec![0; size];
|
||||||
let err = unsafe { ffi::uc_mem_read(self.inner().uc, address, buf.as_mut_ptr(), size) };
|
let err = unsafe { ffi::uc_mem_read(self.get_handle(), address, buf.as_mut_ptr(), size) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
} else {
|
} else {
|
||||||
@ -284,7 +294,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
pub fn mem_write(&mut self, address: u64, bytes: &[u8]) -> Result<(), uc_error> {
|
pub fn mem_write(&mut self, address: u64, bytes: &[u8]) -> Result<(), uc_error> {
|
||||||
let err =
|
let err =
|
||||||
unsafe { ffi::uc_mem_write(self.inner().uc, address, bytes.as_ptr(), bytes.len()) };
|
unsafe { ffi::uc_mem_write(self.get_handle(), address, bytes.as_ptr(), bytes.len()) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -312,7 +322,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
perms: Permission,
|
perms: Permission,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
) -> Result<(), uc_error> {
|
) -> Result<(), uc_error> {
|
||||||
let err = ffi::uc_mem_map_ptr(self.inner().uc, address, size, perms.bits(), ptr);
|
let err = ffi::uc_mem_map_ptr(self.get_handle(), address, size, perms.bits(), ptr);
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -330,7 +340,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
size: libc::size_t,
|
size: libc::size_t,
|
||||||
perms: Permission,
|
perms: Permission,
|
||||||
) -> Result<(), uc_error> {
|
) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_mem_map(self.inner().uc, address, size, perms.bits()) };
|
let err = unsafe { ffi::uc_mem_map(self.get_handle(), address, size, perms.bits()) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -372,7 +382,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_mmio_map(
|
ffi::uc_mmio_map(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
address,
|
address,
|
||||||
size,
|
size,
|
||||||
ffi::mmio_read_callback_proxy::<D, R> as _,
|
ffi::mmio_read_callback_proxy::<D, R> as _,
|
||||||
@ -450,7 +460,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// `address` must be aligned to 4kb or this will return `Error::ARG`.
|
/// `address` must be aligned to 4kb or this will return `Error::ARG`.
|
||||||
/// `size` must be a multiple of 4kb or this will return `Error::ARG`.
|
/// `size` must be a multiple of 4kb or this will return `Error::ARG`.
|
||||||
pub fn mem_unmap(&mut self, address: u64, size: libc::size_t) -> Result<(), uc_error> {
|
pub fn mem_unmap(&mut self, address: u64, size: libc::size_t) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_mem_unmap(self.inner().uc, address, size) };
|
let err = unsafe { ffi::uc_mem_unmap(self.get_handle(), address, size) };
|
||||||
|
|
||||||
self.mmio_unmap(address, size);
|
self.mmio_unmap(address, size);
|
||||||
|
|
||||||
@ -480,7 +490,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
size: libc::size_t,
|
size: libc::size_t,
|
||||||
perms: Permission,
|
perms: Permission,
|
||||||
) -> Result<(), uc_error> {
|
) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_mem_protect(self.inner().uc, address, size, perms.bits()) };
|
let err = unsafe { ffi::uc_mem_protect(self.get_handle(), address, size, perms.bits()) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -491,7 +501,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// Write an unsigned value from a register.
|
/// Write an unsigned value from a register.
|
||||||
pub fn reg_write<T: Into<i32>>(&mut self, regid: T, value: u64) -> Result<(), uc_error> {
|
pub fn reg_write<T: Into<i32>>(&mut self, regid: T, value: u64) -> Result<(), uc_error> {
|
||||||
let err =
|
let err =
|
||||||
unsafe { ffi::uc_reg_write(self.inner().uc, regid.into(), &value as *const _ as _) };
|
unsafe { ffi::uc_reg_write(self.get_handle(), regid.into(), &value as *const _ as _) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -504,7 +514,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// The user has to make sure that the buffer length matches the register size.
|
/// The user has to make sure that the buffer length matches the register size.
|
||||||
/// This adds support for registers >64 bit (GDTR/IDTR, XMM, YMM, ZMM (x86); Q, V (arm64)).
|
/// This adds support for registers >64 bit (GDTR/IDTR, XMM, YMM, ZMM (x86); Q, V (arm64)).
|
||||||
pub fn reg_write_long<T: Into<i32>>(&self, regid: T, value: &[u8]) -> Result<(), uc_error> {
|
pub fn reg_write_long<T: Into<i32>>(&self, regid: T, value: &[u8]) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_reg_write(self.inner().uc, regid.into(), value.as_ptr() as _) };
|
let err = unsafe { ffi::uc_reg_write(self.get_handle(), regid.into(), value.as_ptr() as _) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -518,7 +528,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
pub fn reg_read<T: Into<i32>>(&self, regid: T) -> Result<u64, uc_error> {
|
pub fn reg_read<T: Into<i32>>(&self, regid: T) -> Result<u64, uc_error> {
|
||||||
let mut value: u64 = 0;
|
let mut value: u64 = 0;
|
||||||
let err =
|
let err =
|
||||||
unsafe { ffi::uc_reg_read(self.inner().uc, regid.into(), &mut value as *mut u64 as _) };
|
unsafe { ffi::uc_reg_read(self.get_handle(), regid.into(), &mut value as *mut u64 as _) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
@ -572,7 +582,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
return Err(uc_error::ARCH);
|
return Err(uc_error::ARCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unsafe { ffi::uc_reg_read(self.inner().uc, curr_reg_id, value.as_mut_ptr() as _) };
|
err = 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();
|
||||||
@ -586,7 +596,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
pub fn reg_read_i32<T: Into<i32>>(&self, regid: T) -> Result<i32, uc_error> {
|
pub fn reg_read_i32<T: Into<i32>>(&self, regid: T) -> Result<i32, uc_error> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let err =
|
let err =
|
||||||
unsafe { ffi::uc_reg_read(self.inner().uc, regid.into(), &mut value as *mut i32 as _) };
|
unsafe { ffi::uc_reg_read(self.get_handle(), regid.into(), &mut value as *mut i32 as _) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
@ -614,7 +624,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::CODE,
|
HookType::CODE,
|
||||||
ffi::code_hook_proxy::<D, F> as _,
|
ffi::code_hook_proxy::<D, F> as _,
|
||||||
@ -646,7 +656,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::BLOCK,
|
HookType::BLOCK,
|
||||||
ffi::block_hook_proxy::<D, F> as _,
|
ffi::block_hook_proxy::<D, F> as _,
|
||||||
@ -689,7 +699,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
hook_type,
|
hook_type,
|
||||||
ffi::mem_hook_proxy::<D, F> as _,
|
ffi::mem_hook_proxy::<D, F> as _,
|
||||||
@ -722,7 +732,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::INTR,
|
HookType::INTR,
|
||||||
ffi::intr_hook_proxy::<D, F> as _,
|
ffi::intr_hook_proxy::<D, F> as _,
|
||||||
@ -755,7 +765,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::INSN,
|
HookType::INSN,
|
||||||
ffi::insn_in_hook_proxy::<D, F> as _,
|
ffi::insn_in_hook_proxy::<D, F> as _,
|
||||||
@ -789,7 +799,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::INSN,
|
HookType::INSN,
|
||||||
ffi::insn_out_hook_proxy::<D, F> as _,
|
ffi::insn_out_hook_proxy::<D, F> as _,
|
||||||
@ -829,7 +839,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
ffi::uc_hook_add(
|
ffi::uc_hook_add(
|
||||||
self.inner().uc,
|
self.get_handle(),
|
||||||
&mut hook_ptr,
|
&mut hook_ptr,
|
||||||
HookType::INSN,
|
HookType::INSN,
|
||||||
ffi::insn_sys_hook_proxy::<D, F> as _,
|
ffi::insn_sys_hook_proxy::<D, F> as _,
|
||||||
@ -860,7 +870,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
.hooks
|
.hooks
|
||||||
.retain(|(hook_ptr, _hook_impl)| hook_ptr != &hook);
|
.retain(|(hook_ptr, _hook_impl)| hook_ptr != &hook);
|
||||||
|
|
||||||
err = unsafe { ffi::uc_hook_del(inner.uc, hook) };
|
err = unsafe { ffi::uc_hook_del(inner.handle, hook) };
|
||||||
|
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -874,7 +884,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// To be populated via `context_save`.
|
/// To be populated via `context_save`.
|
||||||
pub fn context_alloc(&self) -> Result<Context, uc_error> {
|
pub fn context_alloc(&self) -> Result<Context, uc_error> {
|
||||||
let mut empty_context: ffi::uc_context = ptr::null_mut();
|
let mut empty_context: ffi::uc_context = ptr::null_mut();
|
||||||
let err = unsafe { ffi::uc_context_alloc(self.inner().uc, &mut empty_context) };
|
let err = unsafe { ffi::uc_context_alloc(self.get_handle(), &mut empty_context) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(Context {
|
Ok(Context {
|
||||||
context: empty_context,
|
context: empty_context,
|
||||||
@ -886,7 +896,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
|
|
||||||
/// Save current Unicorn context to previously allocated Context struct.
|
/// Save current Unicorn context to previously allocated Context struct.
|
||||||
pub fn context_save(&self, context: &mut Context) -> Result<(), uc_error> {
|
pub fn context_save(&self, context: &mut Context) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_context_save(self.inner().uc, context.context) };
|
let err = unsafe { ffi::uc_context_save(self.get_handle(), context.context) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -901,11 +911,11 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// individually to avoid unnecessary allocations.
|
/// individually to avoid unnecessary allocations.
|
||||||
pub fn context_init(&self) -> Result<Context, uc_error> {
|
pub fn context_init(&self) -> Result<Context, uc_error> {
|
||||||
let mut new_context: ffi::uc_context = ptr::null_mut();
|
let mut new_context: ffi::uc_context = ptr::null_mut();
|
||||||
let err = unsafe { ffi::uc_context_alloc(self.inner().uc, &mut new_context) };
|
let err = unsafe { ffi::uc_context_alloc(self.get_handle(), &mut new_context) };
|
||||||
if err != uc_error::OK {
|
if err != uc_error::OK {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
let err = unsafe { ffi::uc_context_save(self.inner().uc, new_context) };
|
let err = unsafe { ffi::uc_context_save(self.get_handle(), new_context) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(Context {
|
Ok(Context {
|
||||||
context: new_context,
|
context: new_context,
|
||||||
@ -922,7 +932,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// internal metadata. Contexts may not be shared across engine instances with
|
/// internal metadata. Contexts may not be shared across engine instances with
|
||||||
/// differing arches or modes. Memory has to be restored manually, if needed.
|
/// differing arches or modes. Memory has to be restored manually, if needed.
|
||||||
pub fn context_restore(&self, context: &Context) -> Result<(), uc_error> {
|
pub fn context_restore(&self, context: &Context) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_context_restore(self.inner().uc, context.context) };
|
let err = unsafe { ffi::uc_context_restore(self.get_handle(), context.context) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -944,7 +954,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
count: usize,
|
count: usize,
|
||||||
) -> Result<(), uc_error> {
|
) -> Result<(), uc_error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let err = ffi::uc_emu_start(self.inner().uc, begin, until, timeout, count as _);
|
let err = ffi::uc_emu_start(self.get_handle(), begin, until, timeout, count as _);
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -958,7 +968,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// This is usually called from callback function in hooks.
|
/// This is usually called from callback function in hooks.
|
||||||
/// NOTE: For now, this will stop the execution only after the current block.
|
/// NOTE: For now, this will stop the execution only after the current block.
|
||||||
pub fn emu_stop(&mut self) -> Result<(), uc_error> {
|
pub fn emu_stop(&mut self) -> Result<(), uc_error> {
|
||||||
let err = unsafe { ffi::uc_emu_stop(self.inner().uc) };
|
let err = unsafe { ffi::uc_emu_stop(self.get_handle()) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -971,7 +981,7 @@ impl<'a, D> Unicorn<'a, D> {
|
|||||||
/// supported: `MODE`, `PAGE_SIZE`, `ARCH`
|
/// supported: `MODE`, `PAGE_SIZE`, `ARCH`
|
||||||
pub fn query(&self, query: Query) -> Result<usize, uc_error> {
|
pub fn query(&self, query: Query) -> Result<usize, uc_error> {
|
||||||
let mut result: libc::size_t = Default::default();
|
let mut result: libc::size_t = Default::default();
|
||||||
let err = unsafe { ffi::uc_query(self.inner().uc, query, &mut result) };
|
let err = unsafe { ffi::uc_query(self.get_handle(), query, &mut result) };
|
||||||
if err == uc_error::OK {
|
if err == uc_error::OK {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user