process_memory_reader/
lib.rs

1//! Crate for reading process memory.
2//!
3//! # Example
4//! ```no_run
5//! use process_memory_reader::Process;
6//!
7//! let process = process_memory_reader::open_process(22212).unwrap();
8//! let base_address = process.base_address("Notepad.exe").unwrap();
9//!
10//! process.read_u8(base_address + 0x127).unwrap();
11//! ```
12
13#[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/// Errors that can be caught when trying to read process memory.
26#[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    /// Finds process module base address.
52    fn base_address(&self, module_name: &str) -> Option<usize>;
53
54    /// Read the specified length in bytes from the address memory.
55    fn read_bytes(&self, address: usize, buffer: &mut [u8]) -> Result<(), MemoryReadError>;
56
57    /// Read string until null char are read.
58    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}