その他の検査

ドライバー検証ツールの [その他のチェック] オプションは、アクティブなカーネル オブジェクトを含むメモリの解放など、ドライバーまたはシステムがクラッシュする一般的なエラーがないかドライバーを監視します。

具体的には、[その他のチェック] オプションは、次の不適切なドライバーの動作を検索します。

  • 解放されたメモリ内のアクティブな作業項目。 ドライバーは ExFreePool を呼び出して、 IoQueueWorkItem を使用してキューに登録された作業項目を含むプール ブロックを解放します。

  • 解放されたメモリ内のアクティブなリソース。 ドライバーは ExFreePool を呼び出して、アクティブな ERESOURCE 構造体を含むプール ブロックを解放します。 ドライバーは ExFreePool を呼び出す前に、 ExDeleteResource を呼び出して ERESOURCE オブジェクトを削除する必要があります。

  • 解放されたメモリ内のアクティブなルックアサイド リスト。 ドライバーは ExFreePool を呼び出して、アクティブなルックアサイド リスト (NPAGED_LOOKASIDE_LIST または PAGED_LOOKASIDE_LIST 構造体をまだ含むプール ブロックを解放します。 ExFreePool を呼び出す前に、 ExDeleteNPagedLookasideList または ExDeletePagedLookasideList を呼び出してルックアサイド リストを削除する必要があります。

  • Windows Management Instrumentation (WMI) と Event Tracing for Windows (ETW) の登録に関する問題。 ドライバー検証ツールによって検出されるこのような問題は次のとおりです。

    • WMI コールバックの登録を解除せずにアンロードを試みるドライバー。

    • WMI から登録解除されていないデバイス オブジェクトを削除しようとするドライバー。

    • ETW カーネル モード プロバイダーの登録を解除せずにアンロードを試みるドライバー。

    • 既に登録解除されているプロバイダーの登録を解除しようとするドライバー。

  • カーネル ハンドル エラー。 (Windows Vista 以降のバージョン)[その他のチェック] オプションを有効にすると、システム プロセスのハンドル トレースも有効になり、カーネル ハンドルのリークと バグ チェックの0x93: INVALID_KERNEL_HANDLE の調査に役立ちます。 ハンドル トレースを有効にすると、カーネルは最近のハンドルのオープン操作とクローズ操作のスタック トレースを収集します。 スタック トレースは、 !htrace デバッガー拡張機能を使用してカーネル デバッガーに表示できます。 !htrace の詳細については、Debugging Tools for Windows のドキュメントを参照してください。

  • Windows 7 以降のカーネル モード アクセスを使用するユーザー モード ハンドル では、[その他のチェック] オプションを選択すると、ドライバー検証ツールは ObReferenceObjectByHandle への呼び出しにもチェックします。 カーネル モード アクセスでユーザー モード ハンドルを渡すことはできません。 このような操作が発生した場合、ドライバー検証ツールはバグ チェック 0xC4を発行し、パラメーター 1 の値を0xF6します。

  • カーネル スタックに割り当てられた同期オブジェクトの UserMode 待機

    Windows 7 以降では、ドライバー検証ツールは、オペレーティング システムが提供するマルチスレッド同期メカニズムをドライバーが誤って使用する可能性がある追加の方法を検出できます。

    カーネル スタック上のローカル変数として、KEVENT 構造体などの同期オブジェクトを割り当てることが一般的な方法です。 プロセスがメモリに読み込まれている間、スレッドのカーネル スタックがワーキング セットからトリミングされたり、ディスクにページングされたりすることはありません。 このようなページング不可能なメモリに同期オブジェクトを割り当てることは正しいです。

    ただし、ドライバーが KeWaitForSingleObjectKeWaitForMultipleObjects などの API を呼び出してスタックに割り当てられているオブジェクトを待機する場合は、API の WaitMode パラメーターに KernelMode 値を指定する必要があります。 プロセスのすべてのスレッドが UserMode モードで待機している場合、そのプロセスはディスクにスワップアウトされる資格があります。 そのため、ドライバーが WaitMode パラメーターとして UserMode を指定した場合、オペレーティング システムは、同じプロセス内の他のすべてのスレッドも UserMode として待機している限り、現在のプロセスをスワップ アウトできます。 プロセス全体をディスクにスワップアウトするには、カーネル スタックのページングが含まれます。 オペレーティング システムがスワップアウトした同期オブジェクトの待機が正しくありません。 ある時点で、スレッドが一緒に来て、同期オブジェクトに通知する必要があります。 同期オブジェクトの通知には、IRQL = DISPATCH_LEVEL 以上でオブジェクトを操作する Windows カーネルが含まれます。 DISPATCH_LEVEL以上でページアウトまたはスワップアウトされたメモリに触れると、システムがクラッシュします。

    Windows 7 以降では、[その他のチェック] オプションを選択すると、検証済みドライバーが UserMode での待機に使用する同期オブジェクトが現在のスレッドのカーネル スタックに割り当てられないことがドライバー検証ツールによってチェックされます。 ドライバー検証ツールは、このような不適切な待機を検出すると、0x123のパラメーター 1 値を使用して、 バグ チェック 0xC4 DRIVER_VERIFIER_DETECTED_VIOLATION を発行します。

  • カーネル ハンドル参照が正しくありません

    各 Windows プロセスにはハンドル テーブルがあります。 ハンドル テーブルは、ハンドル エントリの配列として表示できます。 有効な各ハンドル値は、この配列内の有効なエントリを参照します。

    システム プロセスの ハンドル テーブルに対して有効なハンドルとしての カーネル ハンドルシステム プロセス を除くすべてのプロセスに対して有効なハンドルとしてのユーザー ハンドル。

    Windows 7 では、ドライバー検証ツールは、正しくないカーネル ハンドル値を参照しようとします。 これらのドライバーの欠陥は、ドライバー検証ツールのその他のチェック オプションが有効になっている場合、 バグ チェック 0x93: INVALID_KERNEL_HANDLE として報告されます。 通常、この種の不適切なハンドル参照は、ドライバーが既にそのハンドルを閉じているが、それを引き続き使用しようとしていることを意味します。 この種の欠陥により、参照されているハンドル値が別の関連のないドライバーによって既に再利用されている可能性があるため、システムに予期しない問題が発生する可能性があります。

    カーネル ドライバーが最近カーネル ハンドルを閉じ、後で閉じたハンドルを参照する場合、ドライバー検証ツールは、前に説明したようにバグチェックを強制します。 この場合、 !htrace デバッガー拡張機能の出力は、このハンドルを閉じたコード パスのスタック トレースを提供します。 !htrace のパラメーターとして、システム プロセスのアドレスを使用します。 システム プロセスのアドレスを検索するには、 !process 4 0 コマンドを使用します。

    Windows 7 以降、ドライバー検証ツールは ObReferenceObjectByHandle にチェックを追加します。 KernelMode アクセスを使用してユーザー空間ハンドルを渡すことが禁止されるようになりました。 このような組み合わせが検出された場合、ドライバー検証ツールは、0xF6のパラメーター 1 の値を持つ バグ チェック 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION を発行します。

このオプションのアクティブ化

Driver Verifier Manager または Verifier.exe コマンド ラインを使用して、1 つ以上のドライバーの その他のチェック オプションをアクティブにできます。 詳細については、 「ドライバー検証ツール オプションの選択」を参照してください 。

  • コマンド ラインで

    コマンド ラインでは、[その他のチェック] オプションは ビット 11 (0x800) で表されます。 その他のチェックを有効にするには、0x800のフラグ値を使用するか、フラグ値に0x800を追加します。 次に例を示します。

    verifier /flags 0x800 /driver MyDriver.sys
    

    このオプションは、次の起動時にアクティブになります。

    Windows Vista 以降のバージョンの Windows では、コマンドに /volatile パラメータを追加することで、コンピュータを再起動せずにその他のチェックをアクティブまたは非アクティブにすることもできます。 次に例を示します。

    verifier /volatile /flags 0x800 /adddriver MyDriver.sys
    

    この設定はすぐに有効になりますが、コンピューターをシャットダウンまたは再起動すると失われます。 詳細については、「揮発性設定の使用」を参照してください。

    [その他のチェック] オプションも標準設定に含まれています。 次に例を示します。

    verifier  /standard /driver MyDriver.sys
    
  • ドライバー検証ツール マネージャーの使用

    1. ドライバー検証ツール マネージャーを起動します。 コマンド プロンプト ウィンドウで、 検証ツール と入力します。

    2. [カスタム設定の作成 (コード開発者用)] を選択し、 [次へ] をクリックします。

    3. 全一覧から [個々の設定を選択]を選択します。

    4. [その他のチェック] を選択 します。

    [その他のチェック] 機能も標準設定に含まれています。 この機能を使用するには、ドライバー検証ツール マネージャーで、 [標準設定の作成] をクリックします。

結果の表示

[その他のチェック] オプションの結果を表示するには、カーネル デバッガーで !verifier 拡張機能を使用します。 (!verifier の情報については、 Debugging Tools for Windows のドキュメントを参照してください。)

次の例では、その他のチェック オプションにより、ドライバーが解放しようとしていたメモリ内でアクティブな ERESOURCE 構造体が検出され、 バグ チェック 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION が発生しました。 バグ チェック 0xC4表示には、ERESOURCE のアドレスと影響を受けるメモリが含まれます。

1: kd> !verifier 1

Verify Level 800 ... enabled options are:
 Miscellaneous checks enabled

Summary of All Verifier Statistics

RaiseIrqls                             0x0
AcquireSpinLocks                       0x0
Synch Executions                       0x0
Trims                                  0x0

Pool Allocations Attempted             0x1
Pool Allocations Succeeded             0x1
Pool Allocations Succeeded SpecialPool 0x0
Pool Allocations With NO TAG           0x0
Pool Allocations Failed                0x0
Resource Allocations Failed Deliberately   0x0

Current paged pool allocations         0x0 for 00000000 bytes
Peak paged pool allocations            0x0 for 00000000 bytes
Current nonpaged pool allocations      0x0 for 00000000 bytes
Peak nonpaged pool allocations         0x0 for 00000000 bytes

Driver Verification List

Entry     State           NonPagedPool   PagedPool   Module

8459ca50 Loaded           00000000       00000000    buggy.sys



*** Fatal System Error: 0x000000c4
 (0x000000D2,0x9655D4A8,0x9655D468,0x000000B0)


        0xD2 : Freeing pool allocation that contains active ERESOURCE.
               2 -  ERESOURCE address.
               3 -  Pool allocation start address.
               4 -  Pool allocation size.

プールの割り当てを調査するには、プール割り当ての開始アドレス (9655D468) で !pool デバッガー拡張機能を使用します。 (2 フラグは、指定されたアドレスを含むプールのヘッダー情報のみを表示します。他のプールのヘッダー情報は抑制されます。)

1: kd> !pool 9655d468  2
Pool page 9655d468 region is Paged pool
*9655d468 size:   b0 previous size:    8  (Allocated) *Bug_

ERESOURCE に関する情報を検索するには、 !locks (!kdext*.locks) デバッガー拡張機能を構造体のアドレスと共に使用します。

1: kd> !locks 0x9655D4A8     <<<<<- ERESOURCE @0x9655D4A8 lives inside the pool block being freed

Resource @ 0x9655d4a8    Available
1 total locks

また、 kb デバッガー コマンドを使用して、エラーの原因となった呼び出しのスタック トレースを表示することもできます。 次の例は、ドライバー検証ツールがインターセプトした ExFreePoolWithTag の呼び出しを含むスタックを示しています。

1: kd> kb
ChildEBP RetAddr  Args to Child
92f6374c 82c2c95a 00000003 92f68cdc 00000000 nt!RtlpBreakWithStatusInstruction
92f6379c 82c2d345 00000003 9655d468 000000c4 nt!KiBugCheckDebugBreak+0x1c
92f63b48 82c2c804 000000c4 000000d2 9655d4a8 nt!KeBugCheck2+0x5a9
92f63b6c 82e73bae 000000c4 000000d2 9655d4a8 nt!KeBugCheckEx+0x1e
92f63b88 82e78c32 9655d4a8 9655d468 000000b0 nt!VerifierBugCheckIfAppropriate+0x3c
92f63ba4 82ca7dcb 9655d468 000000b0 00000000 nt!VfCheckForResource+0x52
92f63bc8 82e7fb2d 000000b0 00000190 9655d470 nt!ExpCheckForResource+0x21
92f63be4 82e6dc6c 9655d470 92f63c18 89b6c58c nt!ExFreePoolSanityChecks+0x1fb
92f63bf0 89b6c58c 9655d470 00000000 89b74194 nt!VerifierExFreePoolWithTag+0x28
92f63c00 89b6c0f6 846550c8 846550c8 846e2200 buggy!MmTestProbeLockForEverStress+0x2e
92f63c18 82e6c5f1 846e2200 846550c8 85362e30 buggy!TdDeviceControl+0xc4
92f63c38 82c1fd81 82d4d148 846550c8 846e2200 nt!IovCallDriver+0x251
92f63c4c 82d4d148 85362e30 846550c8 84655138 nt!IofCallDriver+0x1b
92f63c6c 82d4df9e 846e2200 85362e30 00000000 nt!IopSynchronousServiceTail+0x1e6
92f63d00 82d527be 00000001 846550c8 00000000 nt!IopXxxControlFile+0x684
92f63d34 82cb9efc 0000004c 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
92f63d34 6a22b204 0000004c 00000000 00000000 nt!KiFastCallEntry+0x12c