Thoxy67/rust-pe
GitHub: Thoxy67/rust-pe
这是一个使用纯 Rust 编写的反射式 PE 加载器库,能够在不将文件写入磁盘的情况下,直接从内存加载并执行本地 PE 文件及 .NET 程序集。
Stars: 45 | Forks: 7
# rspe
使用纯 Rust (`no_std`) 编写的反射式 PE 加载器库。从内存加载本地和 .NET 程序集。
## 功能
- 本地 PE 加载 (C/C++/Rust/Go...)
- [x] 64 位 (x86_64)
- [x] 32 位 (x86)
- [x] ARM/ARM64 重定位支持
- [x] 架构验证 (PE 位数必须匹配宿主进程)
- .NET 程序集加载 (C#/VB/CLR)
- [x] 通过 CLR 托管执行 64 位 .NET
- [x] 通过 CLR 托管执行 32 位 .NET
- [x] 将命令行参数传递给 `Main(string[] args)`
- [x] 从 PE 元数据自动检测运行时版本
### PE 加载流程
1. 解析 DOS/NT 头部 (运行时支持 PE32 和 PE32+)
2. 将节映射到分配的内存中
3. 解析导入 (按名称和序号,PE32 为 4 字节 / PE32+ 为 8 字节 thunk)
4. 应用基址重定位 (HIGHLOW, DIR64, ARM_MOV32, THUMB_MOV32)
5. 解析延迟导入 (DataDirectory\[13\],现代 RVA 格式)
6. 注册异常处理程序 (RtlAddFunctionTable,仅限 x64/ARM64)
7. 设置每节内存保护
8. 调用 TLS 回调 (DLL_PROCESS_ATTACH)
9. 通过 CreateThread 执行入口点
10. 清理 (注销异常表,释放内存)
### 高级安全功能
- [x] 安全 Cookie 初始化 (`__security_cookie` 用于 /GS 缓冲区安全)
- [x] CFG (控制流保护) - 通过 `SetProcessValidCallTargets` 注册有效调用目标
- [x] SxS / 激活上下文 - 激活 GUI 应用程序的嵌入式清单
- [x] 绑定导入目录失效
### 导出表解析
用于从已加载的 PE 镜像解析导出的实用函数:
- `get_export_by_name(baseptr, ntheader, name)` — 按名称解析
- `get_export_by_ordinal(baseptr, ntheader, ordinal)` — 按序号解析
通过加载目标 DLL 自动处理转发的导出 (例如,`"NTDLL.RtlAllocateHeap"` 解析为 ntdll.dll 中的实际函数)。
### API Set 解析
使用 PEB ApiSetMap 自动将 Windows API sets (`api-ms-win-*`, `ext-ms-win-*`) 解析为其实际的宿主 DLL。这使加载从虚拟 API set DLL 导入的 PE 成为可能。
### 实用函数
- `utils::detect_platform(bytes)` — 检测 PE 是 32 位还是 64 位
- `utils::check_dotnet(pe)` — 检查 PE 是否为 .NET 程序集
- `utils::get_dotnet_version(pe)` — 从元数据中提取 .NET 运行时版本字符串
- `utils::rva_to_file_offset(pe, rva)` — 将 RVA 转换为原始文件偏移
### 支持的机器类型
| 架构 | 机器代码 | 位数 |
|--------------|--------------|---------|
| i386 | 0x014c | 32-bit |
| AMD64 | 0x8664 | 64-bit |
| IA64 | 0x0200 | 64-bit |
| ARM (ARMNT) | 0x01C4 | 32-bit |
| ARM64 | 0xAA64 | 64-bit |
### 错误处理
该库使用 `PeError` 枚举进行错误处理:
```
pub enum PeError {
InvalidPe,
FileTooSmall,
ArchMismatch, // PE bitness doesn't match host process
AllocFailed,
InvalidNtHeader,
ImportResolveFailed,
SectionOutOfBounds,
UnsupportedRelocationType,
ThreadCreationFailed,
VirtualProtectFailed,
DotNetError(&'static str),
}
```
## Cargo 功能
```
[dependencies]
rust-pe = { version = "0.1", default-features = true }
# 或禁用 .NET support 以减少 binary size:
rust-pe = { version = "0.1", default-features = false }
```
| 功能 | 默认 | 描述 |
|----------|---------|-------------------------------------|
| `dotnet` | Yes | 启用通过 CLR 托管执行 .NET 程序集 |
## 用法
### 基本用法 (嵌入式 PE)
```
use rust_pe::reflective_loader;
fn main() {
let data = include_bytes!("app.exe");
// Native PE or .NET assembly — detected automatically
unsafe {
reflective_loader(data).expect("failed to load PE");
}
}
```
### 使用命令行参数
```
use rust_pe::reflective_loader_with_args;
fn main() {
let data = include_bytes!("app.exe");
// Arguments are passed to native PE via PEB CommandLine patching
// or to .NET Main(string[] args) via CLR invocation
unsafe {
reflective_loader_with_args(data, &["arg1", "arg2"]).expect("failed");
}
}
```
### 从文件加载
```
use rust_pe::reflective_loader;
use std::fs;
fn main() {
let data = fs::read("path/to/executable.exe").expect("failed to read file");
unsafe {
reflective_loader(&data).expect("failed to load PE");
}
}
```
### 转发 CLI 参数
```
use rust_pe::reflective_loader_with_args;
fn main() {
let data = include_bytes!("app.exe");
let args: Vec = std::env::args().skip(1).collect();
let arg_refs: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
unsafe {
reflective_loader_with_args(data, &arg_refs).expect("failed");
}
}
```
### 参数传递工作原理
- **本地 PE**: 参数通过修补 PEB CommandLine 传递,因此 `GetCommandLineW()` 返回提供的参数
- **.NET 程序集**: 参数通过 CLR 调用直接传递给 `Main(string[] args)`
## `no_std` 支持
该库兼容 `no_std` (需要 `alloc`)。它不依赖标准库,适合受限环境或当二进制大小很重要时。
## 致谢 / 参考
特别感谢以下个人和项目对本项目的贡献:
- [memN0ps](https://github.com/memN0ps) 提供有用的 winapi rust 代码以供学习
- [trickster0](https://github.com/trickster0) 提供许多 OffensiveRust 代码以供学习
## 许可证
本项目采用 MIT 许可证 - 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
标签:API Set解析, ARM架构, CLR托管, Hakrawler, Native代码, no_std, OpenCanary, PEB, PE加载器, Rust, TLS回调, Windows内部机制, x86_64, 内存加载, 分布式计算, 反射式加载, 可视化界面, 安全特性, 导入表解析, 导出表解析, 延迟加载, 异常处理, 控制流保护, 无文件执行, 端点可见性, 网络流量审计, 通知系统, 重定位