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}