自定义SEH处理程序/ SAFESEH

Fil*_*lip 5 c++ windows assembly visual-studio-2008

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

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

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

.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end
Run Code Online (Sandbox Code Playgroud)

作为描述在这里.然后使用/ safeseh选项(以及其他)组装asm文件.

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

extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct 
_CONTEXT *ContextRecord, void * DispatcherContext);
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的任何建议!

Fil*_*lip 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
Run Code Online (Sandbox Code Playgroud)

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

extern "C" int __stdcall MyExceptionHandlerAsm();
Run Code Online (Sandbox Code Playgroud)

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