mem_rs/memory/base_read_write.rs
1use std::ffi::c_void;
2use std::ptr;
3use windows::Win32::Foundation::HANDLE;
4use windows::Win32::System::Diagnostics::Debug::{ReadProcessMemory, WriteProcessMemory};
5use crate::memory::MemoryType;
6
7pub trait BaseReadWrite
8{
9 /// Read memory relative to the object's location in memory. Supports an optional offset.
10 ///
11 /// # Example
12 ///
13 /// ```
14 /// use mem_rs::prelude::*;
15 ///
16 /// let mut process = Process::new("name_of_process.exe");
17 /// process.refresh()?;
18 /// let pointer = process.create_pointer(0x1234, vec![0]);
19 ///
20 /// let mut buffer: [u8; 8] = [0; 8];
21 /// let success = pointer.read_memory_rel(Some(0x1234), &mut buffer);
22 /// ```
23 fn read_memory_rel(&self, offset: Option<usize>, buffer: &mut [u8]) -> bool;
24
25 /// Write memory relative to the object's location in memory. Supports an optional offset.
26 ///
27 /// # Example
28 ///
29 /// ```
30 /// use mem_rs::prelude::*;
31 ///
32 /// let mut process = Process::new("name_of_process.exe");
33 /// process.refresh()?;
34 /// let pointer = process.create_pointer(0x1234, vec![0]);
35 ///
36 /// let mut buffer: [u8; 4] = [0x1, 0x2, 0x3, 0x4];
37 /// let success = pointer.write_memory_rel(Some(0x1234), &mut buffer);
38 /// ```
39 fn write_memory_rel(&self, offset: Option<usize>, buffer: &[u8]) -> bool;
40
41 /// Read memory from an absolute address
42 ///
43 /// # Example
44 ///
45 /// ```
46 /// use mem_rs::prelude::*;
47 ///
48 /// let mut process = Process::new("name_of_process.exe");
49 /// process.refresh()?;
50 /// let pointer = process.create_pointer(0x1234, vec![0]);
51 ///
52 /// let mut buffer: [u8; 8] = [0; 8];
53 /// let success = pointer.read_memory_abs(0x1234, &mut buffer);
54 /// ```
55 fn read_memory_abs(&self, address: usize, buffer: &mut [u8]) -> bool;
56
57 /// Write memory to an absolute address
58 ///
59 /// # Example
60 ///
61 /// ```
62 /// use mem_rs::prelude::*;
63 ///
64 /// let mut process = Process::new("name_of_process.exe");
65 /// process.refresh()?;
66 /// let pointer = process.create_pointer(0x1234, vec![0]);
67 ///
68 /// let mut buffer: [u8; 4] = [0x1, 0x2, 0x3, 0x4];
69 /// let success = pointer.write_memory_abs(0x1234, &mut buffer);
70 /// ```
71 fn write_memory_abs(&self, address: usize, buffer: &[u8]) -> bool;
72
73 /// Read memory into a buffer from a process handle
74 fn read_with_handle(&self, handle: HANDLE, memory_type: MemoryType, address: usize, buffer: &mut [u8]) -> bool
75 {
76 return match memory_type
77 {
78 MemoryType::Win32Api =>
79 {
80 let mut read_bytes = 0;
81 if unsafe { ReadProcessMemory(handle, address as *mut c_void, buffer.as_mut_ptr() as *mut c_void, buffer.len(), Some(&mut read_bytes)).is_err() }
82 {
83 return false;
84 }
85 read_bytes == buffer.len()
86 },
87 MemoryType::Direct =>
88 {
89 let slice = unsafe { std::slice::from_raw_parts(address as *const u8, buffer.len()) };
90 buffer.clone_from_slice(slice);
91 true //error handling?
92 }
93 }
94 }
95
96 /// Write from a buffer ino memory from a process handle
97 fn write_with_handle(&self, handle: HANDLE, memory_type: MemoryType, address: usize, buffer: &[u8]) -> bool
98 {
99 return match memory_type
100 {
101 MemoryType::Win32Api =>
102 {
103 let mut wrote_bytes = 0;
104 if unsafe { WriteProcessMemory(handle, address as *mut c_void, buffer.as_ptr() as *mut c_void, buffer.len(), Some(&mut wrote_bytes)).is_err() }
105 {
106 return false;
107 }
108 wrote_bytes == buffer.len()
109 },
110 MemoryType::Direct =>
111 {
112 unsafe{ ptr::write_volatile(address as *mut &[u8], buffer); }
113 true
114 },
115 }
116 }
117}