!chkimg

!chkimg 拡張機能は、実行可能ファイルのイメージを、シンボルストアやその他のファイルリポジトリ上のコピーと比較して、破損を検出します。

!chkimg [Options] [-mmw LogFile LogOptions] [Module]

パラメーター

オプション 次のオプションの任意の組み合わせ:

-p **** SearchPath
シンボル サーバーにアクセスする前に、SearchPathでファイルを再帰的に検索します。

-f
イメージ内のエラーを修正します。 シンボル ストア上のファイルとメモリ内のイメージの違いがスキャンによって検出されるたびに、シンボル ストア上のファイルの内容がイメージ上にコピーされます。 ライブ デバッグを実行している場合は、!chkimg -f 拡張子を実行する前にダンプ ファイルを作成できます。

-nar
シンボル サーバー上のファイルのマップされたイメージが移動されないようにします。 デフォルトでは、ファイルのコピーがシンボル サーバー上に配置され、メモリにマップされると、!chkimg はファイルのイメージをシンボル サーバー上に移動します。 ただし、-narオプションを使用する場合、サーバーからのファイルのイメージは移動されません。

デバッガーは読み込んだイメージを常に再配置するため、既にメモリ内にある実行可能イメージ (つまり、スキャン対象の実行可能イメージ) が移動されます。

このスイッチは、オペレーティング システムによって元のイメージが既に移動されている場合にのみ役立ちます。 イメージが移動されていない場合は、!chkimg とデバッガがイメージを移動します。 このスイッチの使用はまれです。

-ss **** SectionName
スキャンを、名前に文字列SectionName が含まれるセクションに制限します。 スキャンには、名前にこの文字列が含まれるカード不可能なセクションが含まれます。 SectionName は大文字と小文字が区別され、8 文字を超えることはできません。

-as
スキャンには、使い捨てセクションを除く画像のすべてのセクションが含まれます。 既定では (-as または -ss を使用しない場合)、スキャンでは、書き込み可能なセクション、実行可能でないセクション、名前に "PAGE" が含まれるセクション、およびカード可能なセクションがスキップされます。

-r **** StartAddress **** EndAddress
スキャンを、StartAddress で始まり EndAddress で終わるメモリ範囲に制限します。 この範囲内では、通常スキャンされるすべてのセクションがスキャンされます。 セクションがこの範囲と部分的に重複している場合、この範囲と重複するセクションのその部分のみがスキャンされます。 -as スイッチまたは -ss スイッチも使用している場合でも、スキャンはこの範囲に制限されます。

-nospec
スキャンにHal.dllとNtoskrnl.exeの予約済みセクションが含まれるようします。 既定では、!chkimg はこれらのファイルの特定の部分をチェックしません。

-noplock
0x90のバイト値 (nop 命令) と 0xF0 (ロック命令) のバイト値を持つことによって、不一致の領域を表示します。 既定では、これらの不一致は表示されません。

-np
修正プログラムが適用された命令が認識されるようにします。

-d
スキャンの実行中に、一致しないすべての領域の概要が表示されます。 インデックス付きビューの詳細については、「解説」を参照してください。

-db
db デバッガー コマンドに似た形式で不一致領域を表示します。 したがって、各表示行には、行内の最初のバイトのアドレスが表示され、最大で16個の16進バイト値が続きます。 バイト値の直後に、対応する ASCII 値が続きます。 復帰や改行など、印刷できない文字はすべてピリオド (.) として表示されます。 一致しないバイトはアスタリスク (*) でマークされます。

-ロラ **** インズ
-d または -db が表示する出力行の数を行数に制限します。

-v
詳細モードの情報が表示されます。

-mmw
ログ ファイルを作成し、!chkimg のアクティビティをこのファイルに記録します。 ログ ファイルの各行は、1 つの不一致を表します。

LogFile
フォーマット ファイルの完全パスを指定します。 相対パスを指定した場合、パスは現在のパスを基準にした相対パスになります。

LogOptions
ログ ファイルの場所を指定します。 LogOptions は、さまざまな文字を連結した文字列です。 ログ ファイルの各行には、コンマで区切られた複数の列が含まれています。 これらの列には、LogOptions 文字列に文字が表示される順序で、次のオプション文字が 指定する項目が 含まれます。 次のオプションを複数回含めることができます。 少なくとも 1 つのオプションを含める必要があります。

ログオプション ログファイルに含まれる情報

v

不一致の仮想アドレス

r

モジュール内の不一致のオフセット (相対アドレス)

s

不一致のアドレスに対応するシンボル

S

不一致を含むセクションの名前

e

不一致の場所で予想されていた正しい値

w

不一致の場所にあった正しくない値

LogOptions には、次の追加オプションの一部を含めることも、まったく含めないこともできます。

ログオプション 効果

o

LogFile という名前のファイルが既に存在する場合は、既存のファイルが上書きされます。 既定では、デバッガーは既存のファイルの末尾に新しい情報を追加します。

tString

ログ ファイルに追加の列を追加します。 この列の各エントリにはStringが含まれます。 tString オプションは、既存のログ ファイルに新しい情報を追加し、新しいレコードを古いレコードと区別する必要がある場合に便利です。 tString の間にスペースを追加することはできません。 tIString オプションを使用する場合、String には次のスペースの前に存在するすべての文字が含まれるとみなされるため、これを LogOptions の最後のオプションにする必要があります。

たとえば、LogOptionsrSewo の場合、ログ ファイルの各行には、不一致の場所の相対アドレスとセクション名、およびその場所での予期される値と実際の値が含まれます。 このオプションにより、以前のファイルも上書きされます。 オプションが異なる複数の ログ ファイルを作成する場合は、-mmw スイッチを複数回使用できます。 同時に最大 10 個のログ ファイルを作成できます。

モジュール
チェックするモジュールを指定します。 Module には、モジュールの名前、モジュールの開始アドレス、またはモジュールに含まれる任意のアドレスを指定できます。 Module を省略すると、デバッガーは現在の命令ポインターを含むモジュールを使用します。

DLL

Windows XP以降

拡張dll

解説

!chkimg を使用すると、メモリ内の実行可能ファイルのイメージとシンボル ストアに存在するファイルのコピーが比較されます。

ファイルのすべてのセクションが比較されます。ただし、無効なセクションカード、書き込み可能なセクション、実行可能でないセクション、名前に "PAGE" があるセクション、または INITKDBG からのセクションを除きます。 この動作は、-ss-as、または -r スイッチを使用して変更できます。

!chkimg は、次の例外を除いて、イメージとファイルの不一致をイメージ エラーとして表示します。

  • インポート アドレス テーブル (IAT) によって占有されているアドレスはチェックされません。

  • Hal.dllおよびNtoskrnl.exeの特定のアドレスは、これらのセクションが読み込まれるときに特定の変更が発生するため、チェックされません。 これらのアドレスをチェックするには、-nospec オプションを含めます。

  • 0x90バイト値がファイル内に存在し、0xF0値がイメージの対応するバイトに存在する場合 (またはその逆)、この状況は一致と見なされます。 通常、シンボル サーバーは、ユニプロセッサとマルチプロセッサの両方のバージョンに存在するバイナリの 1 つのバージョンを保持します。 x86 ベースのプロセッサでは、lock命令は 0xF0 であり、この命令はユニプロセッサ バージョンの nop (0x90) 命令に対応します。 !chkimg でこのペアを不一致として表示したい場合は、-noplock オプションを設定します。

-f オプションを使用してイメージの不一致を修正すると、!chkimg はエラーとみなした不一致のみを修正します。 たとえば、!chkimg は、-noplock を含めない限り、0x90 バイトを 0xF0 バイトに変更しません。

-d オプションを含めると、!chkimg はスキャンの実行中にすべての不一致領域の概要を表示します。 各不一致は 2 行に表示されます。 最初の行には、範囲の開始、範囲の末尾、範囲のサイズ、範囲の先頭に対応するシンボル名とオフセット、最後のエラー以降のバイト数 (かっこ内) が含まれます。 2 行目は角かっこで囲まれており、予想されていた 16 進数のバイト値、コロン、イメージで実際に検出された 16 進数のバイト値が含まれます。 範囲が 8 バイトより長い場合は、コロンの前とコロンの後に最初の 8 バイトのみが表示されます。 次の例は、この状況を示しています。

be000015-be000016  2 bytes - win32k!VeryUsefulFunction+15 (0x8)
     [ 85 dd:95 23 ]

場合によっては、ドライバーは、フック、リダイレクト、またはその他の方法を使用して、Microsoft Windows カーネルの一部を変更します。 スタック上になくなったドライバーであっても、カーネルの一部が変更されている可能性があります。 !chkimg 拡張子をファイル比較ツールとして使用すると、Windows カーネル (またはその他のイメージ) のどの部分がドライバーによって変更されているか、またその部分がどのように変更されているかを正確に判断できます。 この比較は、完全ダンプ ファイルで最も効果的です。

読み込まれた各モジュールの確認

!chkimg !for_each_module 拡張機能と併用して、ロードされた各モジュールのイメージを確認することもできます。 次の例は、この状況を示しています。

!for_each_module !chkimg @#ModuleName 

!analyze例

たとえば、バグ チェックが発生し、!analyze を使用して開始するとします。

kd> !analyze 
....
BugCheck 1000008E, {c0000005, bf920e48, baf75b38, 0}
Probably caused by : memory_corruption
CHKIMG_EXTENSION: !chkimg !win32k
....

この例では、!analyze 出力はメモリ破損が発生したことを示唆しており、Win32k.sys が破損したモジュールである可能性を示唆する CHKIMG_EXTENSION 行が含まれています。 (この行が存在しない場合でも、スタックの最上部にあるモジュールが破損している可能性があると考えられます。)次の例に示すように、まずスイッチを付けずに !chkimg を使用します。

kd> !chkimg win32k
Number of different bytes for win32k: 31

次の例は、実際にメモリの破損があることを示しています。 Win32k モジュールのすべてのエラーを表示するには、!chkimg -d を使用します。

kd> !chkimg win32k -d
    bf920e40-bf920e46  7 bytes - win32k!HFDBASIS32::vSteadyState+1f
        [ 78 08 d3 78 0c c2 04:00 00 00 00 00 01 00 ]
    bf920e48-bf920e5f  24 bytes - win32k!HFDBASIS32::vHalveStepSize (+0x08)
        [ 8b 51 0c 8b 41 08 56 8b:00 00 00 00 00 00 00 00 ]
Number of different bytes for win32k: 31

一覧表示されている 2 番目のセクションの破損したイメージを逆アセンブルしようとすると、次の出力が発生する可能性があります。

kd> u  win32k!HFDBASIS32::vHalveStepSize
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 0000             add     [eax],al
bf920e4a 0000             add     [eax],al
bf920e4c 0000             add     [eax],al
bf920e4e 0000             add     [eax],al
bf920e50 7808            js win32k!HFDBASIS32::vHalveStepSize+0x12 (bf920e5a)
bf920e52 d3780c           sar     dword ptr [eax+0xc],cl
bf920e55 c20400           ret     0x4
bf920e58 8b510c           mov     edx,[ecx+0xc]

次に、!chkimg -f を使用してメモリ破損を修復します。

kd> !chkimg win32k -f
Warning: Any detected errors will be fixed to what we expect!
Number of different bytes for win32k: 31 (fixed)

これで、修正されたビューを逆アセンブルし、行った変更を確認できます。

kd> u  win32k!HFDBASIS32::vHalveStepSize
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 8b510c           mov     edx,[ecx+0xc]
bf920e4b 8b4108           mov     eax,[ecx+0x8]
bf920e4e 56               push    esi
bf920e4f 8b7104           mov     esi,[ecx+0x4]
bf920e52 03c2             add     eax,edx
bf920e54 c1f803           sar     eax,0x3
bf920e57 2bf0             sub     esi,eax
bf920e59 d1fe             sar     esi,1

ストレージとメモリの破損の調査

ランダムなファイルとメモリの破損は、調査が困難な場合があります。 状況によっては考慮すべき 1 つのツールとして、ドライバー検証ツールの使用など、追加のメモリチェックを有効にすることです。 ドライバーの検証ツールについては、次に参照してください。

物理メモリをテストするには、Windowsメモリ診断ツールを使用します。 その使用とその他の一般的な手法については、ブルー スクリーン データで説明されています。

スキャン ディスク ユーティリティを使用して、ファイル システム エラーを特定します。 スキャンするドライブを長押し (または右クリック) し、プロパティ を選択します。 ツールを選択します。 今すぐチェック ボタンを選択します。