はい、.NET ジッターは、/GS コンパイラ オプションを使用して Microsoft C/C++ コンパイラによって生成されたネイティブ コードにも存在する一種のスタック カナリア チェックを生成します。基本的なスキームは、ランダムな 32 ビット値をスタックの一番上に格納し、メソッド エントリに書き込むことです。メソッドの終了時に、値がまだそこにあるかどうかをチェックします。値の変化は、マルウェアがプログラムを制御するために使用する種類のスタック バッファ オーバーフローの非常に高い予測因子です。
遊ぶためのいくつかのコード:
class Program {
static void Main(string[] args) {
Kaboom();
}
static unsafe void Kaboom() {
byte* ptr = stackalloc byte[1];
for (int ix = 0; ix < 42; ++ix) ptr[ix] = 0;
}
}
このコードを実行すると、デバッガーが接続されていても、Windows エラー報告ダイアログがトリガーされます。[出力] ウィンドウでクラッシュの理由を確認できます。
プログラム '[3636] ConsoleApplication33.exe: Native' はコード -1073740791 (0xc0000409) で終了しました。
例外コードは、ntstatus.h SDK ヘッダー ファイルで定義されています。
//
// MessageId: STATUS_STACK_BUFFER_OVERRUN
//
// MessageText:
//
// The system detected an overrun of a stack-based buffer in this application. This overrun could
// potentially allow a malicious user to gain control of this application.
//
#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409L) // winnt
Debug + Windows + Disassembly でこれを行うコードを確認できます。Kaboom の重要な部分:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 sub esp,8 ; stack space for local variables
00000006 xor eax,eax
00000008 mov dword ptr [ebp-8],eax ; zero-initialize local variables
0000000b mov dword ptr [ebp-4],eax
0000000e mov dword ptr [ebp-4],esp
00000011 mov dword ptr [ebp-8],0EDDB7EDFh ; canary stored here
// For loop code omitted
0000002d cmp dword ptr [ebp-8],0EDDB7EDFh ; check canary value
00000034 je 0000003B
00000036 call 727767A8 ; crash program
0000003b lea esp,[ebp] ; normal exit, pop stack frame
0000003e pop ebp
0000003f ret
実際のカナリア値は、コードがジットされるたびに変化します。