/SAFESEH(映像具有安全异常处理程序)

/SAFESEH[:NO]

指定 /SAFESEH 时,仅当链接器还可以生成映像安全异常处理程序的表时,才生成映像。 此表为操作系统指定对映像有效的异常处理程序。

/SAFESEH 仅在链接 x86 目标时有效。 已注明异常处理程序的平台不支持 /SAFESEH。 例如,在 x64 和 ARM 上,PDATA 中注明了所有异常处理程序。 ML64.exe 支持添加注释以向映像发出 SEH 信息(XDATA 和 PDATA),从而允许通过 ml64 函数展开它们。 有关详细信息,请参阅适用于 x64 的 MASM (ml64.exe)

如果未指定 /SAFESEH,且所有代码段都与安全异常处理功能兼容,则链接器将生成包含安全异常处理程序表的映像。 如果任意代码段与安全异常处理功能不兼容,则生成的映像将不包含安全异常处理程序表。 如果 /SUBSYSTEM 指定 WINDOWSCE 或其中一个 EFI_* 选项,则链接器不会尝试生成包含安全异常处理程序表的映像,因为这些子系统都不会利用此信息。

如果指定了 /SAFESEH:NO,即使所有代码段都与安全异常处理功能兼容,链接器也不会生成包含安全异常处理程序表的映像。

链接器无法生成映像的最常见原因是,链接器的一个或多个输入文件与安全异常处理程序功能不兼容。 代码与安全异常处理程序不兼容的一个常见原因是,它是由以前版本的 Visual C++ 编译器创建的。

还可以使用 .SAFESEH 将函数注册为结构化异常处理程序。

无法将现有二进制文件标记为具有安全异常处理程序(或无异常处理程序);必须在生成时添加有关安全异常处理的信息。

链接器生成安全异常处理程序表的功能取决于使用 C 运行时库的应用程序。 如果链接到 /NODEFAULTLIB 并且你需要安全异常处理程序表,则需要提供包含为 Visual C++ 定义的所有条目的负载配置结构(例如,可以在 loadcfg.c CRT 源文件中找到)。 例如:

#include <windows.h>
extern DWORD_PTR __security_cookie;  /* /GS security cookie */

/*
* The following two names are automatically created by the linker for any
* image that has the safe exception table present.
*/

extern PVOID __safe_se_handler_table[]; /* base of safe handler entry table */
extern BYTE  __safe_se_handler_count;  /* absolute symbol whose address is
                                           the count of table entries */
typedef struct {
    DWORD       Size;
    DWORD       TimeDateStamp;
    WORD        MajorVersion;
    WORD        MinorVersion;
    DWORD       GlobalFlagsClear;
    DWORD       GlobalFlagsSet;
    DWORD       CriticalSectionDefaultTimeout;
    DWORD       DeCommitFreeBlockThreshold;
    DWORD       DeCommitTotalFreeThreshold;
    DWORD       LockPrefixTable;            // VA
    DWORD       MaximumAllocationSize;
    DWORD       VirtualMemoryThreshold;
    DWORD       ProcessHeapFlags;
    DWORD       ProcessAffinityMask;
    WORD        CSDVersion;
    WORD        Reserved1;
    DWORD       EditList;                   // VA
    DWORD_PTR   *SecurityCookie;
    PVOID       *SEHandlerTable;
    DWORD       SEHandlerCount;
} IMAGE_LOAD_CONFIG_DIRECTORY32_2;

const IMAGE_LOAD_CONFIG_DIRECTORY32_2 _load_config_used = {
    sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_2),
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    &__security_cookie,
    __safe_se_handler_table,
    (DWORD)(DWORD_PTR) &__safe_se_handler_count
};

在 Visual Studio 开发环境中设置此链接器选项

  1. 打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性

  2. 选择“链接器”文件夹。

  3. 选择“命令行”属性页。

  4. 将该选项输入“附加选项”框中。

以编程方式设置此链接器选项

另请参阅

MSVC 链接器参考
MSVC 链接器选项