C 运行时错误 R6035

Microsoft Visual C++ 运行时库,错误 R6035 - 此应用程序中的模块正在初始化模块的全局安全 Cookie,而依赖于该安全 Cookie 的函数处于活动状态。 尽早调用 __security_init_cookie。

在首次使用全局安全 Cookie 之前,必须调用 __security_init_cookie

全局安全 Cookie 用于在使用 /GS(缓冲区安全检查)编译的代码中和使用结构化异常处理的代码中提供缓冲区溢出保护。 本质上,进入受到溢出保护的函数时,Cookie 被置于堆栈之上;退出时,会将堆栈上的值与全局 Cookie 进行比较。 它们之间存在任何差异则表示已经发生缓冲区溢出,并导致该程序的立即终止。

错误 R6035 表示在输入受保护函数后调用 __security_init_cookie。 如果继续执行,则会检测到一个虚假的缓冲区溢出,因为堆栈上的 Cookie 不再与全局 Cookie 匹配。

请看下面的 DLL 示例。 DLL 入口点通过链接器 /ENTRY(入口点符号)选项设置为 DllEntryPoint。 这会绕过 CRT 的初始化,该初始化通常会初始化全局安全 Cookie,因此 DLL 本身必须调用 __security_init_cookie

// Wrong way to call __security_init_cookie
DllEntryPoint(...) {
   DllInitialize();
   ...
   __try {
      ...
   } __except()... {
      ...
   }
}

void DllInitialize() {
   __security_init_cookie();
}

此示例将生成错误 R6035,因为 DllEntryPoint 使用结构化异常处理,因此使用安全 Cookie 来检测缓冲区溢出。 在调用 DllInitialize 时,全局安全 Cookie 已放在堆栈上。

此示例演示了正确的方法:

// Correct way to call __security_init_cookie
DllEntryPoint(...) {
   __security_init_cookie();
   DllEntryHelper();
}

void DllEntryHelper() {
   ...
   __try {
      ...
   } __except()... {
      ...
   }
}

在这种情况下,DllEntryPoint 不受缓冲区溢出的保护(它没有本地字符串缓冲区,并且不使用结构化异常处理);因此,它可以安全地调用 __security_init_cookie。 然后,它会调用受保护的帮助程序函数。

注意

错误消息 R6035 仅由 x86 调试 CRT 生成,仅用于结构化异常处理(但条件是所有平台上的错误),以及所有形式的异常处理(如 C++ EH)。

另请参阅

MSVC 中的安全功能