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:
Sai Ashwin
2024-12-07 12:19:23 +05:30
committed by GitHub
parent 7d8fe2ab11
commit 3a01515367
3 changed files with 93 additions and 0 deletions

View File

@@ -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,

View File

@@ -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)).