memory_rs/internal/
injections.rs1use std::ops::DerefMut;
2use std::slice::IterMut;
3
4use crate::internal::memory::{hook_function, write_aob, MemoryPattern};
5use crate::internal::memory_region::*;
6use anyhow::{Context, Result};
7
8pub trait Inject {
12 fn inject(&mut self);
13 fn remove_injection(&mut self);
14}
15
16#[derive(Debug)]
21pub struct Detour {
22 pub entry_point: usize,
24 f_orig: Vec<u8>,
26
27 new_function: usize,
29
30 function_end: Option<&'static mut usize>,
33}
34
35impl Detour {
36 pub fn new(
37 entry_point: usize,
38 size: usize,
39 new_function: usize,
40 function_end: Option<&'static mut usize>,
41 ) -> Detour {
42 let mut f_orig = vec![];
43
44 unsafe {
45 let slice_ = std::slice::from_raw_parts(entry_point as *const u8, size);
46 f_orig.extend_from_slice(slice_);
47 }
48
49 Detour {
50 entry_point,
51 f_orig,
52 new_function,
53 function_end,
54 }
55 }
56
57 pub fn new_from_aob(
60 scan: MemoryPattern,
61 region: &MemoryRegion,
62 new_function: usize,
63 function_end: Option<&'static mut usize>,
64 size_injection: usize,
65 offset: Option<isize>,
66 ) -> Result<Detour> {
67 let mut entry_point = region.scan_aob(&scan)?.context("Couldn't find aob")?;
68
69 if let Some(v) = offset {
70 entry_point = ((entry_point as isize) + v) as usize;
71 }
72
73 Ok(Detour::new(
74 entry_point,
75 size_injection,
76 new_function,
77 function_end,
78 ))
79 }
80}
81
82impl Inject for Detour {
83 fn inject(&mut self) {
84 unsafe {
85 hook_function(
86 self.entry_point,
87 self.new_function,
88 self.function_end.as_deref_mut(),
89 self.f_orig.len(),
90 )
91 .unwrap();
92 }
93 }
94
95 fn remove_injection(&mut self) {
96 unsafe {
97 write_aob(self.entry_point, &self.f_orig).unwrap();
98 }
99 }
100}
101
102#[cfg(feature = "impl-drop")]
103impl Drop for Detour {
104 fn drop(&mut self) {
105 self.remove_injection();
106 }
107}
108
109#[derive(Debug)]
114pub struct Injection {
115 pub entry_point: usize,
117 pub f_orig: Vec<u8>,
119 pub f_new: Vec<u8>,
121}
122
123impl Injection {
124 pub fn new(entry_point: usize, f_new: Vec<u8>) -> Injection {
125 let aob_size = f_new.len();
126 let slice = unsafe { std::slice::from_raw_parts(entry_point as *const u8, aob_size) };
127 let mut f_orig = Vec::new();
128 f_orig.extend_from_slice(slice);
129
130 Injection {
131 entry_point,
132 f_orig,
133 f_new,
134 }
135 }
136
137 pub fn new_from_aob(
162 region: &MemoryRegion,
163 f_new: Vec<u8>,
164 memory_pattern: MemoryPattern,
165 ) -> Result<Injection> {
166 let entry_point = region
167 .scan_aob(&memory_pattern)?
168 .context("Couldn't find aob")?;
169 Ok(Injection::new(entry_point, f_new))
170 }
171}
172
173impl Inject for Injection {
174 fn inject(&mut self) {
175 unsafe {
176 write_aob(self.entry_point, &(self.f_new)).unwrap();
177 }
178 }
179
180 fn remove_injection(&mut self) {
181 unsafe {
182 write_aob(self.entry_point, &(self.f_orig)).unwrap();
183 }
184 }
185}
186
187#[cfg(feature = "impl-drop")]
188impl Drop for Injection {
189 fn drop(&mut self) {
190 self.remove_injection();
191 }
192}
193
194pub struct StaticElement {
197 addr: usize,
198 original_value: Option<u32>,
199}
200
201impl StaticElement {
202 pub fn new(addr: usize) -> StaticElement {
203 let original_value = unsafe { Some(*(addr as *mut u32)) };
204
205 StaticElement {
206 addr,
207 original_value,
208 }
209 }
210}
211
212impl Inject for StaticElement {
213 fn inject(&mut self) {
214 unsafe {
215 let ptr = self.addr as *mut u32;
216 if self.original_value.is_none() {
217 self.original_value = Some(*ptr);
218 }
219 *ptr = 0;
220 }
221 }
222
223 fn remove_injection(&mut self) {
224 if self.original_value.is_none() {
225 return;
226 }
227 unsafe {
228 let ptr = self.addr as *mut u32;
229 *ptr = self.original_value.unwrap();
230 }
231
232 self.original_value = None;
233 }
234}
235
236#[cfg(feature = "impl-drop")]
237impl Drop for StaticElement {
238 fn drop(&mut self) {
239 self.remove_injection();
240 }
241}
242
243impl Inject for Box<dyn Inject> {
244 fn inject(&mut self) {
245 self.deref_mut().inject();
246 }
247
248 fn remove_injection(&mut self) {
249 self.deref_mut().remove_injection();
250 }
251}
252
253impl<T: Inject> Inject for IterMut<'_, T> {
254 fn inject(&mut self) {
255 self.for_each(|x| x.inject());
256 }
257
258 fn remove_injection(&mut self) {
259 self.for_each(|x| x.remove_injection());
260 }
261}