如何在使用ud2指令结合向量异常处理后恢复程序执行?
解决__ud2触发异常后无限循环的问题
问题原因
当__ud2触发异常后,你返回EXCEPTION_CONTINUE_EXECUTION但未修改指令指针,系统会重新执行触发异常的__ud2指令,导致无限循环。__ud2是固定2字节的无效指令,必须让指令指针跳过这条指令,才能继续执行后续代码。
解决方案
在异常处理函数中,修改异常上下文的指令指针(x64为RIP,x86为EIP),使其向后偏移2字节,跳过__ud2指令:
修改后的代码如下:
#include <Windows.h> #include <iostream> void resumeFromUD2() { PVOID handler = AddVectoredExceptionHandler(1, [](struct _EXCEPTION_POINTERS* ExceptionInfo)->LONG { std::cout << "vectored exception handled\n"; std::cout << "exception code: " << std::hex << ExceptionInfo->ExceptionRecord->ExceptionCode << std::dec << "\n"; // 仅处理__ud2触发的非法指令异常 if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ILLEGAL_INSTRUCTION) { // 跳过2字节的__ud2指令 #ifdef _WIN64 ExceptionInfo->ContextRecord->RIP += 2; #else ExceptionInfo->ContextRecord->EIP += 2; #endif } return EXCEPTION_CONTINUE_EXECUTION; }); int testValue = 0; testValue++; __ud2(); testValue++; // 此时testValue值应为2 std::cout << "testValue: " << testValue << '\n'; RemoveVectoredExceptionHandler(handler); }
关键说明
STATUS_ILLEGAL_INSTRUCTION是__ud2触发的异常代码(值为0xC000001D),先判断异常类型可避免处理无关异常。- 需根据编译架构选择对应的指令指针寄存器:x64平台用
RIP,x86平台用EIP。 - 偏移2字节是因为
__ud2指令在x86和x64平台上均为固定2字节长度。
内容的提问来源于stack exchange,提问作者Badasahog
相关产品推荐
相关产品推荐

