mem_rs/process/scanning.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 crate::helpers::{scan, to_pattern};
18use crate::pointer::Pointer;
19use crate::prelude::*;
20
21impl Process
22{
23 /// Does an absolute scan (for x86 targets or for process code) where the target pointer is absolute
24 /// Takes a list of offsets to create pointer jumps down a bigger complex structure.
25 /// Pointers implement memory reading and writing.
26 ///
27 /// # Examples
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.scan_abs("Error message", "56 8B F1 8B 46 1C 50 A1 ? ? ? ? 32 C9", 8, vec![0, 0, 0])?;
35 /// ```
36 pub fn scan_abs(&self, error_name: &str, pattern: &str, scan_offset: usize, pointer_offsets: Vec<usize>) -> Result<Pointer, String>
37 {
38 let byte_pattern = to_pattern(pattern);
39 let scan_result = scan(&self.get_main_module().memory, &byte_pattern);
40 if scan_result.is_none()
41 {
42 return Err(String::from(format!("Scan failed: {}", error_name)));
43 }
44
45 let mut address = scan_result.unwrap();
46 address += self.get_main_module().base_address;
47 address += scan_offset;
48 return Ok(Pointer::new(self.process_data.clone(), self.is_64_bit(), address, pointer_offsets));
49 }
50
51 /// Does a relative scan (for x64 targets) where the target pointer is located relative to instruction's
52 /// size and location.
53 /// Takes a list of offsets to create pointer jumps down a bigger complex structure.
54 /// Pointers implement memory reading and writing.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// use mem_rs::prelude::*;
60 ///
61 /// let mut process = Process::new("name_of_process.exe");
62 /// process.refresh()?;
63 /// let pointer = process.scan_rel("Error message", "48 8b 05 ? ? ? ? 48 8b 50 10 48 89 54 24 60", 3, 7, vec![0])?;
64 /// ```
65 pub fn scan_rel(&self, error_name: &str, pattern: &str, scan_offset: usize, instruction_size: usize, pointer_offsets: Vec<usize>) -> Result<Pointer, String>
66 {
67 let byte_pattern = to_pattern(pattern);
68 let scan_result = scan(&self.get_main_module().memory, &byte_pattern);
69 if scan_result.is_none()
70 {
71 return Err(String::from(format!("Scan failed: {}", error_name)));
72 }
73
74 let address = scan_result.unwrap();
75 let address_value = self.read_u32_rel(Some(address + scan_offset));
76 let result = self.get_main_module().base_address + address + instruction_size + address_value as usize; //Relative jump
77
78 return Ok(Pointer::new(self.process_data.clone(), self.is_64_bit(), result, pointer_offsets));
79 }
80
81 /// Create a pointer without scanning from an absolute address and a list of offsets.
82 /// For special use cases where an address might be the result of some calculation.
83 ///
84 /// let network = vanilla.process.create_pointer(network_ptr as usize, vec![0xc, 0x6c978])
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// use mem_rs::prelude::*;
90 ///
91 /// let mut process = Process::new("name_of_process.exe");
92 /// process.refresh()?;
93 /// let magic_address = 0x1234;
94 /// let pointer = process.create_pointer(magic_address, vec![0xc, 0x10]);
95 /// ```
96 pub fn create_pointer(&self, address: usize, pointer_offsets: Vec<usize>) -> Pointer
97 {
98 return Pointer::new(self.process_data.clone(), self.is_64_bit(), address, pointer_offsets);
99 }
100}