diff --git a/README.md b/README.md index 9f7296d..d1b316d 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ You can specify another process with `TargetProcess = someProcess` in `BufferAll ## Crate Features (Rust) +- `std`: [Enabled by Default] Enables use of standard library. - `external_processes`: Support external processes (windows only). - `no_format`: Disables formatting code in errors, saving ~8kB of space. - `size_opt`: Makes cold paths optimized for size instead of optimized for speed. [Requires 'nightly' Rust] diff --git a/docs/index.md b/docs/index.md index 379880a..0a93fdd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -250,6 +250,8 @@ Alternative overload also allows you to pass a 'context' variable. ### Crate Features (Rust) +- `std`: [Enabled by Default] Enables use of standard library. +- `external_processes`: Support external processes (windows only). - `no_format`: Disables formatting code in errors, saving ~8kB of space. - `size_opt`: Makes cold paths optimized for size instead of optimized for speed. [Requires 'nightly' Rust] - `c_exports` Provides C exports for the library. diff --git a/src-rust/Cargo.lock b/src-rust/Cargo.lock index a653ed7..8158d01 100644 --- a/src-rust/Cargo.lock +++ b/src-rust/Cargo.lock @@ -998,7 +998,6 @@ dependencies = [ "criterion", "dirs", "errno", - "lazy_static", "libc", "mach", "memoffset 0.9.0", diff --git a/src-rust/Cargo.toml b/src-rust/Cargo.toml index 4a970c9..001e55e 100644 --- a/src-rust/Cargo.toml +++ b/src-rust/Cargo.toml @@ -11,6 +11,8 @@ license = "GPL-3.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["std"] +std = [] external_processes = [] c_exports = [] no_format = [] @@ -19,7 +21,6 @@ nightly = [] # Optimizations for nightly builds. [dependencies] memoffset = "0.9.0" -lazy_static = "1.4.0" dirs = "5.0.1" errno = "0.3.3" spin = "0.9.8" diff --git a/src-rust/src/buffers.rs b/src-rust/src/buffers.rs index 6f8ff74..1aac735 100644 --- a/src-rust/src/buffers.rs +++ b/src-rust/src/buffers.rs @@ -232,7 +232,7 @@ mod tests { use crate::{ internal::locator_header_finder::LocatorHeaderFinder, structs::params::{BufferAllocatorSettings, BufferSearchSettings}, - utilities::cached::CACHED, + utilities::cached::get_sys_info, }; use std; @@ -253,8 +253,8 @@ mod tests { #[test] fn allocate_private_memory_up_to_max_address() { let mut settings = BufferAllocatorSettings::new(); - settings.min_address = CACHED.max_address / 2; - settings.max_address = CACHED.max_address; + settings.min_address = get_sys_info().max_address / 2; + settings.max_address = get_sys_info().max_address; let result = Buffers::allocate_private_memory(&mut settings); assert!(result.is_ok()); @@ -267,8 +267,8 @@ mod tests { #[test] fn get_buffer_baseline() { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -286,8 +286,8 @@ mod tests { #[test] fn memory_is_executable_x64() { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -317,8 +317,8 @@ mod tests { #[test] fn memory_is_executable_aarch64() { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -352,8 +352,8 @@ mod tests { #[case(256)] fn get_buffer_aligned_test(#[case] alignment: u32) { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -382,7 +382,7 @@ mod tests { #[test] fn get_buffer_with_proximity() { const SIZE: usize = 4096; - let base_address = CACHED.max_address - (std::i32::MAX as usize); + let base_address = get_sys_info().max_address - (std::i32::MAX as usize); unsafe { LocatorHeaderFinder::reset(); diff --git a/src-rust/src/c/buffers_c_buffers.rs b/src-rust/src/c/buffers_c_buffers.rs index 7b331e3..08bf5c1 100644 --- a/src-rust/src/c/buffers_c_buffers.rs +++ b/src-rust/src/c/buffers_c_buffers.rs @@ -344,7 +344,7 @@ mod tests { use crate::{ internal::locator_header_finder::LocatorHeaderFinder, structs::params::{BufferAllocatorSettings, BufferSearchSettings}, - utilities::cached::CACHED, + utilities::cached::get_sys_info, }; use rstest::rstest; use std; @@ -366,8 +366,8 @@ mod tests { #[test] fn allocate_private_memory_up_to_max_address() { let mut settings = BufferAllocatorSettings::new(); - settings.min_address = CACHED.max_address / 2; - settings.max_address = CACHED.max_address; + settings.min_address = get_sys_info().max_address / 2; + settings.max_address = get_sys_info().max_address; let result = buffers_allocate_private_memory(&mut settings); assert!(result.is_ok); @@ -380,8 +380,8 @@ mod tests { #[test] fn get_buffer_baseline() { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -403,8 +403,8 @@ mod tests { #[case(256)] fn get_buffer_aligned_test(#[case] alignment: u32) { let settings = BufferSearchSettings { - min_address: (CACHED.max_address / 2), - max_address: CACHED.max_address, + min_address: (get_sys_info().max_address / 2), + max_address: get_sys_info().max_address, size: 4096, }; @@ -431,7 +431,7 @@ mod tests { #[test] fn get_buffer_with_proximity() { const SIZE: usize = 4096; - let base_address = CACHED.max_address - (std::i32::MAX as usize); + let base_address = get_sys_info().max_address - (std::i32::MAX as usize); unsafe { LocatorHeaderFinder::reset(); diff --git a/src-rust/src/internal/buffer_allocator.rs b/src-rust/src/internal/buffer_allocator.rs index e363ca2..0d4b933 100644 --- a/src-rust/src/internal/buffer_allocator.rs +++ b/src-rust/src/internal/buffer_allocator.rs @@ -117,7 +117,7 @@ mod tests { use super::*; #[cfg(target_os = "windows")] use crate::internal::buffer_allocator_windows::{Kernel32, LocalKernel32}; - use crate::utilities::cached::CACHED; + use crate::utilities::cached::get_sys_info; use std::ffi::c_void; const ALLOCATION_GRANULARITY: usize = 65536; // Assuming 64KB Allocation Granularity @@ -298,7 +298,7 @@ mod tests { min_address: 0, max_address: i32::MAX as usize, size: 4096, - target_process_id: CACHED.this_process_id, + target_process_id: get_sys_info().this_process_id, retry_count: 8, brute_force: false, }; @@ -313,10 +313,10 @@ mod tests { #[test] fn can_allocate_up_to_max_address() { let mut settings = BufferAllocatorSettings { - min_address: CACHED.max_address / 2, - max_address: CACHED.max_address, + min_address: get_sys_info().max_address / 2, + max_address: get_sys_info().max_address, size: 4096, - target_process_id: CACHED.this_process_id, + target_process_id: get_sys_info().this_process_id, retry_count: 8, brute_force: false, }; diff --git a/src-rust/src/internal/buffer_allocator_linux.rs b/src-rust/src/internal/buffer_allocator_linux.rs index 0d3bcf5..f592af3 100644 --- a/src-rust/src/internal/buffer_allocator_linux.rs +++ b/src-rust/src/internal/buffer_allocator_linux.rs @@ -1,7 +1,7 @@ use crate::structs::errors::BufferAllocationError; use crate::structs::internal::LocatorItem; use crate::structs::params::BufferAllocatorSettings; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use crate::utilities::linux_map_parser::get_free_regions_from_process_id; use crate::{ internal::buffer_allocator::get_possible_buffer_addresses, @@ -49,7 +49,7 @@ unsafe fn try_allocate_buffer( entry.start_address, entry.end_address, settings.size as usize, - CACHED.allocation_granularity as usize, + get_sys_info().allocation_granularity as usize, buffer, ) { let allocated = mmap( diff --git a/src-rust/src/internal/buffer_allocator_mmap_rs.rs b/src-rust/src/internal/buffer_allocator_mmap_rs.rs index 95637f8..e74ee31 100644 --- a/src-rust/src/internal/buffer_allocator_mmap_rs.rs +++ b/src-rust/src/internal/buffer_allocator_mmap_rs.rs @@ -1,7 +1,7 @@ use crate::structs::errors::BufferAllocationError; use crate::structs::internal::LocatorItem; use crate::structs::params::BufferAllocatorSettings; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use crate::utilities::map_parser_utilities::get_free_regions; use crate::{ internal::buffer_allocator::get_possible_buffer_addresses, @@ -68,7 +68,7 @@ unsafe fn try_allocate_buffer( entry.start_address, entry.end_address, settings.size as usize, - CACHED.get_allocation_granularity() as usize, + get_sys_info().get_allocation_granularity() as usize, buffer, ) { let mmapoptions = MmapOptions::new(settings.size as usize) diff --git a/src-rust/src/internal/buffer_allocator_osx.rs b/src-rust/src/internal/buffer_allocator_osx.rs index f5d21af..1160121 100644 --- a/src-rust/src/internal/buffer_allocator_osx.rs +++ b/src-rust/src/internal/buffer_allocator_osx.rs @@ -2,7 +2,7 @@ use crate::internal::buffer_allocator::get_possible_buffer_addresses; use crate::structs::errors::BufferAllocationError; use crate::structs::internal::LocatorItem; use crate::structs::params::BufferAllocatorSettings; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use crate::utilities::wrappers::Unaligned; use core::cmp::min; use core::mem; @@ -17,7 +17,7 @@ use mach::vm_types::mach_vm_address_t; pub fn allocate_osx( settings: &BufferAllocatorSettings, ) -> Result { - let max_address = min(CACHED.max_address, settings.max_address); + let max_address = min(get_sys_info().max_address, settings.max_address); let min_address = settings.min_address; unsafe { @@ -179,7 +179,7 @@ fn get_buffer_pointers_in_page_range( ) -> &[usize] { let page_start = page_address; let page_end = page_address + page_size; - let allocation_granularity = CACHED.allocation_granularity; + let allocation_granularity = get_sys_info().allocation_granularity; unsafe { get_possible_buffer_addresses( minimum_ptr, diff --git a/src-rust/src/internal/buffer_allocator_windows.rs b/src-rust/src/internal/buffer_allocator_windows.rs index 61cea87..1f11a5d 100644 --- a/src-rust/src/internal/buffer_allocator_windows.rs +++ b/src-rust/src/internal/buffer_allocator_windows.rs @@ -3,7 +3,7 @@ use crate::internal::buffer_allocator::get_possible_buffer_addresses; use crate::structs::errors::BufferAllocationError; use crate::structs::internal::LocatorItem; use crate::structs::params::BufferAllocatorSettings; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use crate::utilities::mathematics::min; use crate::utilities::wrappers::Unaligned; use core::ffi::c_void; @@ -127,11 +127,11 @@ impl Drop for ProcessHandle { // Helpers // fn get_max_windows_address(process_id: u32, handle: HANDLE) -> usize { - if CACHED.this_process_id == process_id { + if get_sys_info().this_process_id == process_id { // Note: In WOW64 mode, the following rules apply: // - If current process is large address aware, this will return 0xFFFEFFFF. // - If it is not LAA, this should return 0x7FFEFFFF. - return CACHED.max_address; + return get_sys_info().max_address; } unsafe { @@ -172,7 +172,7 @@ pub fn allocate_windows( #[cfg(feature = "external_process")] { - return if CACHED.this_process_id == settings.target_process_id { + return if get_sys_info().this_process_id == settings.target_process_id { allocate_fast(&LocalKernel32 {}, max_address, &settings) } else { allocate_fast(&RemoteKernel32 { handle }, max_address, &settings) @@ -229,7 +229,7 @@ fn allocate_fast( match try_allocate_buffer(k32, &mut memory_information, settings) { Some(item) => return Ok(item), None => { - current_address += CACHED.allocation_granularity as usize; + current_address += get_sys_info().allocation_granularity as usize; } }; } @@ -291,7 +291,7 @@ fn get_buffer_pointers_in_page_range<'a>( ) -> &'a [usize] { let page_start = page_info.BaseAddress as usize; let page_end = page_info.BaseAddress as usize + page_info.RegionSize; - let allocation_granularity = CACHED.allocation_granularity; + let allocation_granularity = get_sys_info().allocation_granularity; unsafe { get_possible_buffer_addresses( diff --git a/src-rust/src/internal/locator_header_finder.rs b/src-rust/src/internal/locator_header_finder.rs index 8593ac5..e6e34e3 100644 --- a/src-rust/src/internal/locator_header_finder.rs +++ b/src-rust/src/internal/locator_header_finder.rs @@ -3,11 +3,10 @@ use core::ptr::null_mut; use crate::internal::memory_mapped_file::MemoryMappedFile; use crate::structs::internal::LocatorHeader; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use alloc::boxed::Box; use alloc::string::String; use alloc::string::ToString; -use lazy_static::lazy_static; use spin::Mutex; #[cfg(unix)] @@ -23,9 +22,7 @@ pub struct LocatorHeaderFinder {} static mut LOCATOR_HEADER_ADDRESS: *mut LocatorHeader = null_mut(); static mut MMF: Option> = None; -lazy_static! { - static ref GLOBAL_LOCK: Mutex<()> = Mutex::new(()); -} +static GLOBAL_LOCK: Mutex<()> = Mutex::new(()); /// The reason the variable was last found. #[cfg(test)] @@ -55,18 +52,18 @@ impl LocatorHeaderFinder { fn open_or_create_memory_mapped_file() -> Box { // no_std let mut name = String::from("/Reloaded.Memory.Buffers.MemoryBuffer, PID "); - name.push_str(&CACHED.this_process_id.to_string()); + name.push_str(&get_sys_info().this_process_id.to_string()); #[cfg(target_os = "windows")] return Box::new(WindowsMemoryMappedFile::new( &name, - CACHED.allocation_granularity as usize, + get_sys_info().allocation_granularity as usize, )); #[cfg(unix)] return Box::new(UnixMemoryMappedFile::new( &name, - CACHED.allocation_granularity as usize, + get_sys_info().allocation_granularity as usize, )); } @@ -202,7 +199,7 @@ mod tests { use crate::internal::locator_header_finder::LAST_FIND_REASON; use crate::structs::internal::locator_header::LENGTH_OF_PREALLOCATED_CHUNKS; use crate::structs::internal::LocatorHeader; - use crate::utilities::cached::CACHED; + use crate::utilities::cached::get_sys_info; #[test] #[cfg(not(target_os = "android"))] @@ -261,7 +258,7 @@ mod tests { assert!(!address.is_null()); let header = &*address; - let expected_num_items = ((CACHED.allocation_granularity + let expected_num_items = ((get_sys_info().allocation_granularity - std::mem::size_of::() as i32) as f64 / LENGTH_OF_PREALLOCATED_CHUNKS as f64) diff --git a/src-rust/src/internal/memory_mapped_file_unix.rs b/src-rust/src/internal/memory_mapped_file_unix.rs index 8f4d05a..7041687 100644 --- a/src-rust/src/internal/memory_mapped_file_unix.rs +++ b/src-rust/src/internal/memory_mapped_file_unix.rs @@ -178,7 +178,7 @@ impl MemoryMappedFile for UnixMemoryMappedFile { mod tests { #[cfg(not(target_os = "android"))] - use {super::*, crate::utilities::cached::CACHED}; + use {super::*, crate::utilities::cached::get_sys_info}; #[test] #[cfg(not(target_os = "android"))] @@ -186,9 +186,9 @@ mod tests { // Let's create a memory mapped file with a specific size. let file_name = format!( "/Reloaded.Memory.Buffers.MemoryBuffer.Test, PID {}", - CACHED.this_process_id + get_sys_info().this_process_id ); - let file_length = CACHED.allocation_granularity as usize; + let file_length = get_sys_info().allocation_granularity as usize; let mmf = UnixMemoryMappedFile::new(&file_name, file_length); assert!(!mmf.already_existed); @@ -204,10 +204,10 @@ mod tests { fn test_memory_mapped_file_data() { let file_name = format!( "/test_memory_mapped_file_data PID {}", - CACHED.this_process_id + get_sys_info().this_process_id ); - let file_length = CACHED.allocation_granularity as usize; + let file_length = get_sys_info().allocation_granularity as usize; println!("file_length: {:?}", file_length); let mmf = UnixMemoryMappedFile::new(&file_name, file_length); diff --git a/src-rust/src/internal/memory_mapped_file_windows.rs b/src-rust/src/internal/memory_mapped_file_windows.rs index 28e5ae6..19289ad 100644 --- a/src-rust/src/internal/memory_mapped_file_windows.rs +++ b/src-rust/src/internal/memory_mapped_file_windows.rs @@ -80,16 +80,16 @@ impl MemoryMappedFile for WindowsMemoryMappedFile { #[cfg(test)] mod tests { use super::*; - use crate::utilities::cached::CACHED; + use crate::utilities::cached::get_sys_info; #[test] fn test_windows_memory_mapped_file_creation() { // Let's create a memory mapped file with a specific size. let file_name = format!( "/Reloaded.Memory.Buffers.MemoryBuffer.Test, PID {}", - CACHED.this_process_id + get_sys_info().this_process_id ); - let file_length = CACHED.allocation_granularity as usize; + let file_length = get_sys_info().allocation_granularity as usize; let mmf = WindowsMemoryMappedFile::new(&file_name, file_length); assert_eq!(mmf.already_existed, false); @@ -104,10 +104,10 @@ mod tests { fn test_windows_memory_mapped_file_data() { let file_name = format!( "/Reloaded.Memory.Buffers.MemoryBuffer.Test, PID {}", - CACHED.this_process_id + get_sys_info().this_process_id ); - let file_length = CACHED.allocation_granularity as usize; + let file_length = get_sys_info().allocation_granularity as usize; let mmf = WindowsMemoryMappedFile::new(&file_name, file_length); // Let's test we can read and write to the data. diff --git a/src-rust/src/lib.rs b/src-rust/src/lib.rs index 8707095..cc276d0 100644 --- a/src-rust/src/lib.rs +++ b/src-rust/src/lib.rs @@ -53,7 +53,7 @@ Happy Hacking 💜 */ #![cfg_attr(feature = "nightly", feature(optimize_attribute))] -#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(feature = "std"), no_std)] pub mod structs { diff --git a/src-rust/src/structs/internal/locator_header.rs b/src-rust/src/structs/internal/locator_header.rs index ed7391b..10fd30b 100644 --- a/src-rust/src/structs/internal/locator_header.rs +++ b/src-rust/src/structs/internal/locator_header.rs @@ -4,7 +4,7 @@ use crate::structs::errors::ItemAllocationError; use crate::structs::internal::LocatorItem; use crate::structs::params::BufferAllocatorSettings; use crate::structs::SafeLocatorItem; -use crate::utilities::cached::CACHED; +use crate::utilities::cached::get_sys_info; use crate::utilities::wrappers::Unaligned; use core::alloc::Layout; use core::cell::Cell; @@ -48,6 +48,7 @@ impl LocatorHeader { #[allow(clippy::new_without_default)] #[cfg(test)] pub fn new() -> Self { + extern crate std; LocatorHeader { this_address: Unaligned::new(std::ptr::null_mut()), next_locator_ptr: Unaligned::new(std::ptr::null_mut::()), @@ -155,6 +156,11 @@ impl LocatorHeader { /// Acquires the lock, blocking until it can do so. pub fn lock(&mut self) { while !self.try_lock() { + #[cfg(all(feature = "std", not(unix), not(windows)))] + { + std::thread::yield_now(); + } + #[cfg(unix)] unsafe { libc::sched_yield(); @@ -332,10 +338,11 @@ impl LocatorHeader { } // Allocate the next locator. - let alloc_size = CACHED.allocation_granularity; + let alloc_size = get_sys_info().allocation_granularity; unsafe { let addr = alloc::alloc::alloc( - Layout::from_size_align(alloc_size as usize, CACHED.page_size as usize).unwrap(), + Layout::from_size_align(alloc_size as usize, get_sys_info().page_size as usize) + .unwrap(), ); if addr.is_null() { self.unlock(); @@ -355,9 +362,10 @@ impl LocatorHeader { #[cfg(test)] mod tests { + extern crate std; use crate::structs::internal::locator_header::{Unaligned, LENGTH, MAX_ITEM_COUNT}; use crate::structs::internal::LocatorHeader; - use crate::utilities::cached::CACHED; + use crate::utilities::cached::get_sys_info; use memoffset::offset_of; use std::alloc::{alloc, Layout}; use std::mem::{align_of, size_of}; @@ -580,8 +588,8 @@ mod tests { header.initialize(LENGTH); let size = 100; - let min_address = CACHED.max_address / 2; - let max_address = CACHED.max_address; + let min_address = get_sys_info().max_address / 2; + let max_address = get_sys_info().max_address; // Act let item_count = header.num_items; @@ -609,8 +617,8 @@ mod tests { header.num_items = MAX_ITEM_COUNT as u8; let size = 100; - let min_address = CACHED.max_address / 2; - let max_address = CACHED.max_address; + let min_address = get_sys_info().max_address / 2; + let max_address = get_sys_info().max_address; // Act let item_count = header.num_items; diff --git a/src-rust/src/structs/internal/locator_item.rs b/src-rust/src/structs/internal/locator_item.rs index a530519..ef1ba8a 100644 --- a/src-rust/src/structs/internal/locator_item.rs +++ b/src-rust/src/structs/internal/locator_item.rs @@ -74,6 +74,11 @@ impl LocatorItem { /// Acquires the lock, blocking until it can do so. pub fn lock(&mut self) { while !self.try_lock() { + #[cfg(all(feature = "std", not(unix), not(windows)))] + { + std::thread::yield_now(); + } + #[cfg(unix)] unsafe { libc::sched_yield(); diff --git a/src-rust/src/structs/params/buffer_allocator_settings.rs b/src-rust/src/structs/params/buffer_allocator_settings.rs index 148d8b5..481edd3 100644 --- a/src-rust/src/structs/params/buffer_allocator_settings.rs +++ b/src-rust/src/structs/params/buffer_allocator_settings.rs @@ -1,8 +1,6 @@ +use crate::utilities::{cached::get_sys_info, mathematics}; use core::cmp::max; -use crate::utilities::cached::CACHED; -use crate::utilities::mathematics; - /// Settings to pass to the buffer allocator. #[derive(Debug, Clone, Copy)] #[repr(C)] @@ -44,9 +42,9 @@ impl BufferAllocatorSettings { pub fn new() -> Self { Self { min_address: 0, - max_address: CACHED.max_address, + max_address: get_sys_info().max_address, size: 4096, - target_process_id: CACHED.this_process_id, + target_process_id: get_sys_info().this_process_id, retry_count: 8, brute_force: true, } @@ -75,14 +73,15 @@ impl BufferAllocatorSettings { /// Sanitizes the input values. pub fn sanitize(&mut self) { // On Windows, VirtualAlloc treats 0 as 'any address', we might aswell avoid this out the gate. - if cfg!(windows) && (self.min_address < CACHED.allocation_granularity as usize) { - self.min_address = CACHED.allocation_granularity as usize; + if cfg!(windows) && (self.min_address < get_sys_info().allocation_granularity as usize) { + self.min_address = get_sys_info().allocation_granularity as usize; } self.size = max(self.size, 1); - self.size = - mathematics::round_up(self.size as usize, CACHED.allocation_granularity as usize) - as u32; + self.size = mathematics::round_up( + self.size as usize, + get_sys_info().allocation_granularity as usize, + ) as u32; } } @@ -96,14 +95,15 @@ impl Default for BufferAllocatorSettings { mod tests { use super::*; + use crate::utilities::cached::get_sys_info; #[test] fn test_default_settings() { let settings = BufferAllocatorSettings::new(); assert_eq!(settings.min_address, 0); - assert_eq!(settings.max_address, CACHED.max_address); + assert_eq!(settings.max_address, get_sys_info().max_address); assert_eq!(settings.size, 4096); - assert_eq!(settings.target_process_id, CACHED.this_process_id); + assert_eq!(settings.target_process_id, get_sys_info().this_process_id); assert_eq!(settings.retry_count, 8); assert!(settings.brute_force); } @@ -124,7 +124,7 @@ mod tests { mathematics::subtract_with_underflow_cap(target, proximity) ); assert_eq!(settings.size, size as u32); - assert_eq!(settings.target_process_id, CACHED.this_process_id); + assert_eq!(settings.target_process_id, get_sys_info().this_process_id); assert_eq!(settings.retry_count, 8); assert!(settings.brute_force); } @@ -138,15 +138,20 @@ mod tests { settings.sanitize(); if cfg!(windows) { - assert_eq!(settings.min_address, CACHED.allocation_granularity as usize); + assert_eq!( + settings.min_address, + get_sys_info().allocation_granularity as usize + ); } else { assert_eq!(settings.min_address, 0); } assert_eq!( settings.size, - mathematics::round_up(max(1, 1) as usize, CACHED.allocation_granularity as usize) - as u32 + mathematics::round_up( + max(1, 1) as usize, + get_sys_info().allocation_granularity as usize + ) as u32 ); } } diff --git a/src-rust/src/structs/params/buffer_search_settings.rs b/src-rust/src/structs/params/buffer_search_settings.rs index b50b38e..5b78c26 100644 --- a/src-rust/src/structs/params/buffer_search_settings.rs +++ b/src-rust/src/structs/params/buffer_search_settings.rs @@ -1,5 +1,4 @@ -use crate::utilities::cached::CACHED; -use crate::utilities::mathematics; +use crate::utilities::{cached::get_sys_info, mathematics}; /// Settings to pass to buffer search mechanisms. #[derive(Debug, Clone, Copy)] @@ -20,7 +19,7 @@ impl BufferSearchSettings { pub fn new() -> Self { Self { min_address: 0, - max_address: CACHED.max_address, + max_address: get_sys_info().max_address, size: 4096, } } @@ -59,7 +58,7 @@ mod tests { fn test_default_settings() { let settings = BufferSearchSettings::new(); assert_eq!(settings.min_address, 0); - assert_eq!(settings.max_address, CACHED.max_address); + assert_eq!(settings.max_address, get_sys_info().max_address); assert_eq!(settings.size, 4096); } diff --git a/src-rust/src/structs/private_allocation.rs b/src-rust/src/structs/private_allocation.rs index e8cfe25..ae510ed 100644 --- a/src-rust/src/structs/private_allocation.rs +++ b/src-rust/src/structs/private_allocation.rs @@ -1,11 +1,10 @@ -use crate::utilities::cached::CACHED; use core::ptr::{self, NonNull}; +#[allow(unused_imports)] +use crate::utilities::cached::get_sys_info; + #[cfg(target_os = "windows")] -use { - crate::internal::buffer_allocator_windows::ProcessHandle, - windows_sys::Win32::System::Memory::{VirtualFree, VirtualFreeEx, MEM_RELEASE}, -}; +use windows_sys::Win32::System::Memory::{VirtualFree, MEM_RELEASE}; #[cfg(target_os = "macos")] use { @@ -98,7 +97,7 @@ impl PrivateAllocation { unsafe { #[cfg(feature = "external_process")] { - if self._this_process_id == CACHED.this_process_id { + if self._this_process_id == get_sys_info().this_process_id { let result = VirtualFree(self.base_address.as_ptr() as *mut c_void, 0, MEM_RELEASE); if result == 0 { @@ -132,7 +131,7 @@ impl PrivateAllocation { #[cfg(target_os = "macos")] pub(crate) fn drop_macos(&mut self) { unsafe { - if self._this_process_id == CACHED.this_process_id { + if self._this_process_id == get_sys_info().this_process_id { let result = mach_vm_deallocate( mach_task_self(), self.base_address.as_ptr() as mach_vm_address_t, @@ -153,7 +152,7 @@ impl PrivateAllocation { use libc::c_void; unsafe { - if self._this_process_id == CACHED.this_process_id { + if self._this_process_id == get_sys_info().this_process_id { let result = libc::munmap(self.base_address.as_ptr() as *mut c_void, self.size); if result != 0 { // Failed to free memory on Linux @@ -200,21 +199,24 @@ impl Drop for PrivateAllocation { #[cfg(test)] mod tests { - use crate::{internal::buffer_allocator, structs::params::BufferAllocatorSettings}; + use crate::{ + internal::buffer_allocator, structs::params::BufferAllocatorSettings, + utilities::cached::get_sys_info, + }; use super::*; #[test] fn test_private_allocation() { let mut settings = BufferAllocatorSettings::new(); - settings.min_address = CACHED.max_address / 2; - settings.max_address = CACHED.max_address; + settings.min_address = get_sys_info().max_address / 2; + settings.max_address = get_sys_info().max_address; let alloc = buffer_allocator::allocate(&mut settings).unwrap(); let result = PrivateAllocation::new( NonNull::::new(alloc.base_address.value as *mut u8).unwrap(), alloc.size as usize, - CACHED.this_process_id, + get_sys_info().this_process_id, ); assert_ne!(result.base_address().as_ptr() as usize, 0); diff --git a/src-rust/src/utilities/cached.rs b/src-rust/src/utilities/cached.rs index c3b9c3e..6cea214 100644 --- a/src-rust/src/utilities/cached.rs +++ b/src-rust/src/utilities/cached.rs @@ -1,12 +1,21 @@ -use lazy_static::lazy_static; #[cfg(target_os = "windows")] use windows_sys::Win32::System::{ SystemInformation::{GetSystemInfo, SYSTEM_INFO}, Threading::GetCurrentProcessId, }; -lazy_static! { - pub static ref CACHED: Cached = Cached::new(); +static mut CACHED: Option = None; + +pub fn get_sys_info() -> &'static Cached { + // No thread safety needed here (we're running code with no side effects), so we omit lazy_static to save on library space. + unsafe { + if CACHED.is_some() { + return unsafe { CACHED.as_ref().unwrap_unchecked() }; + } + + CACHED = Some(Cached::new()); + return unsafe { CACHED.as_ref().unwrap_unchecked() }; + } } pub struct Cached { diff --git a/src-rust/src/utilities/map_parser_utilities.rs b/src-rust/src/utilities/map_parser_utilities.rs index 8992634..5985360 100644 --- a/src-rust/src/utilities/map_parser_utilities.rs +++ b/src-rust/src/utilities/map_parser_utilities.rs @@ -1,6 +1,6 @@ extern crate alloc; -use super::cached::CACHED; +use super::cached::get_sys_info; use alloc::vec::Vec; // Generic structure to use for custom parsers. @@ -58,10 +58,10 @@ pub fn get_free_regions(regions: &[T]) -> Vec