1#![cfg(windows)]
18#![cfg_attr(docsrs, feature(doc_cfg))]
19
20use data::lc;
21use std::{collections::HashMap, ffi::c_void};
22use data::{PeMetadata, PVOID, PAGE_READWRITE};
23use nanorand::{Rng, BufferedRng, WyRand};
24
25pub struct Manager
27{
28 payloads: HashMap<usize, Vec<u8>>,
29 payloads_metadata: HashMap<usize, PeMetadata>,
30 decoys_metadata: HashMap<usize, PeMetadata>,
31 decoys: HashMap<usize, Vec<u8>>,
32 counter: HashMap<usize, i64>,
33 keys: HashMap<usize, u8>
34}
35
36impl Manager {
37 pub fn new () -> Manager {
39 Manager{
40 payloads: HashMap::new(),
41 payloads_metadata: HashMap::new(),
42 decoys_metadata: HashMap::new(),
43 decoys: HashMap::new(),
44 counter: HashMap::new(),
45 keys: HashMap::new(),
46 }
47 }
48
49 pub fn new_module (&mut self, address: usize, payload: Vec<u8>, decoy: Vec<u8>) -> Result<(), String>
51 {
52 if self.payloads.contains_key(&address)
53 {
54 return Err(lc!("[x] This address is already mapped."));
55 }
56
57 let payload_metadata = manualmap::get_pe_metadata(payload.as_ptr(), false)?;
58 let decoy_metadata = manualmap::get_pe_metadata(decoy.as_ptr(), false)?;
59
60 let mut rand_bytes = [0u8; 15];
61 let mut rng = BufferedRng::new(WyRand::new());
62 rng.fill(&mut rand_bytes);
63 let xor_key: u8 = rand_bytes.iter().fold(0u8, |acc, b| acc ^ b);
64
65 let xored_payload = Manager::xor_module(payload, xor_key);
66 let xored_decoy = Manager::xor_module(decoy, xor_key);
67
68 self.payloads.insert(address, xored_payload);
69 self.payloads_metadata.insert(address, payload_metadata);
70 self.decoys_metadata.insert(address, decoy_metadata);
71 self.decoys.insert(address, xored_decoy);
72 self.counter.insert(address, 1);
73 self.keys.insert(address, xor_key);
74
75 Manager::hide_module(self, address)?;
76
77 Ok(())
78 }
79
80 pub fn new_shellcode (&mut self, address: usize, payload: Vec<u8>, decoy: Vec<u8>) -> Result<(), String>
82 {
83 if self.payloads.contains_key(&address)
84 {
85 return Err(lc!("[x] This shellcode is already mapped."));
86 }
87
88 let mut rand_bytes = [0u8; 15];
89 let mut rng = BufferedRng::new(WyRand::new());
90 rng.fill(&mut rand_bytes);
91 let xor_key: u8 = rand_bytes.iter().fold(0u8, |acc, b| acc ^ b);
92
93 let xored_payload = Manager::xor_module(payload, xor_key);
94 let xored_decoy = Manager::xor_module(decoy, xor_key);
95
96 self.payloads.insert(address, xored_payload);
97 self.decoys.insert(address, xored_decoy);
98 self.counter.insert(address, 1);
99 self.keys.insert(address, xor_key);
100
101 Manager::hide_shellcode(self, address)?;
102
103 Ok(())
104 }
105
106 fn xor_module (module: Vec<u8>, key: u8) -> Vec<u8>
107 {
108 unsafe
109 {
110 let mut module_ptr = module.as_ptr();
111 let mut final_module: Vec<u8> = vec![];
112
113 for _i in 0..module.len()
114 {
115 final_module.push(*module_ptr ^ key);
116 module_ptr = module_ptr.add(1);
117 }
118
119 final_module
120 }
121 }
122
123 pub fn map_module (&mut self, address: usize) -> Result<(),String>
125 {
126 unsafe
127 {
128 if self.payloads.contains_key(&address)
129 {
130 if self.counter.get(&address).unwrap() == &0
131 {
132 let payload = self.payloads.get(&address).unwrap();
133 let key = *self.keys.get(&address).unwrap();
134 let pe_info = self.payloads_metadata.get(&address).unwrap();
135 let decoy_info = self.decoys_metadata.get(&address).unwrap();
136
137 let addr: PVOID = std::ptr::with_exposed_provenance_mut::<c_void>(address);
138 let handle = dyncvoke_core::INVALID_HANDLE_VALUE;
139
140 let mut base_addr_local: PVOID = addr;
141 let mut size_local: usize = if decoy_info.is_32_bit {
142 decoy_info.opt_header_32.SizeOfImage as usize
143 } else {
144 decoy_info.opt_header_64.size_of_image as usize
145 };
146 let mut old_protection_local: u32 = 0;
147
148 let ret = dyncvoke_core::nt_protect_virtual_memory(
149 handle,
150 &mut base_addr_local as *mut PVOID,
151 &mut size_local as *mut usize,
152 PAGE_READWRITE,
153 &mut old_protection_local as *mut u32,
154 );
155
156 if ret != 0
157 {
158 return Err(lc!("[x] Error changing memory protection."));
159 }
160
161 dyncvoke_core::rtl_zero_memory(base_addr_local, size_local);
162 let mut decrypted_payload = Manager::xor_module(payload.to_vec(), key);
163 let _r = manualmap::map_to_allocated_memory(decrypted_payload.as_ptr(), addr, pe_info)?;
164 let decrypted_payload_ptr = decrypted_payload.as_mut_ptr();
165
166 for i in 0..decrypted_payload.len()
167 {
168 *(decrypted_payload_ptr.add(i)) = 0u8;
169 }
170 }
171
172 self.counter.insert(address, self.counter[&address] + 1);
173
174 }
175
176 Ok(())
177 }
178 }
179
180 pub fn hide_module(&mut self, address: usize) -> Result<(),String>
182 {
183 if self.payloads.contains_key(&address)
184 {
185 if self.counter.get(&address).unwrap() == &1
186 {
187 let decoy = self.decoys.get(&address).unwrap();
188 let key = *self.keys.get(&address).unwrap();
189 let decrypted_decoy = Manager::xor_module(decoy.to_vec(), key);
190 let pe_info = self.decoys_metadata.get(&address).unwrap();
191 let addr: PVOID = std::ptr::with_exposed_provenance_mut::<c_void>(address);
192
193 let handle = dyncvoke_core::INVALID_HANDLE_VALUE;
194
195 let mut base_addr_local: PVOID = addr;
196 let mut size_local: usize = if pe_info.is_32_bit {
197 pe_info.opt_header_32.SizeOfImage as usize
198 } else {
199 pe_info.opt_header_64.size_of_image as usize
200 };
201 let mut old_protection_local: u32 = 0;
202
203 let ret = dyncvoke_core::nt_protect_virtual_memory(
204 handle,
205 &mut base_addr_local as *mut PVOID,
206 &mut size_local as *mut usize,
207 PAGE_READWRITE,
208 &mut old_protection_local as *mut u32,
209 );
210
211 if ret != 0
212 {
213 return Err(lc!("[x] Error changing memory protection."));
214 }
215
216 dyncvoke_core::rtl_zero_memory(base_addr_local, size_local);
217 let _r = manualmap::map_to_allocated_memory(decrypted_decoy.as_ptr(), addr, pe_info)?;
218 }
219
220 if self.counter.get(&address).unwrap() >= &1
221 {
222 self.counter.insert(address, self.counter[&address] - 1);
223 }
224 }
225
226 Ok(())
227 }
228
229 pub fn hide_shellcode(&mut self, address: usize) -> Result<(),String>
231 {
232 if self.payloads.contains_key(&address)
233 {
234 if self.counter.get(&address).unwrap() == &1
235 {
236 let decoy = self.decoys.get(&address).unwrap();
237 let key = *self.keys.get(&address).unwrap();
238 let decrypted_decoy = Manager::xor_module(decoy.to_vec(), key);
239 let result = overload::managed_module_stomping(&decrypted_decoy, address, 0);
240
241 if !result.is_ok()
242 {
243 return Err(lc!("[x] Error hiding shellcode."));
244 }
245 }
246
247 if self.counter.get(&address).unwrap() >= &1
248 {
249 self.counter.insert(address, self.counter[&address] - 1);
250 }
251
252 }
253
254 Ok(())
255
256 }
257
258 pub fn stomp_shellcode(&mut self, address: usize) -> Result<(),String>
260 {
261 if self.payloads.contains_key(&address)
262 {
263 if self.counter.get(&address).unwrap() == &0
264 {
265 let payload = self.payloads.get(&address).unwrap();
266 let key = *self.keys.get(&address).unwrap();
267 let mut decrypted_payload = Manager::xor_module(payload.to_vec(), key);
268 let result = overload::managed_module_stomping(&decrypted_payload, address, 0);
269 let decrypted_payload_ptr = decrypted_payload.as_mut_ptr();
270 unsafe
271 {
272 for i in 0..decrypted_payload.len()
273 {
274 *(decrypted_payload_ptr.add(i)) = 0u8;
275 }
276 }
277
278 if !result.is_ok()
279 {
280 return Err(lc!("[x] Error stomping shellcode."));
281 }
282
283 }
284
285 self.counter.insert(address, self.counter[&address] + 1);
286
287 }
288
289 Ok(())
290
291 }
292
293}
294
295#[cfg(test)]
296mod tests {
297 use super::*;
298
299 #[test]
300 fn test_manager_creation() {
301 let manager = Manager::new();
302
303 assert!(manager.payloads.is_empty());
304 assert!(manager.payloads_metadata.is_empty());
305 assert!(manager.decoys_metadata.is_empty());
306 assert!(manager.decoys.is_empty());
307 assert!(manager.counter.is_empty());
308 assert!(manager.keys.is_empty());
309 }
310
311 #[test]
312 fn test_xor_module() {
313 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
314 let key: u8 = 0x42;
315 let xored = Manager::xor_module(data.clone(), key);
316 for (i, &byte) in data.iter().enumerate() {
317 assert_eq!(xored[i], byte ^ key);
318 }
319 let de_xored = Manager::xor_module(xored, key);
320 assert_eq!(de_xored, data);
321 }
322
323 #[test]
324 fn test_xor_module_different_keys() {
325 let data = vec![0xFF, 0x00, 0xAA, 0x55, 0x12, 0x34];
326 let no_change = Manager::xor_module(data.clone(), 0x00);
327 assert_eq!(no_change, data);
328 let bitflip = Manager::xor_module(data.clone(), 0xFF);
329 for (i, &byte) in data.iter().enumerate() {
330 assert_eq!(bitflip[i], !byte);
331 }
332 let patterned = Manager::xor_module(data.clone(), 0xAA);
333 for (i, &byte) in data.iter().enumerate() {
334 assert_eq!(patterned[i], byte ^ 0xAA);
335 }
336 }
337
338 #[test]
339 fn test_xor_module_large_data() {
340 let size = 1024 * 1024;
341 let data: Vec<u8> = vec![0x42; size];
342 let key: u8 = 0x5A;
343 let xored = Manager::xor_module(data.clone(), key);
344 assert_eq!(xored.len(), size);
345 let restored = Manager::xor_module(xored, key);
346 assert_eq!(restored.len(), data.len());
347 assert_eq!(restored[0], 0x42);
348 }
349
350 #[test]
351 fn test_counter_tracking() {
352 let mut manager = Manager::new();
353 let address = 0x1000;
354 manager.counter.insert(address, 5);
355
356 assert_eq!(manager.counter.get(&address), Some(&5));
357
358 *manager.counter.get_mut(&address).unwrap() += 1;
360 assert_eq!(manager.counter.get(&address), Some(&6));
361 }
362
363 #[test]
364 fn test_key_storage() {
365 let mut manager = Manager::new();
366
367 let address = 0x2000;
368 let key: u8 = 0xAB;
369
370 manager.keys.insert(address, key);
371
372 assert_eq!(manager.keys.get(&address), Some(&key));
373 }
374
375 #[test]
377 fn test_payload_decoy_storage() {
378 let mut manager = Manager::new();
379
380 let address = 0x3000;
381 let payload = vec![0x90, 0x90, 0xCC]; let decoy = vec![0x55, 0x8B, 0xEC]; manager.payloads.insert(address, payload.clone());
385 manager.decoys.insert(address, decoy.clone());
386
387 assert_eq!(manager.payloads.get(&address), Some(&payload));
388 assert_eq!(manager.decoys.get(&address), Some(&decoy));
389 }
390
391 #[test]
393 fn test_metadata_storage() {
394 let mut manager = Manager::new();
395
396 let address = 0x4000;
397 let pe_metadata = PeMetadata::default();
398
399 manager.payloads_metadata.insert(address, pe_metadata.clone());
400 manager.decoys_metadata.insert(address, pe_metadata);
401
402 assert!(manager.payloads_metadata.get(&address).is_some());
403 assert!(manager.decoys_metadata.get(&address).is_some());
404 }
405
406 #[test]
408 fn test_hashmap_operations() {
409 let mut manager = Manager::new();
410
411 for i in 0..10 {
413 let addr = 0x10000 + (i * 0x1000);
414 manager.payloads.insert(addr, vec![i as u8]);
415 manager.counter.insert(addr, i as i64);
416 manager.keys.insert(addr, (i + 1) as u8);
417 }
418
419 assert_eq!(manager.payloads.len(), 10);
420 assert_eq!(manager.counter.len(), 10);
421 assert_eq!(manager.keys.len(), 10);
422
423 manager.payloads.remove(&(0x10000));
425 manager.counter.remove(&(0x10000));
426 manager.keys.remove(&(0x10000));
427
428 assert_eq!(manager.payloads.len(), 9);
429 }
430
431 #[test]
433 fn test_address_validation() {
434 let valid_addresses: Vec<u64> = vec![
436 0x1000,
437 0x10000,
438 0x140000000,
439 0x7FF60000,
440 ];
441
442 for addr in valid_addresses {
443 assert!(addr > 0);
444 assert_eq!(addr % 0x1000, 0);
446 }
447 }
448
449 #[test]
451 fn test_buffer_size_validation() {
452 let empty: Vec<u8> = vec![];
453 assert!(empty.is_empty());
454
455 let single_byte: Vec<u8> = vec![0x42];
456 assert_eq!(single_byte.len(), 1);
457
458 let page_size = 4096;
459 let page_buffer: Vec<u8> = vec![0x00; page_size];
460 assert_eq!(page_buffer.len(), page_size);
461 }
462}