Kernel Address Sanitizer (KASAN) は、Windows カーネル ドライバーでサポートされているバグ検出テクノロジです。これにより、バッファー オーバーフローや空き時間の使用イベントなど、いくつかのクラスの無効なメモリ アクセスを検出できます。 システムで KASAN を有効にし、特定の MSVC コンパイラ フラグを使用してカーネル ドライバーを再コンパイルする必要があります。
前提条件
KASAN を使用するには、次のものが必要です。
- カーネル ドライバーが読み込まれるターゲット システムの OS バージョン:
- クライアント: Windows 11 24H2 以降。
- サーバー: Windows Server 2025 以降。
- VisualStudio: バージョン 17.11 以降。
- WDK: バージョン 10.0.26100.2161 以降。
KASAN は x64 でのみサポートされています。
カーネル ドライバーで KASAN を有効にする方法
ターゲット システムの管理者 コマンド プロンプト ウィンドウに次のコマンド ラインを入力します。
reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Kernel" /v KasanEnabled /t REG_DWORD /d 1
このレジストリ キーを設定すると、WINDOWS カーネルに、KASAN インストルメント化されたドライバーの読み込みを準備して受け入れるように指示されます。 このレジストリ キーを設定しないと、WINDOWS カーネルは、KASAN インストルメント化されたドライバーの読み込みを拒否します。
変更を有効にするには、ターゲット システムを再起動します。
MSVC コンパイラに新しいフラグを渡して、KASAN インストルメンテーションを有効にしてカーネル ドライバーを再コンパイルします。 次のいずれかの方法を使用します。
- GUI: VisualStudio で、ソリューション エクスプローラーに移動し、カーネル ドライバー プロジェクトを右クリックして、Properties を選択します。 プロパティ ページで、 Configuration Properties>>C/C++>>General に移動し、 Enable Kernel Address Sanitizer を Yes に設定します。 次に、ソリューションをリビルドします。
- コマンド プロンプト: /fsanitize=kernel-address パラメーターをコンパイラのコマンド ラインに追加します。 次に、ソリューションをリビルドします。
再コンパイルされたカーネル ドライバーをターゲット システムに読み込み、通常と同様にストレス テストします。 KASAN は実行時に動作し、 Bug Check 0x1F2: KASAN_ILLEGAL_ACCESSを介して無効なメモリ アクセス イベントを報告します。
カーネル ドライバーで KASAN が有効になっていることを確認する方法
KASAN でコンパイルされたカーネル ドライバーには、"KASAN
" という PE セクションがあります。
Developer コマンド プロンプトで次のコマンドを実行して、ドライバーで KASAN が有効になっていることを確認します
dumpbin /ALL YourDriver.sys
出力に "KASAN
" という名前のセクションが含まれている場合は、ドライバーで KASAN が有効になります。
KASN レポートを分析する方法
KASAN は、ドライバーで無効なメモリ アクセスを検出すると、 Bug Check 0x1F2: KASAN_ILLEGAL_ACCESSを発行します。 生成されたカーネル メモリ ダンプを調べて、ドライバーが無効なメモリ アクセスを正確に実行した場所を特定します。
ターゲット システムにアタッチされたカーネル デバッガーと共に KASAN を使用して、メモリ ダンプを使用した事後検証ではなく、バグ チェックが発行されるとすぐにメモリを動的に検査できるようにします。
バグ チェック パラメーター
Bug Check 0x1F2: KASAN_ILLEGAL_ACCESSのパラメーターは次のとおりです。
- パラメーター 1: 不正にアクセスされているアドレス。
- パラメーター 2: メモリ アクセスのサイズ。
- パラメーター 3: 無効なメモリ アクセスを実行している呼び出し元のアドレス。
- パラメーター 4: メモリ アクセスに関する追加情報:
- ビット [0:7]: KASAN シャドウ コード。 この後の表を参照してください。
- ビット 8: アクセスが書き込みであった場合は
1
、読み取り0
。
KASAN シャドウ コード
KASAN では、すべてのカーネル メモリが、8 バイトでアラインされた 8 バイトの cells の連続したチャンクに分割されると考。 KASAN では、カーネル メモリ内の各 8 バイト セルに シャドウ コードが関連付けられます セルの有効性を示す 1 バイト整数です。 シャドウ コードのエンコードは次のとおりです。
値 | 意味 |
---|---|
0x00 |
セルは完全に有効です。セルの 8 バイトすべてにアクセスすることは有効です。 |
0x01 ->0x07 |
セルは部分的に有効です。セルの最初の value バイトは有効ですが、残りは無効です。 |
0x08 ->0x7F |
セルは条件付きで有効です。セルのすべての 8 バイトへのアクセスは、特定の条件に応じて有効または無効になる可能性があります。 |
>= 0x80 |
セルは完全に無効です。セルの 8 バイトすべてにアクセスすることは無効です。 |
条件付きで有効で完全に無効なセルに対していくつかのサブコードが使用され、セルが関連付けられているメモリの種類と、そのセルへのアクセスが無効になる理由をさらに示します。
条件付きで有効なセルで使用されるサブコード:
-
0x09
: ページング可能なメモリ。 DISPATCH_LEVEL 以上ではアクセスできませんが、それ以外の場合はアクセスできます。
完全に無効なセルで使用されるサブコード:
-
0x81
: alloca の左のレッドゾーン。 -
0x82
: alloca の中央のレッドゾーン。 -
0x83
: alloca の右のレッドゾーン。 -
0x84
: グローバル変数の右のレッドゾーン。 -
0x85
: 汎用の redzone。 -
0x86
: プール メモリの右のレッドゾーン。 -
0x87
: プール メモリが解放されました。 -
0x8A
: 連続するメモリの左のレッドゾーン。 -
0x8B
: 連続するメモリの右のレッドゾーン。 -
0x8C
: ルックアサイドリストメモリを解放しました。 -
0x8D
: プール メモリの左のレッドゾーン。 -
0xF1
: スタック変数の左のレッドゾーン。 -
0xF2
: スタック変数の中央のレッドゾーン。 -
0xF3
: スタック変数の右のレッドゾーン。 -
0xF5
: used-after-ret スタック変数。 -
0xF8
: スコープ外のスタック変数。
KASAN のバグ チェックを理解する: 例
ドライバーの実行時に、次のパラメーターを使用して、KASAN がバグ チェックを発行したとします。
- パラメーター 1:
0xFFFFFFFFFFFFABCD
- パラメーター 2:
0x0000000000000004
- パラメーター 3:
0xFFFFFFFF12345678
- パラメーター 4:
0x0000000000000184
パラメーター 1 は、ドライバーがアドレス 0xFFFFFFFFFFFFABCD
へのアクセスを試み、このアクセスが無効であることを示します。
パラメーター 2 は、それが 4 バイトのアクセスであることを示します。
パラメーター 3 は、ドライバーが無効なアクセスを実行した命令ポインターのアドレスを示します。
パラメーター 4 は、これが書き込みアクセスであり、タッチされるメモリがグローバル変数の右のレッドゾーンであることを示します。
つまり、ドライバーがグローバル変数に対して書き込みバッファー オーバーフローを実行しようとした可能性があります。 この情報を使用して、調査し、ドライバーでこのバグを修正する場所と方法を決定します。
KASAN のパフォーマンスへの影響
KASAN はカーネル メモリの消費量を増やし、KASAN を有効にしてコンパイルされたドライバーで約 2 倍の速度低下を発生させます。
ドライバー検証ツールとの比較
KASAN とドライバー検証ツールは完全に独立した機能ですが、相互に互換性があります。
KASAN は無効なメモリ アクセスの検出に重点を置き、より詳細なアプローチを使用し、より多くのメモリ領域をカバーするため、そのドメインのドライバー検証ツールよりも効率的です。 ドライバー検証ツールには、その他の種類のバグを見つけることを目的とするドライバー固有の規則があり、この規則では、KASAN では検出されません。 詳細については、「 Microsoft: Microsoft プラットフォームでのカーネルサニタイザーの概要を参照してください。
KASAN をドライバー検証ツールと組み合わせて使用して、ドライバーのバグの検出を最大化します。