C 运行时错误 R6035

Microsoft Visual C++ 运行库,错误 R6035 - 在依赖模块的全局安全 Cookie 的函数处于活动状态的情况下,此应用程序中的模块初始化该安全 Cookie。以前调用过 __security_init_cookie。

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

在用 /GS(缓冲区安全检查) 编译的代码和使用结构化异常处理的代码中,全局安全 Cookie 用于缓冲区溢出保护。 实质上,在进入溢出保护的函数时,会将该 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 出现缓冲区溢出(DllEntryPoint 没有本地字符串缓冲区,也不使用结构化异常处理);因此 DllEntryPoint 可以安全地调用 __security_init_cookie。 DllEntryPoint 随后调用受到保护的 Helper 函数。

备注

错误信息 R6035 仅由 x86 调试 CRT 生成,而且仅用于结构化异常处理,但是该情况是所有平台上的错误,并且适用于各种形式的异常处理,如 C++ EH。

请参见

参考

深入的编译器安全检查