PEB 和 EAT ,检测syscall stub
字数 2394 2025-10-01 14:05:52
PEB与EAT:Windows系统调用绕过技术详解
1. 核心概念
1.1 PEB(进程环境块)
- 定义:Windows为每个进程维护的核心数据结构,存储进程运行所需的环境信息
- 功能:
- 记录已加载DLL模块列表
- 堆内存使用情况
- 进程启动参数
- 调试信息
- 访问方式:
- x86架构:通过
fs:[0x30]寄存器直接访问 - x64架构:通过
gs:[0x60]寄存器直接访问
- x86架构:通过
1.2 EAT(导出地址表)
- 定义:DLL或EXE文件中的数据结构,记录模块对外提供的函数及其内存地址
- 作用:充当"函数目录",系统通过EAT定位DLL中的函数内存地址
- 安全价值:
- 绕过API钩子(避免使用被钩子的
GetProcAddress) - 动态函数解析
- 增强代码隐蔽性
- 绕过API钩子(避免使用被钩子的
2. 技术原理
2.1 PEB与EAT组合使用
- 通过PEB定位目标DLL(如
ntdll.dll)基地址 - 解析DLL的EAT,获取目标函数地址
- 直接调用函数,绕过用户模式钩子
2.2 间接系统调用机制
- 执行流程:
- 避免直接查询
ntdll.dll中的系统调用存根 - 运行时动态提取所需系统调用指令
- 保持系统调用指令从
ntdll.dll内存空间执行
- 避免直接查询
- 优势:调用堆栈显示
ntdll.dll位于顶部,增加合法性外观
2.3 哈希值应用
- 目的:避免明文字符串检测,提高效率和隐蔽性
- 哈希算法示例:
DWORD hashString(char* string) { DWORD hash = 0; while(*string) { hash = (hash >> 13) | (hash << 19); // 循环移位 hash += *string; string++; } return hash; }
3. 实现细节
3.1 PEB模块遍历
- x64系统访问:GS寄存器指向TEB,TEB偏移0x60处存储PEB地址
- 优势:避免使用
GetCurrentProcess()等可能被钩子的API
3.2 字符串处理
- Unicode与ASCII转换:
- Windows内部使用Unicode字符串(宽字符)
- 哈希算法需要ASCII字符串(窄字符)
- 转换函数关键点:
- 边界安全检查
- 宽字符到窄字符转换
- 统一转换为小写保证哈希一致性
- 正确添加字符串终止符
3.3 系统调用存根识别
- x64架构特征字节模式:
0x4c 0x8b 0xd1=mov r10, rcx(保存第一个参数)0xb8=mov eax, [SSN](加载系统调用编号)0x00 0x00= SSN高位(通常为0)0x0f 0x05=syscall指令
4. 高级绕过技术:Halos Gate
4.1 技术背景
- 问题:EDR不仅钩子
GetModuleHandleA和GetProcAddress,还直接钩子Native API函数(如NtAllocateVirtualMemory) - 解决方案:检测EDR钩子并通过扫描相邻syscall stubs找到干净系统调用指令
4.2 实现原理
- 核心观察:
ntdll.dll中系统调用函数按顺序排列- 系统调用编号(SSN)连续
- 执行流程:
- 检测目标函数是否被钩子(通过JMP指令识别)
- 向上和向下扫描相邻函数(最多500个函数范围)
- 通过字节模式匹配识别真正系统调用存根
- 根据相邻函数的SSN推断被钩子函数的正确SSN
4.3 钩子检测方法
// 检查函数开头是否包含JMP指令(常见钩子标志)
if(memcmp(functionAddress, "\xE9", 1) == 0 ||
memcmp(functionAddress, "\xFF\x25", 2) == 0) {
// 检测到钩子,启动相邻扫描
}
5. 关键数据结构
5.1 PEB结构关键字段
- Ldr:指向PEB_LDR_DATA结构,包含已加载模块信息
- ProcessHeap:进程堆信息
- ProcessParameters:进程启动参数
5.2 LDR_DATA结构
- InLoadOrderModuleList:按加载顺序排列的模块链表
- InMemoryOrderModuleList:按内存顺序排列的模块链表
- InInitializationOrderModuleList:按初始化顺序排列的模块链表
5.3 LDR_MODULE结构
- BaseAddress:模块基地址
- EntryPoint:模块入口点
- SizeOfImage:模块映像大小
- FullDllName:完整DLL路径(UNICODE_STRING)
- BaseDllName:DLL基础名称(UNICODE_STRING)
6. 对抗技术
6.1 检测规避
- API钩子检测:直接内存访问绕过用户模式钩子
- 内存保护检测:动态解析函数地址,避免静态特征
6.2 反分析技术
- 代码混淆:增加逆向工程难度
- 哈希值应用:替代明文字符串,避免静态检测
- 动态计算:运行时计算函数地址,避免硬编码
- 随机化执行流程:增加行为分析难度
6.3 反调试技术
- PEB调试标志检查:检测调试器附加状态
- 时间检测:识别调试导致的执行延迟
7. 工具与脚本
7.1 哈希计算工具
- 实现前述哈希算法
- 支持Unicode/ASCII字符串输入
7.2 PEB分析工具
- 遍历并显示当前进程加载的所有模块
- 提取模块基地址、大小和路径信息
7.3 系统调用检测工具
- 识别系统调用存根特征字节模式
- 提取系统调用编号(SSN)
7.4 内存操作工具
- 安全的内存读写操作
- 内存属性检测与修改
8. 技术局限性
- EDR进阶检测:现代EDR可能钩子Native API函数本身,而不仅仅是加载函数
- 性能开销:相邻函数扫描可能带来性能损耗
- 版本兼容性:不同Windows版本函数排列可能变化
- 误判风险:模式匹配可能错误识别非系统调用存根
9. 总结
PEB和EAT技术提供了绕过Windows用户模式安全检测的有效方法,通过直接内存访问和底层系统结构操作,实现了高级的API调用隐蔽性。Halos Gate技术进一步解决了Native API被钩子时的绕过问题,体现了在安全对抗中不断演进的技术思维。
这些技术既可用于安全研究,也可能被恶意利用,因此理解其原理对于防御方同样重要。掌握这些底层机制有助于深入理解Windows系统内部工作原理,并开发更有效的安全防护方案。