具有异常链验证(SEHOP)的光纤的SEH设置有效

时间:2012-02-12 14:34:52

标签: winapi stack coroutine seh fiber

我正在研究本机光纤/协程实现 - 相当标准,对于每个光纤,分配单独的堆栈,并且为了切换上下文,寄存器被推送到源上下文堆栈并从目标堆栈弹出。它运作良好,但现在我遇到了一个小问题:

我需要SEH才能在光纤内工作(如果程序终止或者奇怪的事情开始发生,当异常未处理,直到光纤的最后一个堆栈帧,它就不会)。只需在上下文切换期间保存/恢复FS:[0](以及FS:[4]FS:[8]),并最初为新分配的光纤设置FS:[0] 0xFFFFFFFF(所以在上下文切换后设置的异常处理程序将是链的根目录几乎工作。

准确地说,它适用于我测试的所有非服务器Windows操作系统 - 问题是Windows Server 2008和2008 R2默认启用了异常链验证(SEHOP,SEH覆盖保护)功能,这使得{{ 1}}检查原始处理程序(在ntdll.dll中的某个地方)是否仍然是链的根目录,并立即终止程序,就好像没有安装处理程序一样。

因此,我面临着在堆栈上构造适当的根框架以保持验证代码满意的问题。是否有任何(隐藏?)API函数我可以调用它,或者我必须弄清楚需要什么才能让RaiseException和朋友们高兴并自己构建适当的RtlDispatchException条目?我不能只是从创建线程重用Windows提供的那个,因为它将位于错误的地址(SEH实现还检查处理程序地址是否在_EXCEPTION_REGISTRATIONFS:[4]给出的边界内,如果地址顺序一致,也可能。)

哦,我非常希望诉诸FS:[8] WinAPI系列函数。

1 个答案:

答案 0 :(得分:1)

我在评论中提到的方法,生成一个指向EXCEPTION_REGISTRATION的假ntdll!FinalExceptionHandler条目似乎确实在实践中起作用 - 至少,这就是我们现在在D运行时所拥有的,到目前为止没有任何问题的报告:

https://github.com/D-Programming-Language/druntime/blob/c39de42dd11311844c0ef90953aa65f333ea55ab/src/core/thread.d#L4027