retour\arch/
memory.rs

1use once_cell::sync::Lazy;
2
3use crate::{alloc, arch, error::Result, pic};
4use std::sync::Mutex;
5
6/// Shared allocator for all detours.
7pub static POOL: Lazy<Mutex<alloc::ThreadAllocator>> = Lazy::new(|| {
8  // Use a range of +/- 2 GB for seeking a memory block
9  Mutex::new(alloc::ThreadAllocator::new(arch::meta::DETOUR_RANGE))
10});
11
12/// Allocates PIC code at the specified address.
13pub fn allocate_pic(
14  pool: &mut alloc::ThreadAllocator,
15  emitter: &pic::CodeEmitter,
16  origin: *const (),
17) -> Result<alloc::ExecutableMemory> {
18  // Allocate memory close to the origin
19  pool.allocate(origin, emitter.len()).map(|mut memory| {
20    // Generate code for the obtained address
21    let code = emitter.emit(memory.as_ptr() as *const _);
22    memory.copy_from_slice(code.as_slice());
23    memory
24  })
25}