#process-memory #memory #process #module #read-write #patternscan

proc_mem

在Windows上管理进程、模块及其内存读写

6个版本

0.1.6 2023年12月21日
0.1.5 2023年12月18日
0.1.4 2023年4月27日

#34 in Windows API

Download history 16/week @ 2024-03-11 20/week @ 2024-04-01 15/week @ 2024-04-15 22/week @ 2024-04-22 5/week @ 2024-05-06 6/week @ 2024-05-13 18/week @ 2024-05-20 16/week @ 2024-05-27 17/week @ 2024-06-03 10/week @ 2024-06-10 13/week @ 2024-06-17 9/week @ 2024-06-24

每月51次下载

MIT/Apache

38KB
469

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