scanmem alternative with concurrent memory scanning
at master 2.1 kB view raw
1use anyhow::Result; 2use libc::{c_void, iovec, process_vm_readv, process_vm_writev}; 3use log::info; 4 5use crate::process::{MemoryRegion, Process}; 6 7pub struct MemoryReader { 8 process: Process, 9} 10 11impl MemoryReader { 12 pub fn new(process: Process) -> Self { 13 Self { process } 14 } 15 16 pub fn read_memory(&self, address: usize, size: usize) -> Result<Vec<u8>> { 17 let mut buffer = vec![0u8; size]; 18 19 let local_iov = iovec { 20 iov_base: buffer.as_mut_ptr() as *mut c_void, 21 iov_len: size, 22 }; 23 24 let remote_iov = iovec { 25 iov_base: address as *mut c_void, 26 iov_len: size, 27 }; 28 29 let result = unsafe { 30 process_vm_readv( 31 self.process.pid as libc::pid_t, 32 &local_iov, 33 1, 34 &remote_iov, 35 1, 36 0, 37 ) 38 }; 39 40 if result == -1 { 41 let err = std::io::Error::last_os_error(); 42 anyhow::bail!("Failed to read memory at 0x{:x}: {}", address, err); 43 } 44 45 Ok(buffer) 46 } 47 48 pub fn write_memory(&self, address: usize, data: &[u8]) -> Result<()> { 49 let local_iov = iovec { 50 iov_base: data.as_ptr() as *mut c_void, 51 iov_len: data.len(), 52 }; 53 54 let remote_iov = iovec { 55 iov_base: address as *mut c_void, 56 iov_len: data.len(), 57 }; 58 59 let result = unsafe { 60 process_vm_writev( 61 self.process.pid as libc::pid_t, 62 &local_iov, 63 1, 64 &remote_iov, 65 1, 66 0, 67 ) 68 }; 69 70 if result == -1 { 71 let err = std::io::Error::last_os_error(); 72 anyhow::bail!("Failed to write memory at 0x{:x}: {}", address, err); 73 } 74 75 info!("setting *0x{:x} to {:?}...", address, data); 76 Ok(()) 77 } 78 79 pub fn read_region(&self, region: &MemoryRegion) -> Result<Vec<u8>> { 80 let size = region.end_addr - region.start_addr; 81 self.read_memory(region.start_addr, size) 82 } 83}