mem_rs/process/
mod.rs

1// This file is part of the mem-rs distribution (https://github.com/FrankvdStam/mem-rs).
2// Copyright (c) 2022 Frank van der Stam.
3// https://github.com/FrankvdStam/mem-rs/blob/main/LICENSE
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, version 3.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17use std::cell::RefCell;
18use std::rc::Rc;
19use windows::Win32::Foundation::HANDLE;
20use crate::memory::MemoryType;
21use crate::process_data::{ProcessData};
22use crate::process_module::ProcessModule;
23mod inject_dll;
24mod scanning;
25mod read_write;
26mod refresh;
27mod process_modules;
28mod process_name;
29
30const STILL_ACTIVE: u32 = 259;
31
32/// Wraps a native process and allows memory access/manipulation
33///
34/// # Examples
35///
36/// ```
37/// use mem_rs::prelude::*;
38///
39/// let mut process = Process::new("name_of_process.exe");
40/// if process.refresh().is_ok()
41/// {
42///     process.write_memory_abs(0x1234, &u32::to_ne_bytes(10));
43///     let result = process.read_u32_rel(Some(0x1234));
44///     println!("Result: {}", result);
45/// }
46/// ```
47pub struct Process
48{
49    main_module: Option<ProcessModule>, //cache for pattern scans
50    process_data: Rc<RefCell<ProcessData>>
51}
52
53unsafe impl Sync for Process {}
54unsafe impl Send for Process {}
55
56impl Process
57{
58    /// Creates a new process based on the process name.
59    ///
60    /// # Examples
61    ///
62    /// ```
63    /// use mem_rs::prelude::*;
64    ///
65    /// let mut process = Process::new("name_of_process.exe");
66    /// ```
67    pub fn new(name: &str) -> Self
68    {
69        Process
70        {
71            main_module: None,
72            process_data: Rc::new(RefCell::new(ProcessData
73            {
74                name: String::from(name),
75                attached: false,
76                memory_type: MemoryType::Win32Api,
77                id: 0,
78                handle: HANDLE::default(),
79                is_64_bit: true,
80                filename: String::new(),
81                path: String::new(),
82            }))
83        }
84    }
85
86
87    /// Creates a new process based on the process name.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// use mem_rs::prelude::*;
93    ///
94    /// let mut process = Process::new_with_memory_type("name_of_process.exe", MemoryType::Direct);
95    /// ```
96    pub fn new_with_memory_type(name: &str, memory_type: MemoryType) -> Self
97    {
98        Process
99        {
100            main_module: None,
101            process_data: Rc::new(RefCell::new(ProcessData
102            {
103                name: String::from(name),
104                attached: false,
105                memory_type,
106                id: 0,
107                handle: HANDLE::default(),
108                is_64_bit: true,
109                filename: String::new(),
110                path: String::new(),
111            }))
112        }
113    }
114
115    /// Returns if the process is "attached" and can be read/written from/to
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use mem_rs::prelude::*;
121    ///
122    /// let mut process = Process::new("name_of_process.exe");
123    /// //returns false
124    /// let not_attached = process.is_attached();
125    ///
126    /// //refreshing the process will cause it to become attached
127    /// process.refresh().unwrap();
128    ///
129    /// //if name_of_process.exe is running, will return true
130    /// let attached = process.is_attached();
131    /// ```
132    pub fn is_attached(&self) -> bool {return self.process_data.borrow().attached;}
133
134    /// Returns file path of the processes' executable
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use mem_rs::prelude::*;
140    /// 
141    /// let mut process = Process::new("name_of_process.exe");
142    /// process.refresh().unwrap();
143    /// 
144    /// println!("{}", process.get_path());
145    /// ```
146    pub fn get_path(&self) -> String {return self.process_data.borrow().path.clone();}
147
148    pub fn is_64_bit(&self) -> bool {return self.process_data.borrow().is_64_bit.clone();  }
149
150    /// Returns handle of a process
151    pub fn get_handle(&self) -> HANDLE {
152        return self.process_data.borrow().handle.clone();
153    }
154
155    /// Returns id of a process
156    pub fn get_id(&self) -> u32 {
157        return self.process_data.borrow().id.clone();
158    }
159
160    ///Returns a copy of the main module
161    pub fn get_main_module(&self) -> ProcessModule
162    {
163        return self.main_module.as_ref().unwrap().clone();
164    }
165
166    ///returns a copy of all modules
167    pub fn get_modules(&self) -> Vec<ProcessModule>
168    {
169        return Process::get_process_modules(self.process_data.borrow().handle.clone(), &self.process_data);
170    }
171    ///returns if the process is using win32 API's to read/write memory
172    pub fn get_memory_type(&self) -> MemoryType
173    {
174        return self.process_data.borrow().memory_type.clone();
175    }
176}