通过VEH(Vectored Exception Handling)进行syscall
字数 996 2025-08-10 08:28:55
通过VEH(Vectored Exception Handling)进行syscall技术详解
1. VEH基础概念
1.1 什么是VEH
VEH(Vectored Exception Handling)是Windows提供的一种异常处理机制,它允许应用程序注册一个或多个异常处理函数,这些函数会在异常发生时被调用。与传统的SEH(结构化异常处理)相比,VEH具有以下特点:
- 处理函数按注册顺序被调用
- 可以在进程范围内处理异常
- 优先级高于SEH
- 可以处理所有线程的异常
1.2 VEH相关API
PVOID AddVectoredExceptionHandler(
ULONG First,
PVECTORED_EXCEPTION_HANDLER Handler
);
ULONG RemoveVectoredExceptionHandler(
PVOID Handle
);
2. 利用VEH进行syscall的原理
2.1 基本原理
通过VEH进行syscall的核心思想是:
- 故意触发一个异常(如访问违例)
- 在VEH处理函数中修改上下文(如修改EIP/RIP)
- 让执行流跳转到syscall stub
2.2 技术优势
- 绕过用户态hook
- 不需要直接调用syscall指令
- 可以绕过部分EDR的监控
3. 实现步骤详解
3.1 设置VEH处理函数
LONG NTAPI VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
// 检查是否是我们的"魔法"地址
if (ExceptionInfo->ExceptionRecord->ExceptionInformation[1] == MAGIC_ADDRESS) {
// 修改上下文指向syscall stub
ExceptionInfo->ContextRecord->Rip = (DWORD64)&SyscallStub;
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
3.2 触发异常
// 定义一个"魔法"地址
#define MAGIC_ADDRESS 0xDEADBEEF
// 触发访问违例
void TriggerException() {
volatile int* ptr = (int*)MAGIC_ADDRESS;
*ptr = 0x1337; // 这将触发访问违例
}
3.3 Syscall stub实现
SyscallStub:
mov r10, rcx ; 将第一个参数移动到r10
mov eax, SSN ; 系统服务编号
syscall ; 执行系统调用
ret ; 返回
4. 完整实现示例
4.1 头文件定义
#include <windows.h>
#include <winternl.h>
#define MAGIC_ADDRESS 0xDEADBEEF
#define NtAllocateVirtualMemory_SSN 0x18
// Syscall stub声明
extern "C" NTSTATUS NtAllocateVirtualMemorySyscall(
HANDLE ProcessHandle,
PVOID* BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect);
4.2 VEH处理函数
LONG NTAPI VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
if (ExceptionInfo->ExceptionRecord->ExceptionInformation[1] == MAGIC_ADDRESS) {
// 获取syscall stub地址
PVOID syscallStub = &NtAllocateVirtualMemorySyscall;
// 修改RIP指向syscall stub
#ifdef _WIN64
ExceptionInfo->ContextRecord->Rip = (DWORD64)syscallStub;
#else
ExceptionInfo->ContextRecord->Eip = (DWORD)syscallStub;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
4.3 主函数
int main() {
// 注册VEH处理函数
PVOID hHandler = AddVectoredExceptionHandler(1, VectoredExceptionHandler);
// 准备参数
HANDLE hProcess = GetCurrentProcess();
PVOID baseAddr = (PVOID)MAGIC_ADDRESS;
SIZE_T regionSize = 0x1000;
// 触发异常并执行syscall
NtAllocateVirtualMemory(hProcess, &baseAddr, 0, ®ionSize, MEM_COMMIT, PAGE_READWRITE);
// 移除VEH处理函数
RemoveVectoredExceptionHandler(hHandler);
return 0;
}
5. 技术细节与注意事项
5.1 异常处理顺序
Windows异常处理顺序:
- VEH(如果First参数为1的处理函数)
- 调试器
- VEH(如果First参数为0的处理函数)
- SEH
5.2 上下文修改要点
在VEH处理函数中修改上下文时需要注意:
- 确保修改正确的寄存器(x86/x64不同)
- 保存和恢复必要的寄存器状态
- 处理异常返回代码
5.3 对抗检测
- 使用动态SSN(系统服务编号)而非硬编码
- 随机化"魔法"地址
- 混淆syscall stub代码
6. 防御措施
检测此类技术的可能方法:
- 监控AddVectoredExceptionHandler调用
- 分析异常处理函数行为
- 检查异常的上下文修改模式
- 监控异常的"魔法"地址模式
7. 扩展应用
此技术还可用于:
- API调用重定向
- 反调试
- 代码流混淆
- 绕过内存保护机制
8. 总结
通过VEH进行syscall是一种有效的用户态hook绕过技术,它利用了Windows异常处理机制的灵活性。理解这一技术不仅有助于攻击技术的开发,也为防御此类技术提供了基础。在实际应用中,需要结合其他技术如SSN动态解析、内存混淆等来提高隐蔽性。