Rust Bindings: reg_read_batch and reg_write_batch (#2060)
* Added binding for rust reg_{read,write}_batch
* Fix reg_write_batch values pointer
This commit is contained in:
@@ -23,7 +23,19 @@ extern "C" {
|
||||
pub fn uc_errno(engine: uc_handle) -> uc_error;
|
||||
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_batch(
|
||||
engine: uc_handle,
|
||||
regids: *const c_int,
|
||||
values: *const *const c_void,
|
||||
count: c_int,
|
||||
) -> uc_error;
|
||||
pub fn uc_reg_read(engine: uc_handle, regid: c_int, value: *mut c_void) -> uc_error;
|
||||
pub fn uc_reg_read_batch(
|
||||
engine: uc_handle,
|
||||
regids: *const c_int,
|
||||
values: *const *mut c_void,
|
||||
count: c_int,
|
||||
) -> uc_error;
|
||||
pub fn uc_mem_write(
|
||||
engine: uc_handle,
|
||||
address: u64,
|
||||
|
||||
@@ -523,6 +523,28 @@ impl<'a, D> Unicorn<'a, D> {
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Write values into batch of registers
|
||||
pub fn reg_write_batch<T: Into<i32>>(
|
||||
&self,
|
||||
regids: &[T],
|
||||
values: &[u64],
|
||||
count: i32,
|
||||
) -> Result<(), uc_error> {
|
||||
let mut values_ptrs: Vec<*const u64> = vec![0 as *const u64; count as usize];
|
||||
for i in 0..values.len() {
|
||||
values_ptrs[i as usize] = &values[i] as *const u64;
|
||||
}
|
||||
unsafe {
|
||||
ffi::uc_reg_write_batch(
|
||||
self.get_handle(),
|
||||
regids.as_ptr() as *const i32,
|
||||
values_ptrs.as_ptr() as *const *const c_void,
|
||||
count,
|
||||
)
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Write variable sized values into registers.
|
||||
///
|
||||
/// The user has to make sure that the buffer length matches the register size.
|
||||
@@ -540,6 +562,33 @@ impl<'a, D> Unicorn<'a, D> {
|
||||
.and(Ok(value))
|
||||
}
|
||||
|
||||
/// Read batch of registers
|
||||
///
|
||||
/// Not to be used with registers larger than 64 bit
|
||||
pub fn reg_read_batch<T: Into<i32>>(
|
||||
&self,
|
||||
regids: &[T],
|
||||
count: i32,
|
||||
) -> Result<Vec<u64>, uc_error> {
|
||||
unsafe {
|
||||
let mut addrs_vec = vec![0u64; count as usize];
|
||||
let addrs = addrs_vec.as_mut_slice();
|
||||
for i in 0..count {
|
||||
addrs[i as usize] = &mut addrs[i as usize] as *mut u64 as u64;
|
||||
}
|
||||
let res = ffi::uc_reg_read_batch(
|
||||
self.get_handle(),
|
||||
regids.as_ptr() as *const i32,
|
||||
addrs.as_ptr() as *const *mut c_void,
|
||||
count,
|
||||
);
|
||||
match res {
|
||||
uc_error::OK => Ok(addrs_vec),
|
||||
_ => Err(res),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read 128, 256 or 512 bit register value into heap allocated byte array.
|
||||
///
|
||||
/// This adds safe support for registers >64 bit (GDTR/IDTR, XMM, YMM, ZMM, ST (x86); Q, V (arm64)).
|
||||
|
||||
Reference in New Issue
Block a user