Syscall学习
字数 1844 2025-08-23 18:31:24
Syscall技术深入解析与实战应用
1. 系统调用基础概念
1.1 权限级别
- R0(内核态): 最高权限级别,操作系统内核在此级别运行
- R1/R2: 通常用于设备驱动运行
- R3(用户态): 最低权限级别,用户应用程序在此级别运行
1.2 系统调用(Syscall)机制
- 用户态程序通过系统调用请求内核服务
- 在Windows中,调用流程通常为:
用户程序 → kernel32.dll → ntdll.dll → 系统调用进入内核 - ntdll.dll中的Native API函数以"Nt"或"Zw"开头
1.3 系统调用号(SSN)
- 每个系统调用都有一个唯一编号
- 存储在EAX寄存器中
- 相邻函数的SSN通常是递增的
2. EDR检测与绕过技术
2.1 EDR工作原理
- API Hook: EDR通过修改API函数开头插入跳转指令(jmp)到检测代码
- 检测流程: 调用API → 跳转到EDR检测代码 → 检测通过 → 执行原API
2.2 直接系统调用绕过
- 直接使用汇编指令执行系统调用,绕过用户态Hook
- 基本模板:
mov r10, rcx mov eax, SSN ; 系统调用号 syscall
3. 经典Syscall项目分析
3.1 Hell's Gate(地狱之门)
核心思想: 从内存中已加载的ntdll.dll动态解析导出表获取SSN
实现步骤:
- 获取TEB/PEB结构
- 通过PEB获取ntdll模块
- 解析导出表定位目标函数
- 通过函数前导字节识别并提取SSN
- 使用获取的SSN进行直接系统调用
局限性:
- 依赖干净的ntdll内存
- 若ntdll被Hook则失效
3.2 Halo's Gate(光环之门)
改进点: 当目标函数被Hook时,通过相邻未Hook函数推算SSN
实现原理:
- 检查目标函数前导字节是否为
mov r10, rcx - 若被Hook,向上或向下查找最近的干净函数
- 通过相邻函数的SSN差值计算目标SSN
优势:
- 不依赖目标函数本身的完整性
- 利用SSN递增特性推算
3.3 TartarusGate
进一步改进:
- 处理EDR在第二条指令Hook的情况
- 增加更多验证检查
- 在汇编代码中插入NOP指令混淆
3.4 SysWhispers系列
3.4.1 SysWhispers1
特点:
- 支持多版本Windows系统
- 生成包含所有已知版本SSN的汇编代码
- 运行时根据系统版本选择正确SSN
3.4.2 SysWhispers2
改进:
- 支持x86/x64
- 提供标准(std)和随机(rnd)两种模式
- 随机模式使用间接系统调用
关键技术:
-
SSN获取:
- 遍历ntdll导出表
- 收集所有Zw*函数并按地址排序
- 序号即为SSN
-
随机间接调用:
- 在ntdll中随机选择一个syscall指令地址
- 跳转到该地址执行系统调用
3.4.3 SysWhispers3
新增技术:
-
Egg Hunter:
- 在内存中用特殊字节序列(w00tw00t)占位
- 运行时搜索并替换为syscall指令
-
Jumper技术:
- 标准jumper: 固定跳转到ntdll中的syscall
- 随机jumper: 跳转到ntdll中随机的syscall位置
4. 技术对比与演进
4.1 直接 vs 间接系统调用
| 特性 | 直接系统调用 | 间接系统调用 |
|---|---|---|
| 执行位置 | 程序自身内存空间 | ntdll内存空间 |
| 堆栈特征 | 异常(EXE内存) | 正常(NTDLL内存) |
| 检测难度 | 容易被检测 | 更难检测 |
4.2 技术演进路线
- 直接系统调用(Hell's Gate)
- 被Hook时的SSN推算(Halo's Gate)
- 多版本兼容(SysWhispers1)
- 间接调用降低检测率(SysWhispers2)
- 动态指令替换和跳转(SysWhispers3)
5. 防御与检测思路
5.1 EDR可能的检测手段
-
SSN异常检测:
- 监控非常规SSN使用
- 检测SSN与函数不匹配情况
-
调用链分析:
- 检查是否绕过正常API调用路径
-
指令特征检测:
- 查找直接syscall指令模式
- 检测非常规跳转序列
5.2 对抗建议
-
多样化技术组合:
- 结合多种syscall技术
- 随机选择调用方式
-
环境感知:
- 检测EDR存在与否
- 根据环境选择合适技术
-
动态行为:
- 运行时修改代码
- 使用合法程序内存区域
附录:关键代码片段
Hell's Gate核心代码
; 获取SSN并执行系统调用
HellsGate PROC
mov wSystemCall, cx
ret
HellsGate ENDP
HellDescent PROC
mov r10, rcx
mov eax, wSystemCall
syscall
ret
HellDescent ENDP
SysWhispers2间接调用
SW2_GetRandomSyscallAddress PROC
; 在ntdll中查找随机syscall指令
mov eax, 0F05h ; syscall指令操作码
; ... 搜索逻辑 ...
ret
SW2_GetRandomSyscallAddress ENDP
WhisperMain PROC
; 获取SSN和随机地址
call SW2_GetSyscallNumber
call SW2_GetRandomSyscallAddress
; 跳转到随机syscall
jmp rax
WhisperMain ENDP
Egg Hunter示例
NtAllocateVirtualMemory PROC
; 前导代码...
DB 77h, 0h, 0h, 74h, 77h, 0h, 0h, 74h ; "w00tw00t"
ret
NtAllocateVirtualMemory ENDP
运行时替换为:
DB 0Fh, 05h, 90h, 90h, 0C3h, 90h, 0CCh, 0CCh ; syscall; nop; nop; ret; nop; int3; int3