diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8c1afe6..8a5e35e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -42,92 +42,58 @@ jobs: rust_project_path: src-rust rust_branch: nightly - build-c-libs: + build-c-libs-linux: + runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - include: - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - features: "c_exports" - - os: ubuntu-latest - target: i686-unknown-linux-gnu - features: "c_exports" - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - features: "c_exports" - - os: windows-latest - target: x86_64-pc-windows-msvc - features: "c_exports" - - os: windows-latest - target: i686-pc-windows-msvc - features: "c_exports" - - os: windows-latest - target: aarch64-pc-windows-msvc - features: "c_exports" - - os: macos-latest - target: x86_64-apple-darwin - features: "c_exports" - - os: macos-latest - target: aarch64-apple-darwin - features: "c_exports" - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - features: "c_exports,size_opt" - - os: ubuntu-latest - target: i686-unknown-linux-gnu - features: "c_exports,size_opt" - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - features: "c_exports,size_opt" - - os: windows-latest - target: x86_64-pc-windows-msvc - features: "c_exports,size_opt" - - os: windows-latest - target: i686-pc-windows-msvc - features: "c_exports,size_opt" - - os: windows-latest - target: aarch64-pc-windows-msvc - features: "c_exports,size_opt" - - os: macos-latest - target: x86_64-apple-darwin - features: "c_exports,size_opt" - - os: macos-latest - target: aarch64-apple-darwin - features: "c_exports,size_opt" - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - features: "c_exports,size_opt,no_format" - - os: ubuntu-latest - target: i686-unknown-linux-gnu - features: "c_exports,size_opt,no_format" - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - features: "c_exports,size_opt,no_format" - - os: windows-latest - target: x86_64-pc-windows-msvc - features: "c_exports,size_opt,no_format" - - os: windows-latest - target: i686-pc-windows-msvc - features: "c_exports,size_opt,no_format" - - os: windows-latest - target: aarch64-pc-windows-msvc - features: "c_exports,size_opt,no_format" - - os: macos-latest - target: x86_64-apple-darwin - features: "c_exports,size_opt,no_format" - - os: macos-latest - target: aarch64-apple-darwin - features: "c_exports,size_opt,no_format" + os: [ubuntu-latest] + target: [x86_64-unknown-linux-gnu, i686-unknown-linux-gnu, aarch64-unknown-linux-gnu] + features: ["c_exports", "c_exports,size_opt", "c_exports,size_opt,no_format"] + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - id: build-libs + uses: Reloaded-Project/reloaded-project-configurations-rust/.github/actions/build-c-library@v1 + with: + rust_project_path: src-rust + target: ${{ matrix.target }} + features: ${{ matrix.features }} + build-c-libs-macos: runs-on: ${{ matrix.os }} - + strategy: + fail-fast: false + matrix: + os: [macos-latest] + target: [x86_64-apple-darwin, aarch64-apple-darwin] + features: ["c_exports", "c_exports,size_opt", "c_exports,size_opt,no_format"] steps: - uses: actions/checkout@v3 with: submodules: recursive + - id: build-libs + uses: Reloaded-Project/reloaded-project-configurations-rust/.github/actions/build-c-library@v1 + with: + rust_project_path: src-rust + target: ${{ matrix.target }} + features: ${{ matrix.features }} + build-c-libs-windows: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest] + target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, aarch64-pc-windows-msvc] + features: ["c_exports,external_processes", "c_exports,size_opt,external_processes", "c_exports,size_opt,no_format,external_processes"] + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive - id: build-libs - uses: Reloaded-Project/reloaded-project-configurations-rust/.github/actions/build-c-library@v1 # upgrade if needed + uses: Reloaded-Project/reloaded-project-configurations-rust/.github/actions/build-c-library@v1 with: rust_project_path: src-rust target: ${{ matrix.target }} @@ -155,7 +121,7 @@ jobs: header_file: bindings_c.h publish-artifacts: - needs: ["build-c-headers", "build-c-libs", "test-wine", "test-native"] + needs: ["build-c-headers", "build-c-libs-windows", "build-c-libs-linux", "build-c-libs-macos", "test-wine", "test-native"] # Publish only on tags if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest diff --git a/README.md b/README.md index 1fb77e9..d1b316d 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,8 @@ 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] - `c_exports` Provides C exports for the library. 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 7712f4b..8158d01 100644 --- a/src-rust/Cargo.lock +++ b/src-rust/Cargo.lock @@ -317,7 +317,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -346,7 +346,7 @@ checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -567,7 +567,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -578,7 +578,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix 0.38.4", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -812,7 +812,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -992,13 +992,12 @@ checksum = "4bf2521270932c3c7bed1a59151222bd7643c79310f2916f01925e1e16255698" [[package]] name = "reloaded-memory-buffers" -version = "3.3.1" +version = "4.0.0" dependencies = [ "clf", "criterion", "dirs", "errno", - "lazy_static", "libc", "mach", "memoffset 0.9.0", @@ -1006,7 +1005,7 @@ dependencies = [ "pprof", "rstest", "spin", - "windows", + "windows-sys 0.52.0", ] [[package]] @@ -1073,7 +1072,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.3.8", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1086,7 +1085,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.3", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1259,7 +1258,7 @@ dependencies = [ "fastrand", "redox_syscall 0.3.5", "rustix 0.37.25", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1433,7 +1432,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -1442,7 +1441,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -1451,13 +1459,28 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1466,38 +1489,80 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/src-rust/Cargo.toml b/src-rust/Cargo.toml index ce0a298..001e55e 100644 --- a/src-rust/Cargo.toml +++ b/src-rust/Cargo.toml @@ -10,8 +10,10 @@ repository = "https://github.com/Reloaded-Project/Reloaded.Memory.Buffers" 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 = [] size_opt = ["nightly"] @@ -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" @@ -41,8 +42,8 @@ mach = "0.3.2" mmap-rs-with-map-from-existing = "0.6.0" clf = "0.1.7" -[target.'cfg(target_os = "windows")'.dependencies.windows] -version = "0.48.0" +[target.'cfg(target_os = "windows")'.dependencies.windows-sys] +version = "0.52.0" features = [ "Win32_System_Memory", "Win32_Foundation", 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 7d706a3..1f11a5d 100644 --- a/src-rust/src/internal/buffer_allocator_windows.rs +++ b/src-rust/src/internal/buffer_allocator_windows.rs @@ -3,22 +3,20 @@ 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; -use core::mem::size_of; +use core::mem::{size_of, zeroed}; use core::sync::atomic::AtomicI32; -use windows::Win32::Foundation::{CloseHandle, BOOL, HANDLE}; -use windows::Win32::System::Memory::{ - VirtualAlloc, VirtualAllocEx, VirtualFree, VirtualFreeEx, VirtualQuery, VirtualQueryEx, - MEMORY_BASIC_INFORMATION, MEM_COMMIT, MEM_FREE, MEM_RELEASE, MEM_RESERVE, - PAGE_EXECUTE_READWRITE, +use windows_sys::Win32::Foundation::{CloseHandle, BOOL, HANDLE}; +use windows_sys::Win32::System::Memory::{ + VirtualAlloc, VirtualFree, VirtualQuery, MEMORY_BASIC_INFORMATION, MEM_COMMIT, MEM_FREE, + MEM_RELEASE, MEM_RESERVE, PAGE_EXECUTE_READWRITE, }; -use windows::Win32::System::SystemInformation::{GetSystemInfo, SYSTEM_INFO}; -use windows::Win32::System::Threading; -use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; -use Threading::IsWow64Process; +use windows_sys::Win32::System::SystemInformation::{GetSystemInfo, SYSTEM_INFO}; +use windows_sys::Win32::System::Threading::IsWow64Process; +use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; // Abstractions for kernel32 functions // pub trait Kernel32 { @@ -39,19 +37,13 @@ impl Kernel32 for LocalKernel32 { lp_address: *const c_void, lp_buffer: &mut MEMORY_BASIC_INFORMATION, ) -> usize { - unsafe { - VirtualQuery( - Some(lp_address), - lp_buffer, - size_of::(), - ) - } + unsafe { VirtualQuery(lp_address, lp_buffer, size_of::()) } } fn virtual_alloc(&self, lp_address: *const c_void, dw_size: usize) -> *mut c_void { unsafe { VirtualAlloc( - Some(lp_address), + lp_address, dw_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, @@ -60,14 +52,16 @@ impl Kernel32 for LocalKernel32 { } fn virtual_free(&self, lp_address: *mut c_void, dw_size: usize) -> bool { - unsafe { VirtualFree(lp_address, dw_size, MEM_RELEASE).as_bool() } + unsafe { VirtualFree(lp_address, dw_size, MEM_RELEASE) != 0 } } } +#[cfg(feature = "external_process")] pub struct RemoteKernel32 { handle: HANDLE, } +#[cfg(feature = "external_process")] impl Kernel32 for RemoteKernel32 { fn virtual_query( &self, @@ -77,7 +71,7 @@ impl Kernel32 for RemoteKernel32 { unsafe { VirtualQueryEx( self.handle, - Some(lp_address), + lp_address, lp_buffer, size_of::(), ) @@ -88,7 +82,7 @@ impl Kernel32 for RemoteKernel32 { unsafe { VirtualAllocEx( self.handle, - Some(lp_address), + lp_address, dw_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, @@ -97,7 +91,7 @@ impl Kernel32 for RemoteKernel32 { } fn virtual_free(&self, lp_address: *mut c_void, dw_size: usize) -> bool { - unsafe { VirtualFreeEx(self.handle, lp_address, dw_size, MEM_RELEASE).as_bool() } + unsafe { VirtualFreeEx(self.handle, lp_address, dw_size, MEM_RELEASE) != 0 } } } @@ -108,25 +102,24 @@ pub(crate) struct ProcessHandle { impl ProcessHandle { // open_process opens a new process with the given id and returns a ProcessHandle. - pub unsafe fn open_process(id: u32) -> Result { - let handle = OpenProcess(PROCESS_ALL_ACCESS, false, id); - - match handle { - Ok(x) => Ok(Self { handle: x }), - Err(x) => Err(x), + pub unsafe fn open_process(id: u32) -> Self { + ProcessHandle { + handle: OpenProcess(PROCESS_ALL_ACCESS, 0, id), } } - // get_handle returns the internal HANDLE. - pub fn get_handle(&self) -> HANDLE { - self.handle + pub fn is_valid(&self) -> bool { + self.handle != 0 } } impl Drop for ProcessHandle { fn drop(&mut self) { unsafe { - CloseHandle(self.handle); + // Close non-null handle + if self.handle != 0 { + CloseHandle(self.handle); + } } } } @@ -134,25 +127,25 @@ 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 { // Is this Windows on Windows 64? (x86 app running on x64 Windows) let mut is_wow64: BOOL = Default::default(); - let has_is_wow64 = IsWow64Process(handle, &mut is_wow64).as_bool(); + let has_is_wow64 = IsWow64Process(handle, &mut is_wow64) != 0; - let mut system_info: SYSTEM_INFO = Default::default(); + let mut system_info: SYSTEM_INFO = zeroed(); GetSystemInfo(&mut system_info); let mut max_address = 0x7FFFFFFF; // 32bit max // If target is not using WoW64 emulation layer, trust GetSystemInfo for max address. - if !is_wow64.as_bool() && has_is_wow64 { + if is_wow64 == 0 && has_is_wow64 { max_address = system_info.lpMaximumApplicationAddress as usize; } @@ -167,20 +160,27 @@ pub fn allocate_windows( unsafe { let process_handle = ProcessHandle::open_process(settings.target_process_id); - if process_handle.is_err() { + if !process_handle.is_valid() { return Err(BufferAllocationError::new( *settings, "Failed to open process", )); } - let handle = process_handle.unwrap_unchecked().handle; + let handle = process_handle.handle; let max_address = get_max_windows_address(settings.target_process_id, handle); - return if CACHED.this_process_id == settings.target_process_id { - allocate_fast(&LocalKernel32 {}, max_address, &settings) - } else { - allocate_fast(&RemoteKernel32 { handle }, max_address, &settings) - }; + + #[cfg(feature = "external_process")] + { + 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) + }; + } + + #[cfg(not(feature = "external_process"))] + allocate_fast(&LocalKernel32 {}, max_address, settings) } } @@ -189,12 +189,12 @@ fn allocate_fast( mut max_address: usize, settings: &BufferAllocatorSettings, ) -> Result { - max_address = min(max_address, settings.max_address as usize); + max_address = min(max_address, settings.max_address); for _ in 0..settings.retry_count { // Until we get all of the pages. - let mut current_address = settings.min_address as usize; - let mut memory_information = MEMORY_BASIC_INFORMATION::default(); + let mut current_address = settings.min_address; + let mut memory_information: MEMORY_BASIC_INFORMATION = unsafe { zeroed() }; while current_address <= max_address { // Get our info from VirtualQueryEx. let has_page = @@ -208,7 +208,7 @@ fn allocate_fast( match try_allocate_buffer(k32, &mut memory_information, settings) { Some(item) => return Ok(item), None => { - current_address += memory_information.RegionSize as usize; + current_address += memory_information.RegionSize; } }; } @@ -217,8 +217,8 @@ fn allocate_fast( // See remarks on 'BruteForce' in BufferAllocatorSettings, as for why this code exists. // I'm not particularly fond of it, but what can you do? if settings.brute_force { - let mut current_address = settings.min_address as usize; - let mut memory_information = MEMORY_BASIC_INFORMATION::default(); + let mut current_address = settings.min_address; + let mut memory_information = unsafe { zeroed() }; while current_address <= max_address { let has_item = k32.virtual_query(current_address as *const c_void, &mut memory_information); @@ -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; } }; } @@ -243,7 +243,7 @@ fn allocate_fast( fn try_allocate_buffer( k32: &T, - mut page_info: &mut MEMORY_BASIC_INFORMATION, + page_info: &mut MEMORY_BASIC_INFORMATION, settings: &BufferAllocatorSettings, ) -> Option { // Fast return if page is not free. @@ -251,12 +251,12 @@ fn try_allocate_buffer( return None; } - let mut results = [0 as usize; 4]; + let mut results = [0; 4]; for addr in get_buffer_pointers_in_page_range( - &mut page_info, + page_info, settings.size as usize, - settings.min_address as usize, - settings.max_address as usize, + settings.min_address, + settings.max_address, &mut results, ) { let allocated = k32.virtual_alloc(*addr as *const c_void, settings.size as usize); @@ -290,8 +290,8 @@ fn get_buffer_pointers_in_page_range<'a>( results: &'a mut [usize; 4], ) -> &'a [usize] { let page_start = page_info.BaseAddress as usize; - let page_end = page_info.BaseAddress as usize + page_info.RegionSize as usize; - let allocation_granularity = CACHED.allocation_granularity; + let page_end = page_info.BaseAddress as usize + page_info.RegionSize; + 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 83c9954..19289ad 100644 --- a/src-rust/src/internal/memory_mapped_file_windows.rs +++ b/src-rust/src/internal/memory_mapped_file_windows.rs @@ -1,13 +1,14 @@ extern crate alloc; +use core::ffi::c_void; + use crate::internal::memory_mapped_file::MemoryMappedFile; use alloc::ffi::CString; -use windows::core::PCSTR; -use windows::imp::CloseHandle; -use windows::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE}; -use windows::Win32::System::Memory::{ +use windows_sys::Win32::Foundation::{CloseHandle, HANDLE, INVALID_HANDLE_VALUE}; +use windows_sys::Win32::Security::SECURITY_ATTRIBUTES; +use windows_sys::Win32::System::Memory::{ CreateFileMappingA, MapViewOfFile, OpenFileMappingA, UnmapViewOfFile, FILE_MAP_ALL_ACCESS, - MEMORYMAPPEDVIEW_HANDLE, PAGE_EXECUTE_READWRITE, + MEMORY_MAPPED_VIEW_ADDRESS, PAGE_EXECUTE_READWRITE, }; pub struct WindowsMemoryMappedFile { @@ -23,41 +24,31 @@ impl WindowsMemoryMappedFile { let mut already_existed = true; unsafe { - let mut map_handle = OpenFileMappingA( - FILE_MAP_ALL_ACCESS.0, - false, - PCSTR(file_name.as_ptr() as *const u8), - ); + let mut map_handle = + OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, file_name.as_ptr() as *const u8); // No file existed, as open failed. Try create a new one. - if map_handle.is_err() { + if map_handle == 0 { map_handle = CreateFileMappingA( INVALID_HANDLE_VALUE, - None, + core::ptr::null::(), PAGE_EXECUTE_READWRITE, 0, length as u32, - PCSTR(file_name.as_ptr() as *const u8), + file_name.as_ptr() as *const u8, ); already_existed = false; } - let data = MapViewOfFile( - HANDLE(map_handle.as_mut().unwrap().0), - FILE_MAP_ALL_ACCESS, - 0, - 0, - length, - ) - .unwrap() - .0 as *mut u8; + let data = + MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS, 0, 0, length).Value as *mut u8; WindowsMemoryMappedFile { already_existed, data, length, - map_handle: map_handle.unwrap(), + map_handle, } } } @@ -66,8 +57,10 @@ impl WindowsMemoryMappedFile { impl Drop for WindowsMemoryMappedFile { fn drop(&mut self) { unsafe { - UnmapViewOfFile(MEMORYMAPPEDVIEW_HANDLE(self.data as isize)); - CloseHandle(self.map_handle.0); + UnmapViewOfFile(MEMORY_MAPPED_VIEW_ADDRESS { + Value: self.data as *mut c_void, + }); + CloseHandle(self.map_handle); } } } @@ -87,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); @@ -111,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 bfc3303..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(); @@ -162,7 +168,7 @@ impl LocatorHeader { #[cfg(windows)] unsafe { - windows::Win32::System::Threading::SwitchToThread(); + windows_sys::Win32::System::Threading::SwitchToThread(); } } } @@ -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 83bfdd9..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(); @@ -81,7 +86,7 @@ impl LocatorItem { #[cfg(windows)] unsafe { - windows::Win32::System::Threading::SwitchToThread(); + windows_sys::Win32::System::Threading::SwitchToThread(); } } } 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 28fe7f9..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::Win32::System::Memory::{VirtualFree, VirtualFreeEx, MEM_RELEASE}, -}; +use windows_sys::Win32::System::Memory::{VirtualFree, MEM_RELEASE}; #[cfg(target_os = "macos")] use { @@ -31,7 +30,7 @@ pub struct PrivateAllocation { /// Exact size of allocated data. pub size: usize, - /// Function that frees the memory. + /// Id of the process where allocation is made. _this_process_id: u32, } @@ -96,23 +95,35 @@ impl PrivateAllocation { use core::ffi::c_void; unsafe { - if self._this_process_id == CACHED.this_process_id { + #[cfg(feature = "external_process")] + { + 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 { + // "Failed to free memory on Windows" + } + } else { + let process_handle = ProcessHandle::open_process(self._this_process_id); + let result = VirtualFreeEx( + process_handle.get_handle(), + self.base_address.as_ptr() as *mut c_void, + 0, + MEM_RELEASE, + ); + if result == 0 { + // "Failed to free memory on Windows in External Process" + } + }; + } + + #[cfg(not(feature = "external_process"))] + { let result = VirtualFree(self.base_address.as_ptr() as *mut c_void, 0, MEM_RELEASE); - if result.0 == 0 { + if result == 0 { // "Failed to free memory on Windows" } - } else { - let process_handle = ProcessHandle::open_process(self._this_process_id); - let result = VirtualFreeEx( - process_handle.unwrap().get_handle(), - self.base_address.as_ptr() as *mut c_void, - 0, - MEM_RELEASE, - ); - if result.0 == 0 { - // "Failed to free memory on Windows in External Process" - } - }; + } } } @@ -120,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, @@ -141,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 @@ -188,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 eeee776..a267fe9 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::Win32::System::{ +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 CACHED.as_ref().unwrap_unchecked(); + } + + CACHED = Some(Cached::new()); + return CACHED.as_ref().unwrap_unchecked(); + } } pub struct Cached { @@ -61,8 +70,10 @@ impl Cached { max_address: &mut usize, page_size: &mut i32, ) { + use core::mem::zeroed; + unsafe { - let mut info: SYSTEM_INFO = Default::default(); + let mut info: SYSTEM_INFO = zeroed(); GetSystemInfo(&mut info); *max_address = info.lpMaximumApplicationAddress as usize; diff --git a/src-rust/src/utilities/icache_clear.rs b/src-rust/src/utilities/icache_clear.rs index b53fc42..7678fc8 100644 --- a/src-rust/src/utilities/icache_clear.rs +++ b/src-rust/src/utilities/icache_clear.rs @@ -23,14 +23,14 @@ pub fn clear_instruction_cache(start: *const u8, end: *const u8) { #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] #[cfg(target_os = "windows")] // MSVC fix pub fn clear_instruction_cache(start: *const u8, end: *const u8) { - use windows::Win32::System::{ + use windows_sys::Win32::System::{ Diagnostics::Debug::FlushInstructionCache, Threading::GetCurrentProcess, }; unsafe { FlushInstructionCache( GetCurrentProcess(), - Some(start as *const core::ffi::c_void), + start as *const core::ffi::c_void, end as usize - start as usize, ); } 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