Windows ドライバーの不具合を見つけるための静的ドライバー検証ツールの使用

静的ドライバー検証ツール (SDV) は、一連のインターフェイス規則とオペレーティング システムのモデルを使用して、ドライバーが Windows オペレーティング システムと正しく対話するかどうかを判断します。 SDV は、ドライバーの潜在的なバグを示す可能性があるドライバー コードの欠陥を検出します。

SDV は、WDM、KMDF、NDIS、または Storport のいずれかのドライバー モデルに準拠するカーネル モード ドライバーを分析できます。 詳細については、サポートされているドライバーおよび「ドライバーまたはライブラリが静的ドライバー検証ツールでサポートされているかどうかの判定」を参照してください。 さらに、SDV では、上記のドライバー モデルに従わないドライバーの限られたサポート (null 逆参照などの一般的なエラーに重点を置いた厳しく制限された規則セット) が提供されます。

ソース コードの準備

次の手順を使用して、分析用のコードを準備します。

  1. 関数ロール型を使用してドライバー提供の関数を宣言する

    SDV では、関数ロール型宣言を使用して関数を宣言する必要があります。 たとえば、DriverEntry ルーチンは、DRIVER_INITIALIZE 関数ロール型を使用して宣言する必要があります。

    DRIVER_INITIALIZE DriverEntry;
    

    宣言の後、コールバック ルーチンを次のように実装 (または定義) します。

    /
    // Driver initialization routine
    //
    NTSTATUS
      DriverEntry(
        _In_ struct _DRIVER_OBJECT  *DriverObject,
        _In_ PUNICODE_STRING  RegistryPath
        )
      {
          // Function body
      }
    

    サポートされている各ドライバー モデルには、ドライバーコールバック関数とディスパッチ ルーチンの一連の関数ロールの種類があります。 これらの関数ロールの種類は、WDK ヘッダー ファイルで宣言されています。 たとえば、Wdm.h に表示されるDRIVER_INITIALIZEロールの種類の関数プロトタイプを次に示します。

    /
    // Define driver initialization routine type.
    //
    _Function_class_(DRIVER_INITIALIZE)
    _IRQL_requires_same_
    typedef
    NTSTATUS
    DRIVER_INITIALIZE (
        _In_ struct _DRIVER_OBJECT *DriverObject,
        _In_ PUNICODE_STRING RegistryPath
        );
    
    typedef DRIVER_INITIALIZE *PDRIVER_INITIALIZE;
    

    関数ロールの型は WDK ヘッダー ファイルで既に定義されているため、コールバック関数をその型として宣言するだけで済みます。 この場合は、DriverEntryDRIVER_INITIALIZE 型として宣言します。 ドライバー モデルの関数ロールの種類の完全な一覧については、「関数ロール型宣言の使用」を参照してください。

  2. C/C++ 実行コード分析

    ソース コードが準備されているかどうかを判断するには、Visual Studio でコード分析ツールを実行します。 コード分析ツールは、SDV に必要な関数ロールの型宣言をチェックします。 コード分析ツールは、見落とされた可能性のある関数宣言を特定したり、関数定義のパラメーターが関数ロール型のパラメーターと一致しない場合に警告したりするのに役立ちます。

    • Visual Studio でドライバーのプロジェクトを開きます。
    • [ビルド] メニューで、[ソリューションでコード分析を実行] をクリックします。

    結果がコード分析ウィンドウに表示されます。 見逃した可能性がある関数宣言を修正します。 ソリューションをビルドするたびに実行されるようにコード分析ツールを構成することもできます。

    次の表は、コード分析ツールがドライバー コードで検出する可能性がある警告の一部を示しています。 静的ドライバー検証ツールを実行するには、ドライバーにこれらの欠陥がない必要があります。

    C/C++ 警告のコード分析 説明
    C28101 Drivers モジュールは、現在の関数が <function-type> の関数ではないと推測しました
    C28022 この関数の関数クラスが、定義に使用された typedef の関数クラスと一致しません。
    C28023 割り当てられている関数、または渡されている関数には、少なくとも 1 つのクラスに対する _Function_class_ annotation が必要です
    C28024 割り当てられている関数ポインターが関数クラスで注釈を付けられています。これは関数クラス一覧には含まれません。
    C28169 ディスパッチ関数<機能>には、_Dispatch_type_ アノテーションがありません
    C28208 関数シグネチャが関数宣言と一致しません

静的ドライバー検証ツールの実行

  1. Visual Studio でドライバー プロジェクト (.vcxProj) ファイルを開きます。 Driver メニューから Launch Static Driver Verifier… をクリックします。

    これにより、静的ドライバー検証ツール アプリケーションが開き、静的ドライバー検証ツールが分析を実行するタイミングを制御、構成、およびスケジュールできます。

  2. ドライバーにライブラリが含まれている場合は、[ライブラリ] タブをクリックし、[ライブラリの追加] をクリックしてライブラリを追加します。

    ライブラリ のソース コードのディレクトリを参照し、プロジェクト ファイル (.vcxProj) を選択します。 ドライバーに含まれるすべてのライブラリを追加します。 SDV がドライバーを分析する前に、ライブラリを追加する必要があります。 ドライバーの分析を開始すると、SDV は処理されていないライブラリも分析します。 ライブラリが処理されると、グローバル SDV キャッシュに格納されます。 詳細については、「静的ドライバー検証ツールでのライブラリ処理」を参照してください 。

  3. 静的ドライバー検証ツールの構成設定を確認します。 [ 構成 ] タブをクリックします。

    [プロジェクトの構成] プロジェクト構成には、Visual Studio で選択した構成とプラットフォームの設定が表示されます。

    リソース ほとんどの場合、既定の設定を使用できます。 SDV がタイムアウト、ギブアップ、またはスペースアウトを報告する場合は、これらの設定を調整してみてください。 詳細については、「静的ドライバー検証ツール のトラブルシューティングに関する推奨事項」を参照してください。

    スケジュール 確認を開始する開始時刻を選択します。 既定の設定では、[メイン] タブで [スタート] をクリックした直後に分析を開始します。ドライバーのサイズとその複雑さに応じて、静的分析の実行に時間がかかる場合があります。 たとえば、1 日の終わりなど、最も都合の良いときに分析を開始するようにスケジュールすることができます。

    Note

    ] 分析中にコンピューターがスリープ状態にならないように、コンピューターの電源管理計画を必ず確認してください。

  4. [ルール] タブをクリックして、分析を開始するときに確認するドライバー API の使用規則を選択します。

    静的ドライバー検証ツールは、分析しているドライバーの種類 (WDF、WDM、NDIS、または Storport) を検出し、ドライバーの種類の既定の規則のセットを選択します。 ドライバーで SDV を初めて実行する場合は、既定の規則セットを実行する必要があります。

    規則の詳細については、「DDI コンプライアンス規則」を参照してください。

  5. 静的分析を開始します。 [メイン] タブをクリックし、[スタート] をクリックします。 [スタート] をクリックすると、静的分析がスケジュールされていること、および分析の実行に時間がかかることを知らせるメッセージが表示されます。 OK をクリックして続行します。 分析は、スケジュールした時刻に開始されます。

結果の表示と分析

静的分析が進むにつれて、SDV は分析の状態を報告します。 分析が完了すると、SDV は結果と統計情報を報告します。 ドライバーが API の使用規則を満たさなければ、結果は欠陥として報告されます。

問題が発生した場合は、警告エラー ページに表示されます。 [ドライバーのプロパティ] ページには、特定のドライバー プロパティのテストの結果が表示されます。 ドライバーのプロパティ テストは、分析をさらに修飾するためにドライバーの機能を識別するために使用されます。 ドライバーのプロパティの結果を使用して、ドライバーの予期されるプロパティとサポートされている機能を確認できます。

静的ドライバー検証ツール レポートで特定の欠陥を表示するには、[結果] ウィンドウの [ディフェクト] をクリックします。 これにより、トレース ビューアーが開き、規則違反のコード パスのトレースが表示されます。 詳細については、「静的ドライバー検証ツールの結果の解釈」を参照してください。

Note

静的ドライバー検証ツールは、分析の結果と設定を保持します。 結果をクリアするには、[クリーン] をクリックします。

静的ドライバー検証ツールの結果のトラブルシューティング

SDV が欠陥が見つからなかったと報告した場合は、[メイン] タブをチェックしてエントリ ポイントが検出されていることを確認します。 ドライバーが関数の役割の種類を使用して関数を宣言しない場合、SDV はドライバー コードの欠陥を分析して見つけることができません。 詳細については、関数の役割タイプ宣言の使用を参照してください。

SDV がタイムアウトを報告するか、有用な結果を返さなかった場合は、いくつかの SDV 構成オプションを変更することが必要になる場合があります。 SDV のトラブルシューティング方法の詳細については、静的ドライバー検証ツールのトラブルシューティングの推奨事項を参照してください。

ドライバーまたはライブラリが静的ドライバー検証ツールでサポートされているかどうかの判定

関数役割型宣言の使用

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

コード分析ツール