memory_rs/external/
process.rs1use std::ffi::{c_void, CStr};
2use std::io::Error;
3
4use windows_sys::Win32::Foundation::{CloseHandle, HANDLE, INVALID_HANDLE_VALUE};
5use windows_sys::Win32::System::Diagnostics::Debug::{ReadProcessMemory, WriteProcessMemory};
6use windows_sys::Win32::System::Diagnostics::ToolHelp::{
7 CreateToolhelp32Snapshot, Module32First, Module32Next, Process32First, Process32Next,
8 MODULEENTRY32, PROCESSENTRY32, TH32CS_SNAPMODULE, TH32CS_SNAPMODULE32, TH32CS_SNAPPROCESS,
9};
10use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS};
11
12pub struct Process {
13 pub h_process: HANDLE,
14 pub module_base_address: usize,
15}
16
17impl Process {
18 pub fn new(process_name: &str) -> Result<Process, Error> {
19 let process_id = get_process_id(process_name)?;
20 let module_base_address = get_module_base(process_id, process_name)?;
21
22 let h_process = unsafe { OpenProcess(PROCESS_ALL_ACCESS, false as i32, process_id) };
23
24 if h_process == 0 {
25 return Err(Error::last_os_error());
26 }
27
28 Ok(Process {
29 h_process,
30 module_base_address,
31 })
32 }
33
34 pub fn write_aob(&self, ptr: usize, data: &[u8], absolute: bool) {
37 let addr = if absolute {
38 ptr as _
39 } else {
40 self.module_base_address + ptr
41 };
42
43 crate::external::memory::write_aob(self.h_process, addr as _, &data);
44 }
45
46 pub fn write_nops(&self, ptr: usize, n: usize, absolute: bool) {
49 let addr = if absolute {
50 ptr as _
51 } else {
52 self.module_base_address + ptr
53 };
54
55 crate::external::memory::write_nops(self.h_process, addr as _, n);
56 }
57
58 pub fn get_aob(&self, ptr: usize, n: usize, absolute: bool) -> Vec<u8> {
61 let addr = if absolute {
62 ptr as _
63 } else {
64 self.module_base_address + ptr
65 };
66
67 let output: Vec<u8> = crate::external::memory::get_aob(self.h_process, addr as _, n);
68
69 output
70 }
71
72 pub fn read_value<OutputType>(&self, ptr: usize, absolute: bool) -> OutputType {
75 let addr = if absolute {
76 ptr as _
77 } else {
78 self.module_base_address + ptr
79 };
80
81 let mut buffer: OutputType = unsafe { std::mem::zeroed() };
82 let s_buffer: usize = std::mem::size_of::<OutputType>();
83 let mut read: usize = 0;
84
85 unsafe {
86 ReadProcessMemory(
87 self.h_process,
88 addr as *const c_void,
89 &mut buffer as *mut OutputType as *mut c_void,
90 s_buffer,
91 &mut read,
92 );
93 };
94
95 assert_eq!(read, s_buffer);
96 buffer
97 }
98
99 pub fn write_value<InputType>(&self, ptr: usize, output: InputType, absolute: bool) {
100 let addr = if absolute {
101 ptr
102 } else {
103 self.module_base_address + ptr
104 };
105
106 let s: usize = std::mem::size_of::<InputType>();
107 let mut written: usize = 0;
108
109 unsafe {
110 WriteProcessMemory(
111 self.h_process,
112 addr as *const c_void,
113 (&output as *const InputType) as *mut c_void,
114 s,
115 &mut written,
116 );
117 };
118
119 assert!(written != 0);
120 }
121
122 pub unsafe fn inject_shellcode(
131 &self,
132 entry_point: *const u32,
133 instruction_size: usize,
134 f_start: *const u8,
135 f_end: *const u8,
136 ) -> *const c_void {
137 crate::external::memory::inject_shellcode(
138 self.h_process,
139 self.module_base_address as _,
140 entry_point as _,
141 instruction_size,
142 f_start,
143 f_end,
144 )
145 }
146
147 }
181
182pub fn get_process_id(process_name: &str) -> Result<u32, Error> {
183 let mut process_id: u32 = 0;
184 let h_snap = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
185
186 if h_snap == INVALID_HANDLE_VALUE {
187 return Err(Error::last_os_error());
188 }
189
190 let mut process_entry: PROCESSENTRY32 = unsafe { std::mem::zeroed() };
191 process_entry.dwSize = std::mem::size_of::<PROCESSENTRY32> as _;
192
193 unsafe {
194 if Process32First(h_snap, &mut process_entry) == 1 {
195 process_id = loop {
196 let current_name = CStr::from_ptr(process_entry.szExeFile.as_ptr() as _)
197 .to_str()
198 .expect("No string found");
199
200 if current_name == process_name {
201 break process_entry.th32ProcessID;
202 }
203
204 if Process32Next(h_snap, &mut process_entry) == 0 {
205 break 0;
206 }
207 }
208 }
209
210 CloseHandle(h_snap);
211 }
212
213 if process_id == 0 {
214 return Err(Error::last_os_error());
215 }
216
217 Ok(process_id)
218}
219
220pub fn get_module_base(process_id: u32, module_name: &str) -> Result<usize, Error> {
221 let mut module_base_address = 0;
222 let h_snap =
223 unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, process_id) };
224
225 if h_snap == INVALID_HANDLE_VALUE {
226 return Err(Error::last_os_error());
227 }
228
229 let mut module_entry: MODULEENTRY32 = unsafe { std::mem::zeroed() };
230 module_entry.dwSize = std::mem::size_of::<MODULEENTRY32> as _;
231
232 unsafe {
233 if Module32First(h_snap, &mut module_entry) != 0 {
234 module_base_address = loop {
235 let current_name = CStr::from_ptr(module_entry.szModule.as_ptr() as _)
236 .to_str()
237 .expect("No string found");
238
239 if current_name == module_name {
240 break module_entry.modBaseAddr as usize;
241 }
242
243 if Module32Next(h_snap, &mut module_entry) == 0 {
244 break 0;
245 }
246 }
247 }
248
249 CloseHandle(h_snap);
250 }
251
252 if module_base_address == 0 {
253 return Err(Error::last_os_error());
254 }
255
256 Ok(module_base_address)
257}