process_memory_reader/
lib.rs1#[cfg(target_os = "windows")]
14pub mod windows;
15#[cfg(target_os = "windows")]
16pub use windows::*;
17
18#[cfg(target_os = "linux")]
19pub mod linux;
20#[cfg(target_os = "linux")]
21pub use linux::*;
22
23use std::io::Error as IoError;
24
25#[derive(Debug)]
27pub enum MemoryReadError {
28 InaccessibleMemoryAddress { address: usize },
29 LessBytesRead { expected: usize, actual: usize },
30 IOError { io_error: IoError },
31}
32
33impl From<IoError> for MemoryReadError {
34 fn from(io_error: IoError) -> Self {
35 MemoryReadError::IOError { io_error }
36 }
37}
38
39macro_rules! define_number_read (
40 ($type: ident, $name: ident, $bytes: expr) => (
41 fn $name(&self, address: usize) -> Result<$type, MemoryReadError> {
42 let mut buffer = [0u8; $bytes];
43 self.read_bytes(address, &mut buffer)?;
44
45 Ok($type::from_le_bytes(buffer))
46 }
47 );
48);
49
50pub trait Process {
51 fn base_address(&self, module_name: &str) -> Option<usize>;
53
54 fn read_bytes(&self, address: usize, buffer: &mut [u8]) -> Result<(), MemoryReadError>;
56
57 fn read_string(&self, address: usize) -> Result<String, MemoryReadError> {
59 let mut buffer = Vec::new();
60 let mut index = 0;
61
62 loop {
63 let ch = self.read_u8(address + index as usize)?;
64
65 if ch == 0 {
66 break;
67 }
68
69 buffer.insert(index, ch);
70 index += 1;
71 }
72
73 Ok(String::from_utf8(buffer).unwrap_or(String::from("")))
74 }
75
76 fn read_u8(&self, address: usize) -> Result<u8, MemoryReadError> {
77 let mut buffer = [0u8; 1];
78 self.read_bytes(address, &mut buffer)?;
79
80 Ok(buffer[0])
81 }
82
83 fn read_bool(&self, address: usize) -> Result<bool, MemoryReadError> {
84 Ok(self.read_u8(address)? == 1)
85 }
86
87 define_number_read!(u32, read_u32, 4);
88 define_number_read!(u64, read_u64, 8);
89 define_number_read!(u128, read_u128, 16);
90 define_number_read!(i32, read_i32, 4);
91 define_number_read!(i64, read_i64, 8);
92 define_number_read!(f32, read_f32, 4);
93 define_number_read!(f64, read_f64, 8);
94}