adamvalves/easyanticheat-kernel-driver-re
GitHub: adamvalves/easyanticheat-kernel-driver-re
EasyAntiCheat.sys 内核驱动的技术逆向分析文档,系统拆解了其内核检测向量、Import混淆、栈帧验证及TPM硬件认证机制。
Stars: 0 | Forks: 0
# EasyAntiCheat.sys 内核驱动逆向 —— 技术剖析
对 `EasyAntiCheat.sys` 内核驱动(从 Rust 构建版本中提取)的深入逆向工程分析。本文档提供了关于 EAC 实现的内核检测向量、import 混淆例程、栈帧验证流水线以及硬件认证机制的技术概述。
## 1. Import 混淆 — `DecryptImport`
EAC 避免对其敏感的内核 API 使用标准的 Import Address Table (IAT) 解析。相反,该驱动程序从其用户模式对应的组件(`EasyAntiCheat_EOS`)中导入了一个 export:
- **Import Export**:`DecryptImport`
每个敏感内核 API 指针都在 runtime 动态解析,并根据调用点进行加密。调用点利用不同的按位运算、循环移位(例如,按 `1`、`5`、`11`、`15`、`21`、`23`、`29`、`39`、`41`、`45`、`47`、`55` 进行 ROR8)以及唯一的 64 位 XOR 密钥:
```
// SeRegisterImageVerificationCallback
func = ROR8(DecryptImport(&SeRegisterImageVerificationCallback), 55) ^ 0x110D352D969C8DD1;
// RtlWalkFrameChain
func = ROR8(DecryptImport(&RtlWalkFrameChain), 21) ^ 0x84720A4F2CD7A4C1;
// RtlVirtualUnwind
func = ROR8(~DecryptImport(&RtlVirtualUnwind), 1) ^ 0x2DBC37BB37609566;
// ExAcquirePushLockExclusiveEx
func = ROR8(DecryptImport(&ExAcquirePushLockExclusiveEx), 45) ^ 0x1CAD0BF732512BF7;
```
在整个二进制文件中发现了超过 **47 个加密的调用点**,掩盖了对以下函数的例程访问:
- `SeRegisterImageVerificationCallback` / `SeUnregisterImageVerificationCallback`
- `RtlWalkFrameChain`, `RtlVirtualUnwind`, `RtlLookupFunctionEntry`
- `ExAcquirePushLockExclusiveEx`, `ExReleasePushLockExclusiveEx`
- `Tbsi_Context_Create`, `Tbsi_GetDeviceInfo`, `Tbsip_Context_Close`
## 2. 驱动初始化与反汇编对抗
位于 `0x18012E054` 的 `DriverEntry` 使用了不透明的跳转序列(`jmp $+1`)和内联垃圾指令字节,以干扰线性扫描反汇编器(IDA Pro / Ghidra):
```
18012E054 push rcx
18012E055 lea rcx, loc_18012E05C
18012E05C add rcx, 139E787h
18012E063 mov [rsp+10h], rcx
18012E068 pop rcx
18012E069 jmp short near ptr loc_18012E069+1 ; Disassembly desynchronization
18012E06B db 64h, 24h, 8, 6Bh, 7Fh
```
## 3. 直接 IAT Import 目录
虽然关键例程隐藏在 `DecryptImport` 之后,但非混淆的 import 揭示了关键的功能模块:
### 文件系统 Minifilter (`FLTMGR.sys`)
- `FltRegisterFilter`, `FltReadFile`, `FltGetFileNameInformation`
- `FltGetRequestorProcess`, `FltGetDestinationFileNameInformation`
- 监控系统级的文件系统 I/O 操作,跟踪进程文件访问、文件创建和重命名请求。
### 代码完整性 (`CI.dll`)
- `CiValidateFileObject`, `CiFreePolicyInfo`
- 根据内核 code integrity 策略验证可执行文件对象签名。
### 加密提供程序 (`CNG.sys` / `BCrypt`)
- `BCryptCreateHash`, `BCryptHashData`, `BCryptFinishHash`
- `BCryptGenerateSymmetricKey`, `BCryptDecrypt`, `BCryptVerifySignature`
- 执行 payload 解密、完整性验证和签名校验。
### 硬件证明与 TPM (`TBS.sys`)
- `Tbsi_Context_Create`, `Tbsi_GetDeviceInfo`, `Tbsip_Submit_Command`
- 建立 TPM 2.0 通信上下文,以执行基于硬件的完整性检查并验证 Platform Configuration Registers (PCR)。
## 4. 内核栈验证机制
EAC 采用多阶段栈审计流水线,以识别手动映射的驱动程序和不受支持的执行区域。
### 4.1 概率帧捕获 (`sub_1800A6928`)
在内核回调执行期间触发。为了平衡系统性能,帧捕获使用 `RtlRandomEx` 以约 1% 的随机抽样率运行:
```
if (RtlRandomEx(&seed) % 100 == 0) {
PEPROCESS process = IoThreadToProcess(current_thread);
RtlWalkFrameChain(frame_buffer, 8, 1); // 1 = Kernel Mode
memcpy(tracking_struct + 0x28, frame_buffer, 64);
}
```
### 4.2 栈展开与验证 (`sub_1800D7870`)
捕获的栈帧将根据已注册的内核模块边界(`g_driver_base` – `g_driver_end`)进行审计:
```
bool validate_stack(stack_data) {
if (get_eprocess(KeGetCurrentThread()) != PsInitialSystemProcess)
return false;
while (true) {
PRUNTIME_FUNCTION unwind_info = RtlLookupFunctionEntry(rip, &image_base, NULL);
if (!unwind_info) break;
RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, rip, unwind_info, ...);
if (!rip) return valid_frames >= 3;
// Verify return address resides within legitimate driver module range
if (rip < g_driver_base || rip >= g_driver_end)
return false; // Invalid / Unmapped Execution Frame Flagged
valid_frames++;
}
}
```
任何指向不受支持的内存或未列出驱动区域的执行地址都会立即触发检测标志。包含少于 3 个有效帧的栈同样会被拒绝。
## 5. 驱动加载拦截
EAC 使用 `SeRegisterImageVerificationCallback` (`sub_1800080B0`) 注册内核级驱动加载回调,直接与 `CI.dll` 交互。每个加载到系统内存中的内核模块在执行入口点之前都会被拦截,以进行哈希计算和策略验证。
## 6. TPM 2.0 硬件认证 (`sub_18003C3BC`)
```
NTSTATUS init_tpm(tpm_context_t* context) {
context->magic = 0xFBF2AFA3761E188A;
context->version = 2; // TPM 2.0
TBS_CONTEXT_PARAMS params = { .version = 2 };
if (Tbsi_Context_Create(¶ms, &context->handle) != 0)
return STATUS_UNSUCCESSFUL;
TPM_DEVICE_INFO info;
if (Tbsi_GetDeviceInfo(sizeof(info), &info) != 0 || (info.flags & ~2) != 0) {
Tbsip_Context_Close(context->handle);
return STATUS_UNSUCCESSFUL;
}
context->cmd_buffer = ExAllocatePoolWithTag(NonPagedPool, 4096, 'mptT');
return STATUS_SUCCESS;
}
```
与 TPM 硬件芯片的直接通信使 EAC 能够执行 endorsement key 查询和 PCR 认证,从而建立独立于操作系统级配置的、基于硬件的识别。
## 7. 其他检测向量
| 向量 | 内部例程 / API | 描述 |
| :--- | :--- | :--- |
| **NMI Callbacks** | `KeDeregisterNmiCallback` (`sub_1800597C4`) | 发出不可屏蔽中断,以审计跨 CPU 核的活动指令指针。 |
| **ETW Tracing** | `NtTraceControl` | 配置 Event Tracing for Windows 以检测系统调用和驱动遥测篡改。 |
| **VBS / HVCI Check** | `VslGetSecurePciEnabled` | 检测 Virtualization-Based Security 状态,以在 VBS 环境下调整完整性检查。 |
| **Kernel Debugger** | `KdEnteredDebugger` | 审计活动的内核调试标志。 |
| **Physical Memory Access** | `MmMapIoSpaceEx`, `MmCopyMemory` | 直接进行物理内存映射,用于 SMBIOS 验证、DMA 控制器审计和表检查。 |
## 优先级严重性总结
- **严重**:内核栈遍历 (`RtlWalkFrameChain` / `RtlVirtualUnwind`),驱动加载拦截 (`SeRegisterImageVerificationCallback`),Minifilter 文件访问监控 (`FLTMGR.sys`)。
- **高**:TPM 2.0 硬件认证 (`TBS.sys`),已加载模块审计 (`PsLoadedModuleList`),Code Integrity 策略验证 (`CiValidateFileObject`)。
- **中**:不可屏蔽中断 (`KeDeregisterNmiCallback`),反调试 (`KdEnteredDebugger`),Event Tracing (`NtTraceControl`)。
## 许可证
在 MIT License 下分发。详情请参阅 `LICENSE`。
标签:Aarch64, 内核驱动, 反作弊, 反逆向工程, 可视化界面, 网络协议, 逆向分析