DDI コンプライアンス バグのデバッグ - DRIVER_VERIFIER_DETECTED_VIOLATION (C4): 0x20002 - 0x20022

DDI コンプライアンスチェックオプションを 選択し、ドライバー検証ツールは、 ドライバーがDDI コンプライアンス規則のいずれかに違反していることを検出すると、 ドライバー検証ツールはバグ チェック 0xC4 DRIVER_VERIFIER_DETECTED_VIOLATIONを生成します (パラメーター 1 は、特定のコンプライアンス規則の識別子と同じです)。

DDI コンプライアンス ルールにより、ドライバーが Windows オペレーティング システム カーネルと正しく対話することが保証されます。 たとえば、規則は、ドライバーが関数に必要な IRQL で関数呼び出しを行うか、ドライバーがスピン ロックを正しく取得して解放することを確認します。 このセクションでは、これらの違反をデバッグするための戦略の例をいくつか説明します。

DDI コンプライアンスチェック違反のデバッグ

!analyze を使用してバグ チェックに関する情報を表示する

発生するバグ チェックと同様に、デバッガーを制御したら、最初に !analyze -v コマンドを 実行することをお勧 めします。

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught.  This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 00020004, ID of the 'IrqlExAllocatePool' rule that was violated.
Arg2: 8481c118, A pointer to the string describing the violated rule condition.
Arg3: 00000000, Reserved (unused).
Arg4: 00000000, Reserved (unused).

## Debugging Details:


DV_VIOLATED_CONDITION:  ExAllocatePoolWithTagPriority should only be called at IRQL <= DISPATCH_LEVEL.

DV_MSDN_LINK: https://go.microsoft.com/fwlink/p/?linkid=216021

DV_RULE_INFO: 0x20004

ドライバー検証ツール が DDI 準拠チェック違反を キャッチ するたびに 、違反に関する情報が !analyze 出力に 表示されます。

この例では、 バグ チェック 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION には、ドライバーが IrqlExAllocatePool コンプライアンス規則に違反 したことを示すパラメーター 1 (Arg1) 0x20004値があります。

!analyze の出力には次の情報が含まれています。

DV_VIOLATED_CONDITION: このフィールドには、ルール違反の原因の説明が表示されます。 この例では、ドライバーが非常に高いIRQLレベルでメモリを割り当てようとした、または DISPATCH_LEVEL でページ プール メモリを割り当てようとした、という条件が違反となっています。 たとえば、割り込みサービス ルーチン (ISR) で ExAllocatePoolWithTagPriority を呼び出 そうとしていたドライバーや、スピン ロックを保持しているときにページ プール メモリを割り当てようとしたドライバーなどです。

DV_MSDN_LINK: WinDBG では、これはライブ リンクであり、IrqlExAllocatePool ルールに関する詳細情報を示す MSDN ページがデバッガーで 開きます。

DV_RULE_INFO: WinDBG では、これはデバッガーで使用できるヘルプからこのルールに関する情報を表示するライブ リンクです。

!ruleinfo 拡張機能コマンドを使用する

!analyze 出力の DV_RULE_INFO: フィールドには、この規則違反に関する詳細情報を検索するために使用できるコマンドが表示されます。 この例では、コマンドを使用できます: !ruleinfo 0x20004

kd> !ruleinfo 0x20004

RULE_ID: 0x20004

RULE_NAME: IrqlExAllocatePool

RULE_DESCRIPTION:
The IrqlExAllocatePool rule specifies that the driver calls:
ExAllocatePool,
ExAllocatePoolWithTag,
ExAllocatePoolWithQuota,
ExAllocatePoolWithQuotaTag and
ExAllocatePoolWithTagPriority
only when it is executing at IRQL <= DISPATCH_LEVEL. A caller
executing at DISPATCH_LEVEL must specify a NonPagedXxx value
for PoolType. A caller executing at IRQL <= APC_LEVEL can
specify any POOL_TYPE value.

MSDN_LINK: https://go.microsoft.com/fwlink/p/?linkid=216021

!analyze-v コマンドを使用して、ソース コード内の違反の場所を特定します

この違反が見つかれば、ドライバー検証ツールはすぐにシステムチェックバグが発生します。 !analyze 出力には、現在の IRQL、現在のスタック、メモリを割り当てる呼び出しが行われたポイントが表示されます。ソース コードで有効になっている場合、 !analyze –v (詳細の場合) 出力には、割り当て要求が行われたソース ファイルと行番号も表示 されます。

CURRENT_IRQL:  10

ANALYSIS_VERSION: 6.13.0016.1929 (debuggers(dbg).130725-1857) amd64fre

LAST_CONTROL_TRANSFER:  from 80ff159d to 80f751f4

STACK_TEXT:  
82f9eaa4 81dda59d 00000003 86fab4b0 00000065 nt!RtlpBreakWithStatusInstruction
82f9eaf8 81dda0b7 82fa0138 82f9eef8 82f9ef40 nt!KiBugCheckDebugBreak+0x1f
82f9eecc 81d5cdc6 000000c4 00020004 85435118 nt!KeBugCheck2+0x676
82f9eef0 81d5ccfd 000000c4 00020004 85435118 nt!KiBugCheck2+0xc6
82f9ef10 8542cb4e 000000c4 00020004 85435118 nt!KeBugCheckEx+0x19
82f9ef30 85425ded ffffffff 85425e0d 82f9ef60 VerifierExt!SLIC_abort+0x40
82f9ef38 85425e0d 82f9ef60 8210c19e 00000080 VerifierExt!SLIC_ExAllocatePoolWithTagPriority_internal_entry_IrqlExAllocatePool+0x6f
82f9ef40 8210c19e 00000080 00000000 00000000 VerifierExt!ExAllocatePoolWithTagPriority_internal_wrapper+0x19
82f9ef60 826c9e16 00000000 00000000 00000000 nt!VerifierExAllocatePoolWithTag+0x24
82f9efa8 81d0726c 833cba80 8a4b9480 00000000 MyDriver!HandleISR+0x146
82f9efbc 81d071c1 833cba80 8a4b9480 000000b8 nt!KiInterruptMessageDispatch+0x12
82f9efe4 81d71f29 00000001 525b61ea 00000224 nt!KiCallInterruptServiceRoutine+0x6d
82f9efe8 00000000 525b61ea 00000224 00000000 nt!KiInterruptDispatch+0x49

STACK_COMMAND:  kb

FOLLOWUP_IP: 
MyDriver!HandleISR+0x140
826c9e10 ff154440699b    call    dword ptr [IrqlExAllocatePool_ExAllocatePoolWithTag!_imp__ExAllocatePoolWithTag (9b694044)]

FAULTING_SOURCE_LINE:  d:\drvsrc\mydriver\isrhandler.c

FAULTING_SOURCE_FILE:  d:\drvsrc\mydriver\isrhandler.c

FAULTING_SOURCE_LINE_NUMBER:  206

DDI コンプライアンス違反の原因を修正する

0x00020022に0x00020000範囲の Arg1 値を持つこれらのバグチェックを修正するには、通常、ドライバーが対応するドキュメントで説明されている API と DDI の使用条件を満たしていることを確認します。

ここで使用した例 (0x20004) では、ISR 内の任意の種類のメモリ割り当てが、ExAllocatePoolWithTagPriority ルーチンに設定されている IRQL 規則に違反します。

一般に、IRQL と適切な使用方法に関する情報については、ルーチンに関するドキュメントを確認する必要があります。 関数をテストする特定 の DDI コンプライアンス規則 を確認します。 この場合、ルールは IrqlExAllocatePool です

静的ドライバー検証ツール を使用して 、同じ規則を使用してドライバーのソース コードを分析します。 静的ドライバー検証ツールは、Windows ドライバーのソース コードをスキャンし、さまざまなコード パスの実行をシミュレートすることによって、考えられる問題を報告するツールです。 静的ドライバー検証ツールは、このような問題を特定するのに役立つ優れた開発時ユーティリティです。

DDI 準拠の検査

DDI コンプライアンス ルール

静的ドライバー検証ツール

バグ チェック 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION