#[cfg(target_os = "windows")]
pub mod inner {
pub mod windows;
pub use windows::*;
pub use windows::WindowsMemoryController as MemoryController;
}
#[cfg(target_os = "linux")]
pub mod inner {
pub mod linux;
pub use linux::*;
pub use linux::LinuxMemoryController as MemoryController;
}
pub mod error;
pub mod page;
pub mod table;
use std::{
ffi::{CStr, c_void},
ptr::NonNull,
};
pub use error::{MemoryError, Result};
pub use table::{HeapState, HookHeap, MemoryHeapHandle, MemoryWriteHandle};
use crate::mem::page::MemoryProtectionGuard;
pub type DefaultMemoryController = inner::MemoryController;
#[derive(Debug, Clone, Copy)]
pub enum MemoryProtection {
NoAccess,
ReadWrite,
ReadExecute,
Other(usize),
}
pub trait MemoryHandle: Sized {
fn from_ptr(ptr: NonNull<c_void>) -> Self;
fn as_ptr(&self) -> NonNull<c_void>;
}
pub trait MemoryController {
type Handle: MemoryHandle + Copy + Clone;
type AllocationInfoType: AllocationInfo<Self>;
unsafe fn get_symbol_address(
&self,
module: Option<&CStr>,
symbol: &CStr,
) -> Result<NonNull<c_void>>;
unsafe fn allocate_memory(&self, min_size: Option<usize>) -> Result<Self::AllocationInfoType>;
unsafe fn set_page_protection(
&self,
handle: Self::Handle,
size: usize,
protection: MemoryProtection,
) -> Result<()>;
fn protection_guard_for_page<'a>(
&'a self,
ptr: NonNull<c_void>,
on_enter: MemoryProtection,
on_exit: Option<MemoryProtection>,
) -> Result<MemoryProtectionGuard<'a, Self>>
where
Self: Sized;
fn protection_guard<'a>(
&'a self,
memory_start: Self::Handle,
memory_size: usize,
on_enter: MemoryProtection,
on_exit: MemoryProtection,
) -> Result<MemoryProtectionGuard<'a, Self>>
where
Self: Sized,
{
MemoryProtectionGuard::guard(self, on_enter, on_exit, memory_start, memory_size)
}
}
pub trait AllocationInfo<C: MemoryController + ?Sized>: Sized {
fn page_size(&self) -> usize;
fn allocation_size(&self) -> usize;
fn allocation_start(&self) -> C::Handle;
}