ソフトウェア開発ライフサイクル内で Application Verifier を使用する

Microsoft Corporation

February 2006

目次

はじめに
AppVerifier とは
AppVerifier の機能
AppVerifier を使用する状況
AppVerifier の使用方法
AppVerifier のデータを分析する
AppVerifier の重要点
付録 A: ドライバの検証ツール
付録 B: AppVerifier を使用してセキュリティ機能をテストする
付録 C: 関連情報

要約

Microsoft Application Verifier (AppVerifier) は、アンマネージ コードの実行時検証ツールで、通常のアプリケーションのテスト手法では特定が難しい、見過ごしがちなプログラミング エラー、セキュリティ上の問題、およびユーザー アカウントの制限付き特権に関する問題の検出に役立ちます。この記事には英語のページへのリンクも含まれています。

はじめに

プログラマ、ソフトウェア アーキテクト、テスタ、セキュリティ コンサルタントなどが直面する最大の課題の 1 つは、作成したアプリケーションを運用環境に配置したときの結果を把握することです。ソース コードを参照しても、複数のグループがコードに関与していたり外部コンポーネントを使用していたりと、さまざま依存関係が存在するため、実行中に発生するすべての現象を把握するのは困難です。Microsoft AppVerifier は、こうした複雑さや、考えられるバグの副作用の管理を支援する際に重要な役割を果たすことができます。AppVerifier は、通常のアプリケーションのテスト手法では特定が難しい、見過ごしがちなプログラミング エラー、セキュリティ上の問題、およびユーザー アカウントの制限付き特権に関する問題の検出に役立ちます。

この記事では、AppVerifier のしくみと、AppVerifier をソフトウェア開発ライフサイクル内に当てはめる方法についての情報を示します。

AppVerifier とは

AppVerifier は、メモリの破損、重要なセキュリティの脆弱性、およびユーザー アカウントの制限付き特権に関する問題を検出し、それらのデバッグを支援するために特別にデザインされた無償のダウンロードです。AppVerifier は、アプリケーションと Microsoft Windows オペレーティング システムとの相互作用を監視し、アプリケーションで使用されるオブジェクト、レジストリ、ファイル システム、および Win32 API (ヒープ、ハンドル、ロック など) の使用をプロファイルすることによって、セキュリティが保護された信頼できるアプリケーションの作成を支援します。また、AppVerifier には、管理権限のない環境でアプリケーションがどのように実行されるのかを予測するチェック機能も含まれています。

AppVerifier をソフトウェア開発ライフサイクル全体で使用すると、まだ修正が容易でコストのかからないライフサイクルの早期に問題点を特定できるので、開発作業全体のコストを抑えることができます。また、見過ごしがちなエラーを検出することや、管理者権限のない制限された環境で最終的なアプリケーションを実行する際にも役立ちます (この最後の点は、Windows Vista アプリケーションではさらに重要になります)。

AppVerifier で特定される問題

AppVerifier は、以下のことを特定するうえで役立ちます。

  • アプリケーションで API が適切に使用されているかどうか。
    • アンセーフ TerminateThread API。
    • スレッド ローカル記憶域 (TLS) API の適切な使用。
    • VirtualAlloc、MapViewOfFile などの仮想空間操作の適切な使用。
  • アプリケーションに構造化例外処理を使用するアクセス違反が内在しているかどうか。
  • アプリケーションが無効なハンドルの使用を試みているかどうか。
  • メモリの破損またはヒープ内に問題が発生しているかどうか。
  • リソースの少ない状況で、アプリケーションで使用するメモリが不足しているかどうか。
  • クリティカル セクションの使用が適切かどうか。
  • 管理者環境では実行されるアプリケーションが、特権の低い環境で正常に実行されるかどうか。
  • 制限付きユーザーとしてアプリケーションが実行されたときに、問題が発生する可能性があるかどうか。
  • 初期化されていない変数が、スレッドのコンテキストの以降の関数呼び出しに含まれるかどうか。

AppVerifier の機能

AppVerifier は 2001 年に作成され、ログオン プロセス中に使用されます。ただし、Download Center にリリースされている Version 3.0 は、一部変更が行われています。ユーザー インターフェイスが変更され、セキュリティに重点が置かれるようになり、より堅牢なレポート処理 (XML ベースのログ) を提供する最新のアーキテクチャを使用しています。また、新しいテスト (LuaPriv など) を柔軟に追加できるようになりました。

AppVerifier のテスト

AppVerifier は、"検証層" と呼ばれるテストのセットで構成されます。これらのテストは、テストするアプリケーションごとに有効または無効にできます。テスト領域内で検証層を展開すると、特定のテストが表示されます。アプリケーションのテストを有効にするには、そのテストの隣にあるチェック ボックスをオンにします。検証層全体を有効にするには、[Basics] など、最上部にあるチェック ボックスをオンにします。

AppVerifier (Version 3.0.28) で実行できるテストは、以下の 4 種類です。

  1. 基本テスト (Basics) は、以下のテストで構成されます。
    • 例外 (Exceptions): アプリケーションに構造化例外処理を使用するアクセス違反が内在していないことを確認します。
    • ハンドル (Handles): アプリケーションが、無効なハンドルの使用を試みていないことを確認します。
    • ヒープ (Heaps): メモリ破損の問題についてヒープ内をチェックします。
    • ロック (Locks): クリティカル セクションが適切に使用されていることを確認します。
    • メモリ (Memory): 仮想空間を操作する API が適切に使用されていることを確認します。
    • TLS: スレッド ローカル記憶域 API が適切に使用されていることを確認します。
  2. 低リソース シミュレーション (Low resource simulation) は、リソースの少ない環境のシミュレーションを試みます。ここでは、以下のような、エラーが発生する可能性のある呼び出しを示す 0 ~ 100 までの数値を定義できます。
    • Wait (WaitForXXXX API など)。
    • Heap_Alloc (ヒープ割り当て API)。
    • Virtual_Alloc (仮想メモリ割り当て API)。
    • Registry (レジストリ API)。
    • File (CreateFile などのファイル API)。
    • Event (CreateEvent などのイベント API)。
    • MapView (CreateMapView などの MapView API)。
    • Ole_Alloc (SysAllocString などの Ole API)。
  3. LuaPriv には、以下の 2 種類のシナリオで使用できる 31 種類のテストが含まれています。
    • 予測: 管理者特権を使用して実行しているアプリケーションを、低い特権 (一般的には、通常のユーザー) を使用して実行した場合に動作するかどうかを判断します。たとえば、アプリケーションが管理者のみにアクセスを許可しているファイルに書き込みを行う場合、管理者以外のユーザーでそのアプリケーションを実行すると、そのファイルに書き込むことができません。
    • 診断: 管理者以外のユーザーで実行するときに、現在の実行処理に既に存在すると考えられる問題を特定します。たとえば、アプリケーションが管理者のみにアクセスを許可するファイルに書き込みを行う場合、そのアプリケーションでは ACCESS_DENIED エラーが発生します。
  4. その他 (Miscellaneous) は、以下のテストで構成されます。
    • 危険な API (Dangerous APIs): アプリケーションが以下の安全ではない操作を使用しているかどうかを追跡します。
      • TerminateThread への危険な呼び出し。
      • メモリの少ない状況で発生すると考えられるスタックのオーバーフロー。
      • 複数スレッド実行中の終了プロセスの呼び出し。
      • DllMain での LoadLibrary の呼び出し。
      • DllMain での FreeLibrary の呼び出し。
      • ダーティ スタック (Dirty Stacks) は、スタック内の未使用領域を (定期的に) あるメモリ パターンで埋めます。これは、スレッドのコンテキストでそれ以降行われる関数呼び出しに含まれる初期化されていない変数を検出するうえで役立ちます。

プロパティ

AppVerifier には、2 つのプロパティ セットがあります。1 つはテストに基づいており、もう 1 つはアプリケーションに基づいています。各プロパティは、以下の項目で定義されます。

  • 名前: プロパティごとの一意名。
  • データ型: Boolean、DWORD、String、MultipleString。
  • 値: 型によって異なる、変更可能な要素。
  • 説明: そのプロパティの説明。

アプリケーションごとのプロパティを編集する

アプリケーションごとに、以下のプロパティを編集できます。

  • Propagate: AppVerifier の設定を親プロセスから子プロセスへ反映します。設定は、False (チェック ボックスがオフ) の場合には反映されませんが、True (チェック ボックスがオン) の場合には反映されます。
  • AutoClr: 指定したイメージの実行が開始されると、検証済みイメージの設定が消去されます。この処理は、False (チェック ボックスがオフ) の場合には行われませんが、Ture (チェック ボックスがオン) 場合には行われます。
  • AutoDisableStop: AppVerifier からエラーについての情報が 1 回だけ示されます。その問題が再度検出されても、エラーは生成されません。False を設定すると、問題が検出されるたびにエラーが生成されます。True に設定すると、エラーが 1 回だけ生成されます。
  • LoggingWithLocksHeld: dll のロード/アンロード イベントがログに記録されます。AppVerifier は、ローダーロックが保持されているときに I/O 処理を行います。これにより、アプリケーションが応答を停止することがあります。False に設定すると、イベントがログに記録されません。True に設定すると、イベントがログに記録されます。

テストごとのプロパティを編集する

特定のテストで使用するプロパティの詳細については、AppVerifier に付属するヘルプを参照してください。プロパティを編集するには、以下の 2 つの方法のいずれかを使用できます。

  • 個別: プロパティ ウィンドウで、編集するプロパティをダブルクリックします。この操作により、アイテムを編集できるダイアログ ボックスが表示されます。このダイアログ ボックスを使用して、既定の設定に戻すこともできます。エントリを変更して [OK] をクリックします。
  • グループ: [Tests] 領域で、編集する必要があるテストまたは検証層のチェック ボックスをオンにします。右クリックを使用すると、すべてのプロパティを表示する画面が表示されます。プロパティを変更するか、既定の設定に戻し、[OK] をクリックします。

ログ

ログは、アプリケーションが実行され、エラーが生成されたときに作成されます。ログは XML 形式なので、ブラウザ、XML、または XLST を使用して表示できます。

AppVerifier を使用する状況

AppVerifier は、ソフトウェア開発ライフサイクル (SDL、セキュリティ開発ライフサイクルとも呼びます) 全体で使用する必要があります。

  • 要求定義フェーズ: AppVerifier の使用を計画し、AppVerifier の実行と検証のスケジュールを作成します。
  • デザイン フェーズ: テストするコンポーネント (モジュール、Dll、EXE) を定義します。
  • 実装フェーズ: 開発中のさまざまなコンポーネントの安定したビルド (Alpha ~ RTM) 上で AppVerifier を実行します (コンポーネントを個別に、また結合してテストすることは重要です)。
  • 検証フェーズ: アプリケーションを限界値に近づけ、予期しない動作や予期しないデータを実行する最初の機会となるので、テスタはすべてのテスト (手動および自動) を AppVerifier を使用して実行する必要があります。また、AppVerifier は、実際の (またはその可能性のある) 攻撃を受けやすいベクタを迅速に列挙できるので、監査 (ブラック ボックスおよびホワイト ボックス) を行うセキュリティ コンサルタントにとっても強力なツールです。
  • リリース フェーズ: クライアントやセキュリティ コンサルタントは、リリースされたバイナリで AppVerifier を使用して、可能性のあるセキュリティ上の脆弱性を特定できます。
  • サポートとサービス フェーズ: AppVerifier を使用して、コード変更 (バグの修正など) によって問題点が再現しないことを確認します。

AppVerifier の使用方法

インストールと構成

  1. インストール: 最新バージョンの AppVerifier を Microsoft Download Center (英語) からダウンロードします。このサイトには、サポートするアーキテクチャ x86、ia64、amd64 ごとにそれぞれセットアップ バイナリがあります。

  2. デバッガのセットアップ: エラーが発生するとデバッガへの割り込みが行われるため、検証するアプリケーションをユーザーモード デバッガまたはシステムをカーネル デバッガの管理下で実行する必要があります。デバッガの詳細については、ヘルプを参照してください。

  3. 設定: AppVerifier は、実行中のプロセスに対しては有効にできません。以下で説明する設定を行ってからアプリケーションを開始する必要があります。この設定は、明示的に削除されるまで保持されます。アプリケーションを何度も開始しても、設定が削除されるまで、そのアプリケーションは AppVerifier と共に起動されます。

    注: AppVerifier は、Visual Studio 2005 Tram System 内でも使用できます。

AppVerifier 基本テストを使用する

以下のシナリオでは、コマンド ラインとユーザー インターフェイスの推奨オプションを紹介しています。コードを実行するすべてのテストでこれらのシナリオを実行して、すべての範囲を確認する必要があります。これらのシナリオでは、アプリケーションがデバッガに "割り込み" を行わず、AppVerifier を有効にせずに実行した場合と同じ率ですべてのテストに合格することを期待しています。

  1. 以下の設定を使用して、目的のアプリケーションの検証を可能にします。

    コマンド ラインの場合: appverif /verify MyApp.exe
    ユーザー インターフェイスの場合:
    a. [Applications] ボックス内で右クリックし、[Add Application] をクリックして、アプリケーションを追加します。
    b. [Tests] ボックスの [Basics] チェック ボックスをオンにします。
    c. [Save] をクリックします。

    • 注:
      • "/verify" を使用すると、基本テストが有効になります。
      • DLL アプリケーションをテストする場合は、その DLL をテスト実行する test.exe に対して AppVerifier を有効にする必要があります。
      • 検証層は個別に実行します。たとえば、あるセッションでは、すべての基本チェックを有効にし、別のセッションではすべての LuaPriv チェックを有効にします。
    1. アプリケーションを起動するすべてのテストを実行します。
    2. デバッガが中断された場合は、それを分析します。中断が発生した場合、中断が発生した原因を把握し、解決する必要があります (ヘルプには、中断とその調査方法について詳しく記載されています)。
    3. 完了したら、以下のようにして、すべての設定を削除します。

    コマンド ラインの場合: appverif /n MyApp.exe
    ユーザー インターフェイスの場合:
    a. [Applications] ボックス内で右クリックし、[Delete Application] をクリックしてアプリケーションを削除します。
    b. [Save] をクリックします。

AppVerifier の低リソース シミュレーション (フォールト インジェクション) を使用する

このシナリオでは、アプリケーションがデバッガに割り込みを行わないことを期待します。これは、対処の必要なエラーが発生しないことを意味します。

フォールト インジェクションが通常の操作にランダムに挿入されるので、このテストに合格する率は著しく低くなる場合があります。

  1. 以下のようにして、AppVerifier の低リソース シミュレーション (フォールト インジェクション) をアプリケーションに対して有効にします。

    コマンド ラインの場合: Appverif /verify MyApp.exe /faults
    ユーザー インターフェイスの場合:
    a. [Applications] ボックス内を右クリックし、[Add Application] をクリックして、アプリケーションを追加します。
    b. [Tests] ボックスの一覧の [Low Resource Simulation] をオンにします。
    c. [Save] をクリックします。

    注: DLL をテストする場合は、プロセス全体ではなく、特定の DLL に低リソース シミュレーション (フォールト インジェクション) を適用できます。この場合、コマンド ライン形式は次のようになります。

    appverif /verify TARGET [/faults [PROBABILITY [TIMEOUT [DLL ...]]]]
    例: appverif /verify mytest.exe /faults 5 1000 d3d9.dll

  2. アプリケーションをテスト実行するすべてのテストを実行します。

  3. 完了したら、すべての設定を削除します。デバッガが中断された場合は、それを分析します。中断が発生した場合、発生した原因を把握し、解決する必要があります。

  4. 完了したら、以下のようにして、すべての設定を削除します。

    コマンド ラインの場合: appverif /n MyApp.exe
    ユーザー インターフェイスの場合:
    a. [Applications] ボックス内で右クリックし、[Delete Application] をクリックしてアプリケーションを削除します。
    b. [Save] をクリックします。

    注: フォールト インジェクションを使用した場合と使用しない場合とでは、アプリケーション内で実行されるコード パスが大きく異なるので、AppVerifier の利点を最大限に活用するためには両方のシナリオを実行する必要があります。

AppVerifier のデータを分析する

アプリケーションの分析中に作成されたデータは、すべて %ALLUSERSPROFILE%\AppVerifierLogs フォルダにバイナリ形式で保存されます。これらのログは、後でユーザー インターフェイスまたはコマンド ラインを使用して XML に変換して、詳しく分析できます。XML ファイルを表示するには、以下のいずれかの方法を使用します。

  • Web ブラウザ: 現在のすべての Web ブラウザは、構造化された色付きの形式で XML ファイルを表示できます。
  • XSL 変換: 未加工の XML コンテンツを、関連情報のみを含むレポートに変換する XSLT を作成します。
  • Excel へのインポート: XML ファイルを Excel にインポートし、フィルタまたはピボット テーブルを使用して、収集したデータを再編成および分析します。
  • データベースへのインポート: XML ファイルを保存し、SQL、Access などのデータベースにインポートします。

AppVerifier の重要点

ここでは、AppVerifier の使用を考えているユーザーの最も一般的な疑問点に関する情報を示します。

システム要件

AppVerifier は、Windows XP、Windows Server 2003、および Windows Vista 上のアンマネージ アプリケーション (.NET Framework アプリケーション以外のアプリケーション) をテストするようにデザインされています。完全ページ ヒープを実行している間は、ページ ヒープを少なくとも 1 GB にすることをお勧めします。

AppVerifier では、ソース コードにアクセスしなくてもテストを実行できますが、アプリケーションのシンボルまたはデバッグ情報のいずれかを使用できると、収集されたデータの品質や有用性に大きな違いが生じます。

AppVerifier の検証対象

AppVerifier は、Windows XP、Windows Server 2003、および Windows Vista のユーザーモードのアプリケーションをテストするために使用します。

  • ドライバ モジュールまたはカーネル モジュールをテストするには、ドライバの検証ツールを活用します。詳細については、「付録 A: ドライバの検証ツール」とサポート技術情報の記事「Driver Verifier を使用して Windows ドライバをトラブルシューティングする方法」を参照してください。
  • Windows CE をテストするには、Windows CE Test Kit (CETK) に付属の特定の Platform AppVerifier を使用します。
  • AppVerifier でテストされるのは、テストの実行中に呼び出される関数のみであることに注意してください。つまり、(対象のアプリケーションまたはモジュールから) 単体テストを行える場合は、各単体テストがコードの最大範囲を対象にしていることを確認する必要があります。エラーは、要求を生成するメソッドが起動された場合にのみ検出されます。

AppVerifier のしくみ

AppVerifier はアンマネージ DLL のメソッド テーブルを変更して、実際の関数が実行される前に必要なチェックが実行されるようにします (これは、"関数フック" とも呼ばれます)。たとえば、Win32 API CreateFileA のアドレスは、正の数がログに記録されたときに一連のテストを起動する、AppVerifier の内部メソッドに置き換えられます。

AppVerifier のメソッド テーブル フック技法の使用は、新しいプロセスが開始されると、特定のレジストリ キー内に作成されたエントリによって制御されます。そのレジストリ エントリが存在すると、新しく作成されたプロセスに AppVerifier DLL が読み込まれます。そのプロセスでは、既存の DLL とその後読み込まれる DLL のメソッド テーブルの置き換えが行われます。これらのフックは、DLL が読み込まれるときに作成されるので、既に実行中のプロセスでは AppVerifier 3.0 を使用することはできません。

AppVerifier のユーザー インターフェイス (UI) は、レジストリ キーの設定を制御し、既存のログについての情報を提供するために使用します。この UI でアプリケーションおよびテストを設定し、[Save] をクリックすると、レジストリが設定されます。その後、アプリケーションを再開する必要があります。これにより、監視が開始されます。この設定は、アプリケーションが AppVerifier から削除されるまで保持されることに注意してください。

問題が特定されると、検証が停止されます。提供される数字を使用して、問題の正確な性質と、発生した理由を特定します。検証の停止に関する詳細については、AppVerifier のヘルプ ファイル appverif.chm に含まれている詳細な説明を参照してください。

ページ ヒープの技術詳細

AppVerifier は、ヒープの破損 (オーバーフローまたはアンダーフロー) を検出するために、要求されたメモリにすべて書き込みできないページを埋め込むか、割り当て済みメモリの前後に特殊なタグを埋め込むことによって、メモリの割り当て方法を変更します。

要求されたメモリにすべて書き込みできないページを埋め込むと (Full 設定は、[Heaps] の [Properties] セクションで有効にします。Full は既定の設定です)、AppVerifier が大量の仮想メモリを使用することになりますが、この方法には、オーバーフローまたはアンダーフローが発生したときに、ヒープの破損イベントがリアルタイムにキャッシュされる利点があります。このモードでのメモリは、[AppVerifier Read-Only Heap Page (4k)] [Amount of memory requested by Application under test] または [Amount of memory requested by Application under test] [AppVerifier Read-Only Heap Page (4k)] のようになります。

ヒープ チェックでは、Backward プロパティの値によって、割り当ての先頭または末尾にガード ページが配置されます。Backward が既定値の False に設定されていると、ガード ページが割り当ての末尾に配置され、バッファ オーバーランがキャッチされます。True に設定されている場合は、ガード ページが割り当ての先頭に配置されて、バッファ アンダーランがキャッチされます。

要求されたメモリに特殊なタグで埋め込む場合 (ヒープ プロパティの [Full] チェック ボックスをオフにすると有効になります)、そのメモリが解放されるときに、AppVerifier によってチェックおよび警告が行われます。この方法を使用する場合の主な問題として、メモリが解放される (メモリ ブロックの最小値は 8 バイト) ときにしかメモリの破損が検出されないので、3 バイトの変数や 5 バイトのオーバーフローが発生した場合は、即座に検出されないことがあります。

アンダーフロー イベントでは、読み取り専用ページへの書き込み試行が行われます。この試行により、例外が発生します。この例外は、対象のアプリケーションがデバッガの管理下で実行されている場合にのみキャッチできます。完全ページ ヒープ モードでは、埋め込みおよびガード ページを使用するので、これらのエラーも検出されます。このことから、コンピュータが完全ページ ヒープのメモリ制約の厳しさに耐えられない場合は、簡易ページ ヒープを使用することになります。

メモリを集中的に使用するアプリケーションの場合、または、 AppVerifier を長期間使用する必要がある場合 (負荷テストなど)、パフォーマンスが低下するので、完全モードではなく通常の (簡易) ヒープ テストを行う方が適切です。ただし、問題が発生した場合は、完全ページ ヒープを有効にして詳しく調べます。

付録 A: ドライバの検証ツール

ドライバの検証ツールは、ドライバの実行中にドライバ (カーネル モード ソフトウェア) で発生したエラーを検出するためのツールです。通常見つかるのは、(バッファ オーバーランなどの) プールの破損、信頼できないデータの不適切な検証、不適切なカーネル モード操作などです。ドライバの検証ツールでは問題が検出されるたびに、システムがクラッシュする過程が管理される (bugcheck) ので、カーネル デバッガがその問題を把握する必要があります。ドライバの検証ツールはオペレーティング システム コンポーネントで、Windows 2000 以降で使用できます。

ドライバの検証ツールの使用シナリオ

  1. インストール: ドライバの検証ツールの設定は、どの Windows システムにも既定でインストールされるシステム ツール verifier.exe を使用して行います。このツールのユーザー インターフェイスを実行するには、コマンド ウィンドウを開いて「verifier.exe」と入力するか、windows\system32 に移動して verifier.exe を実行します。
  2. 設定: 以下に説明する設定を行い、ドライバの検証ツールを有効にしてテストを開始するには、システムを再起動する必要があります。この設定は、明示的に削除されるまで保持されます。

ドライバの検証ツールを使用する

以下のシナリオでは、コマンド ラインとユーザー インターフェイスの推奨オプションを紹介しています。コードを実行するすべてのテストでこれらのシナリオを実行して、すべての範囲を確認する必要があります。これらのシナリオでは、ドライバによってシステム クラッシュが発生することはなく、すべてのテストがドライバの検証ツールを有効にしていない場合と同じ率で合格することを期待します。

  1. 以下のようにして、テストするドライバに対して標準設定を有効にし、再起動します。

    コマンド ラインの場合: verifier /flags 0x1FB /driver MyDriver.sys
    ユーザー インターフェイスの場合:
    a. 最初の画面で [標準の設定を作成する] をクリックします。
    b.[次へ] をクリックします。

    c. [一覧からドライバを選択する] をクリックします。

    d. テストするドライバを選択し、[完了] をクリックします。

  2. ドライバをテスト実行するすべてのテストを実行します。

  3. 発生したシステム クラッシュを分析します。どのようなシステム クラッシュも、検証によって見つかったバグなので、これらを把握し、解決する必要があります。

ドライバの検証ツールの低リソース シミュレーション (フォールト インジェクション) を使用する

これらのシナリオでは、ドライバの検証ツールを有効にした場合に、ドライバによるシステム クラッシュが "発生しない" ことを期待します。システムにランダムにフォールトが挿入されるため、このテストが合格する率は、著しく低くなる場合があります。

  1. 以下のようにして、低リソース シミュレーション (フォールト インジェクション) を有効にし、再起動します。

    コマンド ラインの場合: verifier /volatile /flags 7
    ユーザー インターフェイスの場合:
    a. 最初の画面で [カスタム設定を作成する (コード開発者用)] をクリックし、[次へ] をクリックします。

    b. [低リソースのシミュレーション] をオンにし、[次へ] をクリックします。

    c. 前回のシナリオと同じドライバを選択していること確認し、再起動します。

  2. ドライバをテスト実行するすべてのテストを再度実行します。

  3. 発生したシステム クラッシュを分析します。

  4. 以下のようにして、低リソース シミュレーション (フォールト インジェクション) を無効にし、再起動します。

    コマンド ラインの場合: "verifier /reset" を実行すると、すべての設定が削除されます。"verifier /volatile /flags 3" を実行すると、フォールト インジェクションだけが無効になります。
    ユーザー インターフェイスの場合:
    a. [既存の設定を削除する] をクリックし、[完了] をクリックします。

    b. 再起動します。

検証ツールによるシステム クラッシュのデバッグを開始するには、デバッガ コマンド "!analyze" を実行します。 詳細については、DDK/LDK (Driver Development Kit) のヘルプを参照してください。

注: フォールト インジェクションを使用した場合と使用しない場合とでは、ドライバ内で実行されるコード パスが大きく異なるので、ドライバの検証ツールの利点を最大限に活用するためには両方のシナリオを実行する必要があります。

付録 B: AppVerifier を使用してセキュリティ機能をテストする

以下は、Lauren Lavoie よって執筆されました。

要約: AppVerifier ツールを使用して、プロジェクト コード内の一般的なセキュリティ問題を特定する方法について説明します。

コード レビューを行い脅威モデルを分析した結果、テストするアプリケーションに含まれているセキュリティ バグの検出に役立つ優れた静的テスト ツールを提供できるようになりました。AppVerifier を使用すると、通常のテスト スイートをアプリケーション上で実行しながら、バックグラウンドで動的にテストを実行できます。AppVerifier は、Windows shim エンジンを使用してアプリケーション プログラミング インターフェイス (API) 呼び出しをフックすることにより、アプリケーションの動作を監視します。

最初の AppVerifier は、アプリケーションがクラッシュする原因となる動作を検出しました。ツールへのその後の機能追加により、Windows との互換性、共通 API の適切な使用に対するチェック、セキュリティ関連の必須機能など、より検出の難しい実行時の動作を確認できるようになりました。

開発者は、セキュリティ属性を不適切に設定したり、共通 API 関数を不適切に使用したりすることによって、トロイの木馬の攻撃を受けやすいコードを無意識に記述してしまうことがあります。AppVerifier は、不要なコードを実行する可能性のある状況をキャッチし、ログに記録するので、開発者は作成するコードのセキュリティをさらに高めることができます。

DACL の適切な使用をチェックする

開発者が、コードを攻撃を受けやすくしてしまう最も一般的な原因は、随意アクセス制御リスト (DACL) の不適切な使用です。DACL では、特定のリソースにアクセスできるグループと、そのグループが持つアクセス許可の種類を指定します。リソースを作成またはリソースにアクセスする多数の API が、DACL をパラメータの 1 つとして受け取ります。AppVerifier により、以下が操作が行われます。

  • これらの API 呼び出しをインターセプトし、DACL パラメータが妥当であることをチェックします。これは、リソースへのアクセス許可のセキュリティが確保されていることを確認する、最も簡単かつ効果的な方法の 1 つです。
  • NULL DACL または不要なアクセス許可をすべてのユーザーに与える DACL (すべてのユーザーがアクセス許可を変更できたり、リソースを削除できたりすることなど) が検出されるたびにログにエラーを記録します。また、AppVerifier では、管理者ではないユーザーがアクセス許可を変更できたり、リソースの所有者になったりすることを不適切と見なします。
  • ファイルが開かれるたびに (他のプロセスによって作成されたファイルは、作成時点では上記の AppVerifier のチェック対象にならない可能性があるためです)、または移動されるたびに (ファイルのセキュリティ属性が移動時にコピーされないためです) チェックを行います。

CreateProcess の適切な使用をチェックする

CreateProcess API 関数への呼び出しは、パラメータが適切に指定されていないと攻撃の対象になります。AppVerifier は、CreateProcess (またはその他の API 関数) が NULL lpApplicationName パラメータおよび空白を含んだ lpCommandLine パラメータを使用して呼び出された場合エラーを生成します。たとえば、以下のようなコマンド ライン パラメータを使用することはできません。

c:\program files\sample.exe -t -g c:\program files\sample\test

上記のコマンド ラインを使用すると、悪意あるユーザーが C:\Program にプログラムをインストールした場合に、誤って不要なコードがアプリケーションによって実行される可能性があります。

ソケット API を安全に使用するようにする

AppVerifier は、ソケット関数を使用するアプリケーションで SO_EXCLUSIVEADDRUSE フラグが使用されていることをチェックします。このようにすると、SO_REUSEADDR を使用している望ましくないホストによるポートへのバインドを防ぎ、ホストが乗っ取られる事態を回避できます。

AppVerifier を入手し使用する

AppVerifier を使用するために、新たなテストをテスト スイートに追加する必要はまったくありません。AppVerifier は、アプリケーションのすべてのアクティビティを休みなく、停止するまで監視するように Windows を構成します。AppVerifier によるテストとエラーの報告方法の詳細については、AppVerifier のヘルプを参照してください。AppVerifier の最新バージョンは Microsoft Download Center (英語) から入手できます。

付録 C: 関連情報

AppVerifier の場所

標準バージョンの Application Verifier は、Microsoft Download Center (英語) から無償でダウンロードできます。また、Visual Studio 2005 Team Edition に統合されたバージョンの Application Verifier もあります。

AppVerifier に関する記事

Application Verifier ツールに付属のヘルプ (appverif.chm ファイル)

Michael Howard 著 「Analyzing Your Applications with Windows Application Verifier」 2003 年 12 月 3 日 (AppVerifier v2.5) (英語)

Windows XP の展開 - アプリケーションの互換性について」 2005 年 11 月 (AppVerifier v3.0)

Windows Application Verifier についてよく寄せられる質問」 (AppVerifier v3.0 )

Testing Applications with AppVerifier」 (AppVerifier v3.0) (英語)

Visual Studio 2005 の新しいセキュリティ機能」 (英語) 、Visual Studio Team System に統合されている、基本的なチェック (ヒープ、ハンドル、およびロック) のサブセットついての情報です。

セキュリティ開発ライフサイクルに関する記事

Improving Security Across the Software Development Lifecycle」 (英語)

Software Development Life Cycle (SDLC)」 (英語)

信頼できるコンピューティングのセキュリティ開発ライフサイクル

関数フックと修正プログラムに関する資料

Detours (英語)

The Code Project より

API hooking revealed」 (英語)

Process-wide API spying - an ultimate hack」 (英語)