自動チェック
Driver Verifier は、1 つ以上のドライバーを検証するたびに次のチェックを実行します。 これらのチェックを有効または無効にすることはできません。 Windows 10 バージョン 1709 以降、これらの自動チェックは関連する標準フラグに移動されました。 その結果、標準フラグを使用して Driver Verifier を有効にしているユーザーには、適用されるチェックが減少することはありません。
IRQL とメモリ ルーチンのモニタリング
Driver Verifier は、選択したドライバーで次の禁止されたアクションがないか監視します。
KeLowerIrql を呼び出して IRQL を上げる
KeRaiseIrql を呼び出して IRQL を下げる
サイズゼロのメモリ割り当てをリクエストする
IRQL APC>_LEVEL を使用したページ プールの割り当てまたは解放
IRQL >DISPATCH_LEVEL を使用した非ページ プールの割り当てまたは解放
以前の割り当てから返されなかったアドレスを解放しようとしています
すでに解放されているアドレスを解放しようとしています
IRQL >APC_LEVEL を使用した高速ミューテックスの取得または解放
IRQL が DISPATCH_LEVEL に等しくない場合のスピン ロックの取得または解放
スピンロックを2回解除します。
割り当てリクエストを MUST_SUCCEED とマークします。 そのような要求は決して許されません。
Driver Verifier がアクティブでない場合、これらの違反によってすべての場合に直ちにシステム クラッシュが発生するわけではありません。 Driver Verifier はドライバーの動作を監視し、これらの違反が発生した場合はバグ チェック 0xC4 を発行します。 バグ チェック パラメータのリストについては、バグ チェック 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) を参照してください。
スタック切り替えの監視
Driver Verifier は、検証対象のドライバーによるスタックの使用状況を監視します。 ドライバーがスタックを切り替え、新しいスタックがスレッド スタックでも DPC スタックでもない場合、バグ チェックが発行されます。 (これは、最初のパラメータが 0x90 に等しいバグ チェック 0xC4 になります。)KB デバッガー コマンドによって表示されるスタックには、通常、この操作を実行したドライバーが表示されます。
ドライバーのアンロードを確認する
検証対象のドライバーがアンロードされた後、Driver Verifier はドライバーがクリーンアップされたことを確認するためにいくつかのチェックを実行します。
特に、Driver Verifier は以下を探します。
削除されていないタイマー
保留中の遅延プロシージャ コール (DPC)
削除されていないルックアサイド リスト
削除されていないワーカー スレッド
削除されていないキュー
その他の同様のリソース
このような問題により、ドライバーがアンロードされてからしばらくしてからシステム バグ チェックが発行される可能性があり、これらのバグ チェックの原因を特定するのが難しい場合があります。 Driver Verifier がアクティブな場合、そのような違反があると、ドライバーがアンロードされた直後にバグ チェック 0xC7 が発行されます。 バグ チェック パラメータのリストについては、バグ チェック 0xC7 (TIMER_OR_DPC_INVALID) を参照してください。
メモリ記述子リスト (MDL) の使用状況の監視
Windows Vista では、Driver Verifier は、選択されたドライバーの次の禁止されたアクションも監視します。
適切なフラグを持たない MDL で MmProbeAndLockPages または MmProbeAndLockProcessPages を呼び出します。 たとえば、MmBuildMdlForNonPagesPool を使用して作成された MDL に対して MmProbeAndLockPages を呼び出すことは正しくありません。
適切なフラグを持たない MDL で MmMapLockedPages を呼び出します。 たとえば、すでにシステム アドレスにマップされている MDL やロックされていない MDL に対して MmMapLockedPages を呼び出すことは正しくありません。
部分 MDL (つまり、IoBuildPartialMdl を使用して作成された MDL) で MmUnlockPages または MmUnmapLockedPages を呼び出します。
システム アドレスにマップされていない MDL で MmUnmapLockedPages を呼び出す。
Driver Verifier がアクティブでない場合、これらの違反によって、すべての場合にシステムがすぐに応答を停止するわけではありません。 Driver Verifier はドライバーの動作を監視し、これらの違反が発生した場合はバグ チェック 0xC4 を発行します。 バグ チェック パラメータのリストについては、バグ チェック 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) を参照してください。
NonPaggedPoolSession メモリからの同期オブジェクトの割り当て
Windows 7 以降、Driver Verifier はセッション メモリから同期オブジェクトをチェックします。
同期オブジェクトはページング不可能である必要があります。 また、グローバルなシステム全体の仮想アドレス空間に存在する必要もあります。
グラフィックス ドライバーは、EngAllocMem などの API を呼び出してセッション メモリを割り当てることができます。 グローバル アドレス空間とは異なり、セッション アドレス空間はターミナル サーバー セッションごとに仮想化されます。 これは、2 つの異なるセッションのコンテキストで使用される同じ仮想アドレスが 2 つの異なるオブジェクトを参照することを意味します。 Windows カーネルは、任意のターミナル サーバー セッションから同期オブジェクトにアクセスできる必要があります。 別のセッションからセッション メモリ アドレスを参照しようとすると、システムのクラッシュや別のセッションのデータのサイレント破損など、予期しない結果が発生します。
Windows 7 以降では、検証済みドライバーが KeInitializeEvent や KeInitializeMutex などの API を呼び出して同期オブジェクトを初期化するときに、Driver Verifier はオブジェクトのアドレスがセッション仮想アドレス空間内にあるかどうかを確認します。 Driver Verifier がこの種の不正なアドレスを検出すると、バグ チェック 0xC4 を発行します。DRIVER_VERIFIER_DETECTED_VIOLATION、パラメーター 1 の値は 0xDF です。
オブジェクト参照カウンタが 0 から 1 に変化する
Windows 7 以降、Driver Verifier は、不正なオブジェクト参照の追加クラスをチェックします。
Windows カーネル オブジェクト マネージャーが File オブジェクトや Thread オブジェクトなどのオブジェクトを作成すると、新しいオブジェクトの参照カウンターが 1 に設定されます。 参照カウンターは、ObReferenceObjectByPointer や ObReferenceObjectByHandle などの API の呼び出しによって増加します。 参照カウンタは、同じオブジェクトに対する ObDereferenceObject 呼び出しごとにデクリメントされます。
参照カウンタが 0 の値に達すると、オブジェクトは解放できるようになります。 オブジェクト マネージャーはそれをすぐに解放することも、後で解放することもできます。 ObReferenceObjectByPointer または ObDereferenceObject を呼び出して参照カウンタを 0 から 1 に変更することは、すでに解放されているオブジェクトの参照カウンタをインクリメントすることを意味します。 これは、他の誰かのメモリ割り当てを破損する可能性があるため、常に間違っています。
システムシャットダウンのブロックまたは遅延
Windows 7 以降、システムのシャットダウンが開始から 20 分経過しても終了しない場合、Driver Verifier はカーネル デバッガーにブレークを発行します。 Driver Verifier は、Windows カーネルがレジストリ、プラグ アンド プレイ、I/O マネージャー サブシステムなどのさまざまなサブシステムのシャットダウンを開始する時刻としてシステム シャットダウンの開始を割り当てます。
カーネル デバッガーがシステムに接続されていない場合、ドライバー検証ツールはバグ チェック 0xC4 を発行します。このブレークポイントの代わりに、パラメーター 1 の値が 0x115 の DRIVER_VERIFIER_DETECTED_VIOLATION。
多くの場合、システムのシャットダウンが 20 分以内に完了しない場合は、そのシステムで実行されているドライバーの 1 つが誤動作していることを示しています。 カーネル デバッガーから !analyze -v を実行すると、シャットダウンの原因となったシステム ワーカー スレッドのスタック トレースが表示されます。 そのスタック トレースを調べて、テスト対象のドライバーのいずれかによってシャットダウン スレッドがブロックされているかどうかを判断する必要があります。
すべてのドライバーが正しく機能しているにもかかわらず、システムが高負荷テストの対象となるためにシャットダウンできない場合があります。 ユーザーは、この Driver Verifier ブレークポイントの後に実行を続行し、システムが最終的にシャットダウンするかどうかを確認することを選択できます。