Minimalistic rust library for dealing with processes, their modules and threads under Windows. Furthermore ProcMem provides some functions to read/write to/from memory addresses within these processes/modules and to find memory adresses based on byte pattern.
Use the package manager cargo to install ProcMem (cargo add proc_mem). Or copy the newest version number from crates.io and paste into your Cargo.toml file.
In order to get a running process you will have to
call [Process::with_name()
], [Process::with_pid()
] or [Process::all_with_name()
].
On success the returned value will be of type: [Process
].
use proc_mem::Process;
let chrome: Result<Process, ProcMemError> = Process::with_name("chrome.exe");
let firefox: Result<Process, ProcMemError> = Process::with_pid(12345);
let vscode: Result<Vec<Process>, ProcMemError> = Process::all_with_name("Code.exe");
use proc_mem::Process;
let chrome: Result<Process, ProcMemError> = Process::with_name("chrome.exe");
let did_terminate: bool = chrome.kill();
To get a module which was loaded by a process
you just have to call [Process::module()
].
which on success will return an instance of Module
.
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let desired_module: Result<Module,ProcMemError> = chrome.module("kernel32.dll");
To read memory you have to call [Process::read_mem()
].
This function takes a type and the address to read.
On success the read value will be returned.
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let module = chrome.module("kernel32.dll")?;
let read_value: Result<T, ProcMemError> = chrome.read_mem::<T>(module.base_address() + 0x1337);
To write memory you have to call [Process::write_mem()
].
This function takes a type and the address to write to.
the returned boolean will be true on success and false on failure
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let module = chrome.module("kernel32.dll")?;
let mut val_to_write: i32 = 1337;
let write_result: bool = chrome.write_mem::<T>(module.base_address() + 0x1337, val_to_write);
For the case that the region of memory you are trying to read/write
is protected e.g.: PAGE_READ and you need to change it,
you can use the function [Process::protect_mem()
].
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let module = chrome.module("kernel32.dll")?;
let mut old_protect: u32 = 0;
let protect_result: bool = chrome.protect_mem(module.base_address() + 0x1337, size_of::<i32>(), 0x4, &mut old_protect);
There is also a function to read pointer chains [Process::read_mem_chain()
].
This function takes a type and a Vec of addresses/offsets,
the first entry being the base address to start from.
On success the read value will be returned.
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let module = chrome.module("kernel32.dll")?;
let chain: Vec<usize> = vec![module.base_address(), 0xDEA964, 0x100]
let read_value: Result<T, ProcMemError> = chrome.read_mem_chain::<T>(chain);
If you dont want to read the value from the end of the chain
you can use the function: [Process::read_ptr_chain()
].
This function takes a Vec of addresses/offsets,
the first entry being the base address to start from.
On success the address at the end of the chain will be returned.
use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let module = chrome.module("kernel32.dll")?;
let chain: Vec<usize> = vec![module.base_address(), 0xDEA964, 0x100]
let desired_address: Result<usize, ProcMemError> = chrome.read_ptr_chain(chain);
It´s a pain to maintain offsets manually, but luckily proc_mem provides a way around that issue. You can scan modules for byte patterns and get the desired address this way.
use proc_mem::{Process, Module, Signature};
let some_game = Process::with_name("some_game.exe")?;
let module = some_game.module("module.dll")?;
let lp_signature = Signature {
name: "LocalPlayer",
pattern: "8D 34 85 ? ? ? ? 89 15 ? ? ? ? 8B 41 08 8B 48 04 83 F9 FF",
offsets: vec![3],
extra: 4,
relative: true,
rip_relative: false,
rip_offset: 0,
};
let lp_address: Result<usize,ProcMemError> = module.find_signature(&lp_signature);
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests and documentations as appropriate.