8 个版本
0.1.8 | 2021 年 12 月 8 日 |
---|---|
0.1.7 | 2021 年 12 月 7 日 |
0.1.0 | 2021 年 11 月 22 日 |
#358 in Unix APIs
29 每月下载量
43KB
707 代码行数(不包括注释)
vmemory
Rust 库,用于读取/写入 Windows、macOS、Linux 和未来可能支持的 BSD 变体的其他进程的内存。这将在不考虑内存页面保护的情况下写入内存。
API
ProcessMemory::new_process(file_path: &str, arguments: &Vec<String>) -> Option<ProcessMemory>
在挂起状态下启动一个新的进程,通过 self.resume() 手动恢复,传递要启动的进程的文件路径和启动进程的参数。返回一个包含要解包的结构体的选项
ProcessMemory::attach_process(pid: u32) -> Option<ProcessMemory>
使用进程 ID (PID) 连接到进程。返回一个选项结构体,可以解包,这将允许内存读写操作
ProcessMemory::write_memory(&self, _address: usize, data: &Vec<u8>, offset: bool)
向进程写入内存。要写入的内存是位于远程进程中的 _address
位置的 data
参数中的内存。offset
布尔值将指定 _address
的值是否是相对于进程加载的第一个模块/映射的偏移量(true),或者是否是要写入的直接地址值(false)
例如,第一个模块加载在 0x00400000
offset
设置为 true,且 _address
= 5
内存将写入 0x00400005
ProcessMemory::read_memory(&self, _address: usize, size: usize, offset: bool) -> Vec<u8>
从 _address
的位置读取进程的内存,并按 size
读取 n 字节。offset
参数的规则与在 ProcessMemory::write_memory()
中指定的相同
ProcessMemory::resume(&self)
从挂起状态恢复进程(Linux/macOS 上的 SIGCONT。Windows 上的 CreateProcess 的第一个线程上的 ResumeThread)。这通常只在 Linux 上的 ptrace(2) 会话、macOS 上从挂起状态调用 posix_spawn(2) 或 Windows 上的 CreateProcess 时使用。基本上,所有 ProcessMemory::new_process()
调用都需要调用此函数
ProcessMemory::base(&self)
检索进程加载的第一个映射/模块的基本地址
示例
示例 1
使用 new_process
use vmemory::*;
fn main() {
//
// Spawn a new process in a suspended state with no arguments
//
let test = ProcessMemory::new_process(r"C:\TEST.EXE", &vec!["".to_string()]).unwrap();
//
// Write memory to the process at (base address + 0xA)
// Writing 4 bytes at this location, each byte = 9
//
test.write_memory(0xA, &vec![9, 9, 9, 9], true);
//
// Read memory to confirm the write was registered to the process, as well as a few additional bytes that
// were not written
//
let vmem = test.read_memory(0xA, 10, true);
for v in vmem {
print!("{:02X} ", v);
}
//
// Get the base address of the first module in the process, and print it out
//
println!("\nbase: {:08X}", test.base());
//
// Resume the process
//
test.resume();
}
示例 2
在这里我们使用 attach_process
而不是 new_process
。
注意这个例子中的 offset
布尔值(write_memory
和 read_memory
的第三个参数)。在这里,传递给 write_memory
的直接地址和传递给 read_memory
的偏移量指向进程内存中的同一位置。
use vmemory::*;
fn main() {
//
// Attach to a process with a process ID (PID) of 3145
// Immediately resume from the ptrace attachment
//
let mut test = ProcessMemory::attach_process(3145).unwrap();
test.resume();
//
// Write 5 bytes at the direct address (no offset) 0x5616B07DB000
//
let write_test: Vec<u8> = vec![7, 7, 9, 9, 9];
test.write_memory(0x5616B07DB000, &write_test, false);
//
// Read 5 bytes from the offset (0) relative to the base address of the first mapping/module in the process
//
let vmem = test.read_memory(0, 5, true);
for v in &vmem {
print!("{:02X} ", v);
}
//
// Print out the base address of the process
//
println!("\nbase: {:08X}", test.base());
}
依赖项
~2MB
~42K SLoC