更新 : 2007 年 11 月
エラー メッセージ
Microsoft Visual C++ ランタイム ライブラリ、エラー R6035 - あるグローバル セキュリティ Cookie に依存している関数がアクティブになっている間に、このアプリケーション内のモジュールが、そのモジュールに所属するそのセキュリティ Cookie を初期化しました。__security_init_cookie を既に呼び出しました。
__security_init_cookie は、グローバル セキュリティ Cookie を初めて使用する前に呼び出す必要があります。
グローバル セキュリティ Cookie は、/GS (バッファのセキュリティ チェック) を指定してコンパイルされたコードおよび構造化例外処理を使用するコードでバッファ オーバーランから保護するために使用されます。基本的に、オーバーランから保護された関数を呼び出すと Cookie はスタックに配置され、関数の終了時に、スタックの値がグローバルな Cookie と比較されます。違いが発見された場合は、バッファ オーバーランが発生したことを意味し、プログラムは直ちに終了します。
エラー R6035 は、保護された関数の呼び出し後に __security_init_cookie が呼び出されたことを示します。実行を継続すると、スタック上の Cookie がグローバルな Cookie と一致しなくなるため、実際には発生していないバッファ オーバーランが検出されます。
次の DLL の例を考えます。DLL のエントリ ポイントは、リンカの /ENTRY (エントリ ポイント シンボル) オプションによって DllEntryPoint に設定されます。これにより、通常はグローバル セキュリティ Cookie を初期化する CRT の初期化が省略されるため、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 など) エラー条件は成立しています。 |