implement r/w of process memory
This commit is contained in:
@@ -10,4 +10,6 @@ pub enum Error {
|
||||
SnapshotError(String),
|
||||
#[error("failed to convert integer")]
|
||||
IntegerConversionError(#[from] std::num::TryFromIntError),
|
||||
#[error("failed to access process memory")]
|
||||
MemoryError(String),
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use windows::Win32::System::Threading::{
|
||||
OpenProcess, PROCESS_ALL_ACCESS, PROCESS_VM_READ, PROCESS_VM_WRITE,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Handle(pub HANDLE);
|
||||
|
||||
impl Deref for Handle {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
use super::handle::Handle;
|
||||
|
||||
use std::ffi::c_void;
|
||||
|
||||
use windows::Win32::System::Diagnostics::Debug::{ReadProcessMemory, WriteProcessMemory};
|
||||
|
||||
pub fn read_process_memory<T>(
|
||||
handle: &Handle,
|
||||
address: usize,
|
||||
value: &mut T,
|
||||
) -> Result<(), crate::Error> {
|
||||
unsafe {
|
||||
match ReadProcessMemory(
|
||||
handle.0,
|
||||
address as *const c_void,
|
||||
value as *mut T as *mut c_void,
|
||||
size_of::<T>(),
|
||||
None,
|
||||
) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(why) => {
|
||||
return Err(crate::Error::MemoryError(format!(
|
||||
"failed to read memory: {why}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_process_memory<T>(
|
||||
handle: &Handle,
|
||||
address: usize,
|
||||
value: &mut T,
|
||||
) -> Result<(), crate::Error> {
|
||||
unsafe {
|
||||
match WriteProcessMemory(
|
||||
handle.0,
|
||||
address as *const c_void,
|
||||
value as *mut T as *mut c_void,
|
||||
size_of::<T>(),
|
||||
None,
|
||||
) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(why) => {
|
||||
return Err(crate::Error::MemoryError(format!(
|
||||
"failed to write memory: {why}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
mod handle;
|
||||
mod memory;
|
||||
mod process;
|
||||
mod snapshot;
|
||||
|
||||
|
||||
+47
-9
@@ -1,16 +1,22 @@
|
||||
use super::{handle::Handle, snapshot};
|
||||
use super::{
|
||||
handle::Handle,
|
||||
memory::{read_process_memory, write_process_memory},
|
||||
snapshot,
|
||||
};
|
||||
|
||||
use derive_more::derive::Display;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Process {
|
||||
name: String,
|
||||
id: u32,
|
||||
base_address: usize,
|
||||
handle: Handle,
|
||||
pub name: String,
|
||||
pub id: u32,
|
||||
pub base_address: usize,
|
||||
pub handle: Handle,
|
||||
}
|
||||
|
||||
unsafe impl Send for Process {}
|
||||
unsafe impl Sync for Process {}
|
||||
|
||||
#[derive(Display)]
|
||||
pub enum Identifier {
|
||||
Id(u32),
|
||||
@@ -32,12 +38,13 @@ impl Process {
|
||||
"failed to find a process with identifier `{identifier}`",
|
||||
)));
|
||||
};
|
||||
let process = Self {
|
||||
let mut process = Self {
|
||||
name: snapshot.name,
|
||||
id: snapshot.id,
|
||||
base_address: 0,
|
||||
handle: Handle::from_pid(snapshot.id)?,
|
||||
};
|
||||
process.base_address = process.module(&process.name)?.base_address;
|
||||
Ok(process)
|
||||
}
|
||||
|
||||
@@ -50,7 +57,6 @@ impl Process {
|
||||
}
|
||||
|
||||
pub fn module(&self, name: &str) -> Result<snapshot::Module, crate::Error> {
|
||||
dbg!(snapshot::Module::get_modules(self.id)?);
|
||||
let Some(module) = snapshot::Module::get_modules(self.id)?
|
||||
.into_iter()
|
||||
.find(|snapshot| snapshot.name == name)
|
||||
@@ -61,4 +67,36 @@ impl Process {
|
||||
};
|
||||
Ok(module)
|
||||
}
|
||||
|
||||
pub fn read_mem<T: Default>(&self, address: usize) -> Result<T, crate::Error> {
|
||||
let mut value = Default::default();
|
||||
read_process_memory(&self.handle, address, &mut value)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn read_mem_from_ptr_chain<T: Default>(&self, chain: &[usize]) -> Result<T, crate::Error> {
|
||||
let mut chain = chain.to_vec();
|
||||
let mut address = chain.remove(0);
|
||||
while chain.len() > 1 {
|
||||
address += chain.remove(0);
|
||||
address = self.read_mem(address)?;
|
||||
}
|
||||
let value = self.read_mem(address + chain.remove(0))?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn get_addr_from_ptr_chain(&self, chain: &[usize]) -> Result<usize, crate::Error> {
|
||||
let mut chain = chain.to_vec();
|
||||
let mut address = chain.remove(0);
|
||||
while chain.len() > 1 {
|
||||
address += chain.remove(0);
|
||||
address = self.read_mem(address)?;
|
||||
}
|
||||
Ok(address + chain.remove(0))
|
||||
}
|
||||
|
||||
pub fn write_mem<T: Default>(&self, address: usize, mut value: T) -> Result<(), crate::Error> {
|
||||
write_process_memory(&self.handle, address, &mut value)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user