// 带有异常处理函数的函数
void test1()
{
// 在 VS 的同一个函数中无论编写了多少个 SEH, 编译器
// 实际上只会安装一个叫做 except_handler4 的函数
__try
{
printf("__try { ... }\n");
__try
{
printf("__try { ... }\n");
}
__except (1)
{
printf("__except (1) { ... }\n");
}
}
__except (1)
{
printf("__except (1) { ... }\n");
}
}
// 没有异常处理函数的函数
void test2() { }
// 遍历当前程序中已经存在的异常处理函数
void ShowSEH()
{
// 定义一个结构体指针,用于保存 SEH 链表的头节点
PEXCEPTION_REGISTRATION_RECORD header = nullptr;
// 通过 FS:[0] 找到 ExceptionList 的头节点
__asm push fs:[0]
__asm pop header
// 遍历异常处理链表,链表以 -1 结尾
while (header != (EXCEPTION_REGISTRATION_RECORD*)-1)
{
printf("function: %08X\n", header->Handler);
header = header->Next;
}
printf("\n");
}
EXCEPTION_DISPOSITION NTAPI ExceptionRoutine(
// 产生的异常信息
_Inout_ struct _EXCEPTION_RECORD* ExceptionRecord,
_In_ PVOID EstablisherFrame,
// 产生异常时的线程上下文
_Inout_ struct _CONTEXT* ContextRecord,
_In_ PVOID DispatcherContext
)
{
printf("自定义SEH: ExceptionCode: %X\n", ExceptionRecord->ExceptionCode);
if (EXCEPTION_INT_DIVIDE_BY_ZERO == ExceptionRecord->ExceptionCode)
{
ContextRecord->Eax = 1;
ContextRecord->Ecx = 1;
return ExceptionContinueExecution;
}
return ExceptionContinueSearch;
}
int main()
{
test1();
test2();
PEXCEPTION_REGISTRATION_RECORD ExceptionList = nullptr;
__asm push fs : [0]
__asm pop ExceptionList
// 遍历异常处理函数
ShowSEH();
// 手动安装一个异常处理函数,操作 FS:[0]
__asm push ExceptionRoutine
__asm push fs : [0]
__asm mov fs : [0], esp
ShowSEH();
int number = 0;
number /= 0;
printf("\n");
__asm mov eax, ExceptionList
__asm mov fs : [0], eax
__asm add esp, 0x08
ShowSEH();
return 0;
}