スタックのセキュリティは、スタック オーバーフローに対処するのに十分なほど安全にすることができます。
http://msdn.microsoft.com/en-us/library/9a89h429(VS.80).aspx
登録された例外ハンドラ ( safe -SEH)が必要な理由と、通常の例外ハンドラがそれをカットしない理由についての質問は、非常に大きなスタック オーバーフローが発生する場合のためです。
始まる関数があるとしましょう
try {
char buffer[N];
strcpy(&buffer, &attacker);
} __except(...) { }
これは、アセンブリ コードに変換される可能性があります。
push ebp
mov ebp, esp
; GS if you want to here
; install the exception handler:
push lbl_Exceptionhandler
push dword ptr [fs:0]
mov dword ptr[fs:0], esp
; setup the locals inside the stack
sub esp, LOCALS
; GS if you want to here
; call strcpy
lea ecx [ebp + offset_to_buffer];
push ecx
lea edx, [ebp + offset_to_attacker]
push edx
call _strcpy
add esp, 8
; uninstall the locals
mov esp, ebp
; uninstall the exception handler
pop dword ptr [fs:0]
; return
pop ebp
; optionally check GS cookies that we might have also inserted at any point in this function.
call _checksecuritycookie
ret
つまり、スタックは次のようになります。
RET PTR
/GS1
SAVED EBP
/GS2
SAVED FS:0
/GS3
LOCAL char buffer[N]
GS1、GS2、および GS3 は、スタック カナリアがスタック Cookie の書き込みを選択する場所です。Cookie は関数の最後にのみチェックされることに注意してください (これはコンピューターのセキュリティにとって重要です。チェックを導入するときは、チェックがオーバーフローを検出するかどうかだけでなく、オーバーフローが発生する前に検出するかどうかも考慮する必要があります。スタック Cookie の場合、通常、スタック Cookie は戻りアドレスを保護するためだけに存在し、ローカル変数を保護するためではないため、Cookie は関数の終了時にのみ検査されます)。
通常の例外ハンドラーの問題は、攻撃者のバッファーが非常に大きい場合に発生することです。それが非常に巨大で、スタック全体を破壊し、スレッドのガード ページに書き込み、障害をトリガーするとしましょう。
さて、カーネルは ntdll にコールバックし、プロセスを整理するように指示します。ntdll の最初の呼び出しポートは、登録された例外ハンドラーがあるかどうかを確認することです。では、呼び出す例外ハンドラをどのように見つけるのでしょうか。スタック上の例外ハンドラを指す fs:0 を調べて、例外ハンドラ ポインタを呼び出します。攻撃者が破壊したばかりのスタック上の例外ハンドラーを除いて。
おっとっと。これで、攻撃者が EIP を制御できるようになり、あなたは負けます。
Safe-SEH は、呼び出す可能性のある例外ハンドラーのリストが、実際にはコンパイル時に完全に決定される有限リストであることを指摘することで、この問題を解決します。このリストを PE ファイル自体に書き込むことにより、ntdll は、ジャンプ先の例外ハンドラーが実際には実際の例外ハンドラーであり、悪意のある攻撃者が EIP を乗っ取ろうとする計画の原因ではないことを再確認する機会があります。
Safe-SEH にはコストがかかります (オプトインする理由) が、そのコストは、例外ハンドラーが引き継ぐ前に ntdll がより多くの作業を行うようになるため、例外をキャッチするコストが高くなることです。
それにもかかわらず、私のアドバイスは、SafeSEH を常にオンにすることです。アプリのパフォーマンスは例外をスローする速度に大きく依存しているため、顧客のクレジット カードの詳細を簡単に紛失してしまうということは、開発者の精神がひどく壊れていることを示唆しており、開発者はすぐに大砲に入れられて太陽に向かって発砲されるべきです。社会に損害を与える恐ろしいコード。