【问题标题】:Custom SEH handler with /SAFESEH使用 /SAFESEH 自定义 SEH 处理程序
【发布时间】:2012-08-18 15:14:46
【问题描述】:

我目前正在尝试用 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);

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

感谢您的任何建议!

【问题讨论】:

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


    【解决方案1】:

    我终于找到了一个描述问题的页面: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 的不匹配。

    【讨论】:

    • 这也适用于 x64 吗?如果我使用 32 位 VC 编译器编译它,并在 64 位窗口上运行它,是否会调用自定义的异常处理程序?
    • 只要为 x86 编译它,Windows 将在 32 位和 64 位 Windows 上运行 32 位应用程序。这就是我一直在做的事情。但是,我还没有测试过使用 64 位编译器编译代码。
    【解决方案2】:

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

    【讨论】:

    • 感谢您的回答!是的,我在 ml.exe 中添加了 /safeseh,否则会收到警告。我也会在上面注明。
    【解决方案3】:

    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 位窗口,因此请忽略文档中提到 x64 的事实。

    【讨论】:

      猜你喜欢
      • 2015-04-17
      • 2012-10-25
      • 1970-01-01
      • 2011-07-27
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      相关资源
      最近更新 更多