Cross-platform process memory read/write for Rust.
Read and write memory in external processes on macOS, Linux, and Windows. Enumerate loaded modules and memory regions. Pure Rust, no C FFI wrappers.
[dependencies]
procmod-core = "2"Read a game's player health from a known memory address:
use procmod_core::{Address,Process};fnmain() -> procmod_core::Result<()>{let game = Process::attach(pid)?;// read the player's health at a known offsetlet health:f32 = unsafe{ game.read(Address::new(0x7FF6_1A00_4200))? };println!("player health: {}", health);Ok(())}// Existing read-write attachmentlet process = Process::attach(1234)?;// Capability-restricted attachment with no write methods and minimal Windows rightslet process = Process::attach_read_only(1234)?;println!("target architecture: {:?}", process.architecture());A 64-bit Windows inspector can attach to a 32-bit target. Use Address, Pointer32, and Pointer64 for target addresses rather than interpreting remote pointers as the inspector's usize.
// read a typed value (T must be valid for any bit pattern)let hp:f32 = unsafe{ process.read(address)? };// write a typed value
process.write(address,&100.0_f32)?;// raw byte operationslet bytes = process.read_bytes(address,64)?;
process.write_bytes(address,&[0x90,0x90,0x90])?;Find where a game's main executable or a specific DLL is loaded, then scan from its base address:
let modules = process.modules()?;for m in&modules {println!("{}: base={:#x} size={:#x}", m.name, m.base.value(), m.size);}// find a specific modulelet engine = modules.iter().find(|m| m.name == "engine.dll").unwrap();let scan_region = process.read_bytes_at(engine.base, engine.size)?;Understand what memory is mapped and with what permissions - useful for finding writable data segments or executable code:
let regions = process.regions()?;for r in®ions {println!("{:#x} ({} bytes) {}", r.base, r.size, r.protection);}// find all writable regionslet writable:Vec<_> = regions.iter().filter(|r| r.protection.write).collect();| Platform | Backend | Architectures |
|---|---|---|
| macOS | Mach VM (mach_vm_read_overwrite / mach_vm_write) | x86_64, arm64 |
| Linux | process_vm_readv / process_vm_writev | x86_64, arm64 |
| Windows | ReadProcessMemory / WriteProcessMemory | x86, x86_64 targets from an x86_64 inspector |
- macOS: Requires the
com.apple.security.cs.debuggerentitlement or running as root. SIP must allow task_for_pid on the target. - Linux: Requires
CAP_SYS_PTRACEor appropriateptrace_scopesettings. Reading a child process's memory generally works without extra privileges. - Windows: Requires
SeDebugPrivilegefor system processes. Standard user can read/write processes they own.
MIT