自定义SEH处理程序/ SAFESEH

时间:2012-08-18 15:14:47

标签: c++ windows visual-studio-2008 assembly

我目前正在尝试用C ++创建一个编译器,它在运行时生成机器代码。但是,我目前正在尝试启用安全异常处理(使用/ SAFESEH进行编译)。我的自定义异常处理程序在调试模式下工作,但是当我在发布模式下运行相同的代码时,我的进程才被终止。

我很确定问题是我无法注册我的自定义异常处理程序,因为当我使用/ SAFESEH编译我的代码时:NO,即使在发布模式下一切正常。

我的自定义异常处理程序是用我的其他C ++代码编写的,我试图通过将.asm文件添加到包含内容的项目中来将其注册为异常处理程序:

.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end

here所述。然后使用/ safeseh选项(以及其他)组装asm文件。

我的处理函数目前有以下声明:

extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct 
_CONTEXT *ContextRecord, void * DispatcherContext);

将此函数注册为异常处理程序的正确方法是什么?

感谢您的任何建议!

3 个答案:

答案 0 :(得分:4)

我终于找到了一个描述问题的页面:here。但是,页面中的代码示例未经修改就无法工作。

问题似乎是将外部过程注册为异常处理程序不能按预期工作,因此您必须将本地程序集过程注册为异常处理程序。

根据前面提到的页面上给出的示例,这就是我最终的结果:

.386
.model flat, stdcall
option casemap :none

extern MyExceptionHandler@16:near

MyExceptionHandlerAsm proto
.SAFESEH MyExceptionHandlerAsm

.code
MyExceptionHandlerAsm proc
    jmp MyExceptionHandler@16
MyExceptionHandlerAsm endp
end

这似乎有效,但它很可能不是最优雅的解决方案。例如:为了避免在从C / C ++引用MyExceptionHandlerAsm时出现链接错误,我必须将其声明为:

extern "C" int __stdcall MyExceptionHandlerAsm();

如果有人试图从C / C ++调用MyExceptionHandlerAsm,那么会崩溃,因为参数的数量与MyExceptionHandler的参数数量不匹配。

答案 1 :(得分:1)

MSDN文档看起来您的ASM是正确的。您是否已将/safeseh选项添加到ml.exe

答案 2 :(得分:0)

ExceptionHandler函数的签名实际上是:

typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
    __in struct _EXCEPTION_RECORD *ExceptionRecord,
    __in PVOID EstablisherFrame,
    __inout struct _CONTEXT *ContextRecord,
    __inout PVOID DispatcherContext
    );

this MSDN page。 32位窗口使用相同的异常例程,因此请忽略doc提及x64的事实。