【问题标题】:What SAFESEH:NO option actually doSAFESEH:NO 选项的实际作用
【发布时间】:2014-09-24 16:54:36
【问题描述】:

我正在尝试像在example 中一样使用boost::asio::spawn 函数,但它在Release 中给了我以下错误:

libboost_context-vc120-mt-s-1_55.lib(jump_i386_ms_pe_masm.obj):错误 LNK2026:模块对 SAFESEH 图像不安全

很明显,我应该在项目的设置中设置/SAFESEH:NO 选项,但我不明白这实际上会做什么。这如何影响程序中异常处理的行为(C++ 异常和 SEH)?

顺便说一句,我使用的是 MSVC-12.0。

【问题讨论】:

标签: c++ visual-studio boost exception-handling visual-studio-2013


【解决方案1】:

简答:禁用 SafeSEH 会降低您的程序安全性


详情:SafeSEH 是编译器保护。

在 Windows 环境中 SEH (Structured Exception Handler) 记录的布局如下

Stack data (pointed by TEB - thread environment block)
|
|  I) Pointer to next SEH record II
|  EH pointer
|
|  II) Pointer to next SEH record III
|  EH pointer
|
|  0xFFFFFF
|  default EH (MSVCRT)

通常基于 SEH 的攻击依赖于覆盖上述记录之一并让应用程序抛出异常:这将绕过控制流到您的代码(我考虑到 DEP/这里有 ASLR 保护系统,所以我假设一个已知的 +X 位置)。更准确地说,它们经常“模拟 EH 返回”,然后获取下一个“邪恶的”指针以跳转到 shellcode。

SafeSEH 的工作原理是指示操作系统在跳转到它们之前首先检查处理程序指针的有效性(对照已知有效 EH 的表)。这个过程有一些限制,在特殊情况下,应用程序可能仍然容易受到攻击,但基于 SEH 的攻击不太可能发生(或者更难制造)。

当链接到非 safeSEH 编译模块时,链接器将无法生成 EH 位置的“受信任表”(它根本无法判断这些位置在哪里以及是否是有效的 EH),因此您会遇到错误。

Windows 操作系统工程的一些逻辑限制、兼容性原因以及控制地址超出已加载模块(和可执行映像)范围的问题导致选择默认禁用此选项并留给用户选择是否启用。

如果您的应用程序迫切需要安全性,并且您认为上述场景存在潜在威胁,您应该启用它并重新编译您的模块以便使用它。

【讨论】:

  • 有点跑题了,但是 SEH 内部的工作方式已经变成了much more complicated (并且性能也更高),因为 Vista 。
  • @Marco 如果它保护 exe,那么为什么默认情况下它没有启用?
  • @sonugupta 我猜这可能与compatibility reasons
【解决方案2】:

/SAFESEH 产生一个“安全异常处理表”:

>dumpbin safeseh_yes.dll /loadconfig | find "xcept"
            3001F4D0 Safe Exception Handler Table
                   1 Safe Exception Handler Count
    Safe Exception Handler Table
          30018FE0  __except_handler4

/SAFESEH:NO 不生成表:

>dumpbin safeseh_no.dll /loadconfig | find "xcept"
            00000000 Safe Exception Handler Table
                   0 Safe Exception Handler Count

如果该表存在,则操作系统在调用它之前使用它来验证 SEH 处理程序是否有效。

【讨论】:

    猜你喜欢
    • 2016-11-09
    • 2023-01-14
    • 1970-01-01
    • 2017-05-06
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多