Merge pull request #1866 from mlgiraud/fix/unsafe_ptr_deref
fix: Make functions that deref ptr unsafe
This commit is contained in:
@@ -5,7 +5,8 @@ use crate::{Unicorn, UnicornInner};
|
|||||||
|
|
||||||
use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query, TlbEntry};
|
use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query, TlbEntry};
|
||||||
use alloc::rc::Weak;
|
use alloc::rc::Weak;
|
||||||
use core::{cell::UnsafeCell, ffi::c_void};
|
use core::cell::UnsafeCell;
|
||||||
|
use core::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;
|
||||||
@@ -13,15 +14,30 @@ pub type uc_hook = *mut c_void;
|
|||||||
pub type uc_context = *mut c_void;
|
pub type uc_context = *mut c_void;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn uc_version(major: *mut u32, minor: *mut u32) -> u32;
|
pub fn uc_version(
|
||||||
|
major: *mut u32,
|
||||||
|
minor: *mut u32,
|
||||||
|
) -> u32;
|
||||||
pub fn uc_arch_supported(arch: Arch) -> bool;
|
pub fn uc_arch_supported(arch: Arch) -> bool;
|
||||||
pub fn uc_open(arch: Arch, mode: Mode, engine: *mut uc_handle) -> uc_error;
|
pub fn uc_open(
|
||||||
|
arch: Arch,
|
||||||
|
mode: Mode,
|
||||||
|
engine: *mut uc_handle,
|
||||||
|
) -> uc_error;
|
||||||
pub fn uc_close(engine: uc_handle) -> uc_error;
|
pub fn uc_close(engine: uc_handle) -> uc_error;
|
||||||
pub fn uc_context_free(mem: uc_context) -> uc_error;
|
pub fn uc_context_free(mem: uc_context) -> uc_error;
|
||||||
pub fn uc_errno(engine: uc_handle) -> uc_error;
|
pub fn uc_errno(engine: uc_handle) -> uc_error;
|
||||||
pub fn uc_strerror(error_code: uc_error) -> *const c_char;
|
pub fn uc_strerror(error_code: uc_error) -> *const c_char;
|
||||||
pub fn uc_reg_write(engine: uc_handle, regid: c_int, value: *const c_void) -> uc_error;
|
pub fn uc_reg_write(
|
||||||
pub fn uc_reg_read(engine: uc_handle, regid: c_int, value: *mut c_void) -> uc_error;
|
engine: uc_handle,
|
||||||
|
regid: c_int,
|
||||||
|
value: *const c_void,
|
||||||
|
) -> uc_error;
|
||||||
|
pub fn uc_reg_read(
|
||||||
|
engine: uc_handle,
|
||||||
|
regid: c_int,
|
||||||
|
value: *mut c_void,
|
||||||
|
) -> uc_error;
|
||||||
pub fn uc_mem_write(
|
pub fn uc_mem_write(
|
||||||
engine: uc_handle,
|
engine: uc_handle,
|
||||||
address: u64,
|
address: u64,
|
||||||
@@ -34,7 +50,12 @@ extern "C" {
|
|||||||
bytes: *mut u8,
|
bytes: *mut u8,
|
||||||
size: libc::size_t,
|
size: libc::size_t,
|
||||||
) -> uc_error;
|
) -> uc_error;
|
||||||
pub fn uc_mem_map(engine: uc_handle, address: u64, size: libc::size_t, perms: u32) -> uc_error;
|
pub fn uc_mem_map(
|
||||||
|
engine: uc_handle,
|
||||||
|
address: u64,
|
||||||
|
size: libc::size_t,
|
||||||
|
perms: u32,
|
||||||
|
) -> uc_error;
|
||||||
pub fn uc_mem_map_ptr(
|
pub fn uc_mem_map_ptr(
|
||||||
engine: uc_handle,
|
engine: uc_handle,
|
||||||
address: u64,
|
address: u64,
|
||||||
@@ -51,7 +72,11 @@ extern "C" {
|
|||||||
write_cb: *mut c_void,
|
write_cb: *mut c_void,
|
||||||
user_data_write: *mut c_void,
|
user_data_write: *mut c_void,
|
||||||
) -> uc_error;
|
) -> uc_error;
|
||||||
pub fn uc_mem_unmap(engine: uc_handle, address: u64, size: libc::size_t) -> uc_error;
|
pub fn uc_mem_unmap(
|
||||||
|
engine: uc_handle,
|
||||||
|
address: u64,
|
||||||
|
size: libc::size_t,
|
||||||
|
) -> uc_error;
|
||||||
pub fn uc_mem_protect(
|
pub fn uc_mem_protect(
|
||||||
engine: uc_handle,
|
engine: uc_handle,
|
||||||
address: u64,
|
address: u64,
|
||||||
@@ -81,12 +106,32 @@ extern "C" {
|
|||||||
end: u64,
|
end: u64,
|
||||||
...
|
...
|
||||||
) -> uc_error;
|
) -> uc_error;
|
||||||
pub fn uc_hook_del(engine: uc_handle, hook: uc_hook) -> uc_error;
|
pub fn uc_hook_del(
|
||||||
pub fn uc_query(engine: uc_handle, query_type: Query, result: *mut libc::size_t) -> uc_error;
|
engine: uc_handle,
|
||||||
pub fn uc_context_alloc(engine: uc_handle, context: *mut uc_context) -> uc_error;
|
hook: uc_hook,
|
||||||
pub fn uc_context_save(engine: uc_handle, context: uc_context) -> uc_error;
|
) -> uc_error;
|
||||||
pub fn uc_context_restore(engine: uc_handle, context: uc_context) -> uc_error;
|
pub fn uc_query(
|
||||||
pub fn uc_ctl(engine: uc_handle, control: u32, ...) -> uc_error;
|
engine: uc_handle,
|
||||||
|
query_type: Query,
|
||||||
|
result: *mut libc::size_t,
|
||||||
|
) -> uc_error;
|
||||||
|
pub fn uc_context_alloc(
|
||||||
|
engine: uc_handle,
|
||||||
|
context: *mut uc_context,
|
||||||
|
) -> uc_error;
|
||||||
|
pub fn uc_context_save(
|
||||||
|
engine: uc_handle,
|
||||||
|
context: uc_context,
|
||||||
|
) -> uc_error;
|
||||||
|
pub fn uc_context_restore(
|
||||||
|
engine: uc_handle,
|
||||||
|
context: uc_context,
|
||||||
|
) -> uc_error;
|
||||||
|
pub fn uc_ctl(
|
||||||
|
engine: uc_handle,
|
||||||
|
control: u32,
|
||||||
|
...
|
||||||
|
) -> uc_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UcHook<'a, D: 'a, F: 'a> {
|
pub struct UcHook<'a, D: 'a, F: 'a> {
|
||||||
@@ -98,7 +143,7 @@ pub trait IsUcHook<'a> {}
|
|||||||
|
|
||||||
impl<'a, D, F> IsUcHook<'a> for UcHook<'a, D, F> {}
|
impl<'a, D, F> IsUcHook<'a> for UcHook<'a, D, F> {}
|
||||||
|
|
||||||
pub extern "C" fn mmio_read_callback_proxy<D, F>(
|
pub unsafe extern "C" fn mmio_read_callback_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
size: usize,
|
size: usize,
|
||||||
@@ -107,7 +152,7 @@ pub extern "C" fn mmio_read_callback_proxy<D, F>(
|
|||||||
where
|
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -115,7 +160,7 @@ where
|
|||||||
(user_data.callback)(&mut user_data_uc, offset, size)
|
(user_data.callback)(&mut user_data_uc, offset, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn mmio_write_callback_proxy<D, F>(
|
pub unsafe extern "C" fn mmio_write_callback_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
size: usize,
|
size: usize,
|
||||||
@@ -124,7 +169,7 @@ pub extern "C" fn mmio_write_callback_proxy<D, F>(
|
|||||||
) where
|
) 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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -132,7 +177,7 @@ pub extern "C" fn mmio_write_callback_proxy<D, F>(
|
|||||||
(user_data.callback)(&mut user_data_uc, offset, size, value);
|
(user_data.callback)(&mut user_data_uc, offset, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn code_hook_proxy<D, F>(
|
pub unsafe extern "C" fn code_hook_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
address: u64,
|
address: u64,
|
||||||
size: u32,
|
size: u32,
|
||||||
@@ -140,7 +185,7 @@ pub extern "C" fn code_hook_proxy<D, F>(
|
|||||||
) where
|
) where
|
||||||
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -148,7 +193,7 @@ pub extern "C" fn code_hook_proxy<D, F>(
|
|||||||
(user_data.callback)(&mut user_data_uc, address, size);
|
(user_data.callback)(&mut user_data_uc, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn block_hook_proxy<D, F>(
|
pub unsafe extern "C" fn block_hook_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
address: u64,
|
address: u64,
|
||||||
size: u32,
|
size: u32,
|
||||||
@@ -156,7 +201,7 @@ pub extern "C" fn block_hook_proxy<D, F>(
|
|||||||
) where
|
) where
|
||||||
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -164,7 +209,7 @@ pub extern "C" fn block_hook_proxy<D, F>(
|
|||||||
(user_data.callback)(&mut user_data_uc, address, size);
|
(user_data.callback)(&mut user_data_uc, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn mem_hook_proxy<D, F>(
|
pub unsafe extern "C" fn mem_hook_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
mem_type: MemType,
|
mem_type: MemType,
|
||||||
address: u64,
|
address: u64,
|
||||||
@@ -175,7 +220,7 @@ pub extern "C" fn mem_hook_proxy<D, F>(
|
|||||||
where
|
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -183,11 +228,14 @@ where
|
|||||||
(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)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn intr_hook_proxy<D, F>(uc: uc_handle, value: u32, user_data: *mut UcHook<D, F>)
|
pub unsafe extern "C" fn intr_hook_proxy<D, F>(
|
||||||
where
|
uc: uc_handle,
|
||||||
|
value: u32,
|
||||||
|
user_data: *mut UcHook<D, F>,
|
||||||
|
) 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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -195,7 +243,7 @@ where
|
|||||||
(user_data.callback)(&mut user_data_uc, value);
|
(user_data.callback)(&mut user_data_uc, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn insn_in_hook_proxy<D, F>(
|
pub unsafe extern "C" fn insn_in_hook_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
port: u32,
|
port: u32,
|
||||||
size: usize,
|
size: usize,
|
||||||
@@ -204,7 +252,7 @@ pub extern "C" fn insn_in_hook_proxy<D, F>(
|
|||||||
where
|
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -212,11 +260,14 @@ where
|
|||||||
(user_data.callback)(&mut user_data_uc, port, size)
|
(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 unsafe extern "C" fn insn_invalid_hook_proxy<D, F>(
|
||||||
|
uc: uc_handle,
|
||||||
|
user_data: *mut UcHook<D, F>,
|
||||||
|
) -> bool
|
||||||
where
|
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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -224,7 +275,7 @@ where
|
|||||||
(user_data.callback)(&mut user_data_uc)
|
(user_data.callback)(&mut user_data_uc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn insn_out_hook_proxy<D, F>(
|
pub unsafe extern "C" fn insn_out_hook_proxy<D, F>(
|
||||||
uc: uc_handle,
|
uc: uc_handle,
|
||||||
port: u32,
|
port: u32,
|
||||||
size: usize,
|
size: usize,
|
||||||
@@ -233,7 +284,7 @@ pub extern "C" fn insn_out_hook_proxy<D, F>(
|
|||||||
) where
|
) 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 = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -241,11 +292,13 @@ pub extern "C" fn insn_out_hook_proxy<D, F>(
|
|||||||
(user_data.callback)(&mut user_data_uc, port, size, value);
|
(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 unsafe extern "C" fn insn_sys_hook_proxy<D, F>(
|
||||||
where
|
uc: uc_handle,
|
||||||
|
user_data: *mut UcHook<D, F>,
|
||||||
|
) where
|
||||||
F: FnMut(&mut crate::Unicorn<D>),
|
F: FnMut(&mut crate::Unicorn<D>),
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
@@ -253,24 +306,25 @@ where
|
|||||||
(user_data.callback)(&mut user_data_uc);
|
(user_data.callback)(&mut user_data_uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn tlb_lookup_hook_proxy<D, F>(uc: uc_handle, vaddr: u64, mem_type: MemType, result: *mut TlbEntry, user_data: *mut UcHook<D, F>) -> bool
|
pub unsafe extern "C" fn tlb_lookup_hook_proxy<D, F>(
|
||||||
|
uc: uc_handle,
|
||||||
|
vaddr: u64,
|
||||||
|
mem_type: MemType,
|
||||||
|
result: *mut TlbEntry,
|
||||||
|
user_data: *mut UcHook<D, F>,
|
||||||
|
) -> bool
|
||||||
where
|
where
|
||||||
F: FnMut(&mut crate::Unicorn<D>, u64, MemType) -> Option<TlbEntry>,
|
F: FnMut(&mut crate::Unicorn<D>, u64, MemType) -> Option<TlbEntry>,
|
||||||
{
|
{
|
||||||
let user_data = unsafe { &mut *user_data };
|
let user_data = &mut *user_data;
|
||||||
let mut user_data_uc = Unicorn {
|
let mut user_data_uc = Unicorn {
|
||||||
inner: user_data.uc.upgrade().unwrap(),
|
inner: user_data.uc.upgrade().unwrap(),
|
||||||
};
|
};
|
||||||
debug_assert_eq!(uc, user_data_uc.get_handle());
|
debug_assert_eq!(uc, user_data_uc.get_handle());
|
||||||
let r = (user_data.callback)(&mut user_data_uc, vaddr, mem_type);
|
let r = (user_data.callback)(&mut user_data_uc, vaddr, mem_type);
|
||||||
match r {
|
if let Some(ref e) = r {
|
||||||
Some(ref e) => {
|
let ref_result: &mut TlbEntry = &mut *result;
|
||||||
unsafe {
|
*ref_result = *e;
|
||||||
let ref_result: &mut TlbEntry = &mut *result;
|
|
||||||
*ref_result = *e;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
};
|
};
|
||||||
return r.is_some();
|
r.is_some()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user