6个版本

0.1.5 2024年7月4日
0.1.4 2024年7月4日

#44 in Windows API

Download history 309/week @ 2024-06-29 37/week @ 2024-07-06 12/week @ 2024-07-27

每月 138 次下载

MIT/Apache

40KB
536

ProcMem

ProcMem是一个用于在Windows下处理进程、其模块和线程的最简Rust库。此外,ProcMem提供了一些函数,用于读取/写入进程/模块中的内存地址,以及根据字节模式查找内存地址。

安装

使用包管理器cargo安装ProcMem(cargo add proc_mem)。或者从crates.io复制最新版本号,并将其粘贴到您的Cargo.toml文件中。

用法

示例:获取一个正在运行的进程

为了获取一个正在运行的进程,您需要调用 [Process::with_name()]、[Process::with_pid()] 或 [Process::all_with_name()]。成功返回的值将是类型: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();

示例:从进程获取模块

要获取由进程加载的模块,只需调用 [Process::module()]。成功将返回一个Module实例。

use proc_mem::{Process, Module};
let chrome = Process::with_name("chrome.exe")?;
let desired_module: Result<Module,ProcMemError> = chrome.module("kernel32.dll");

示例:读取/写入内存

要读取内存,必须调用 [Process::read_mem()]。此函数接受类型和读取的地址。成功读取的值将返回。

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);

要写入内存,您需要调用 [Process::write_mem()]。此函数接受一个类型和要写入的地址。返回的布尔值在成功时为 true,在失败时为 false。

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);

对于您尝试读取/写入的内存区域受保护的情况(例如:PAGE_READ),并且您需要更改它,可以使用函数 [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);

还有一个函数用于读取指针链 [Process::read_mem_chain()]。此函数接受一个类型和一个地址/偏移量 Vec,第一个条目是起始的基本地址。在成功的情况下,将返回读取的值。

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);

如果您不想从链的末尾读取值,可以使用函数:[Process::read_ptr_chain()]。此函数接受一个地址/偏移量 Vec,第一个条目是起始的基本地址。在成功的情况下,将返回链的末尾地址。

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);

示例:模式扫描

手动维护偏移量很麻烦,但幸运的是,proc_mem 提供了一种绕过此问题的方法。您可以通过这种方式扫描模块以查找字节模式并获取所需的地址。

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);

贡献

欢迎拉取请求。对于重大更改,请首先打开一个问题来讨论您想更改的内容。

请确保根据需要更新测试和文档。

许可协议

MIT

依赖关系

~2.1–3.5MB
~55K SLoC