カーネルモード デバッガで UMDF ドライバをライブデバッグする


UMDF ドライバをデバッグする際に、ユーザーモード デバッガでWUDFHost.exe にアタッチしてライブデバッグするだけではデバッグしきれなくて困ったことはありませんか?

 

例えば、OS のシャットダウン中の処理をデバッグしたい場合、ユーザーモード デバッガを操作している画面がシャットダウン中になるため、デバッガをその画面から操作できなくなります。

 

そこで、今回は、カーネルモード デバッガ(windbg.exe) UMDF ドライバをデバッグする方法をご紹介します。カーネルモード デバッガからであれば、画面がシャットダウン中であっても、UMDF ドライバのブレークポイントで止めて、ライブデバッグすることができます。

 

具体的には、以下の手順で進めます。

 

    1. ターゲットPC へのUMDF2 ドライバのインストール
    2. ターゲットPC へのWDFVerifier.exe のコピー
    3. カーネルモードデバッガをターゲットPC にアタッチ
    4. WDFVerifier.exe によるターゲット PC の設定
    5. 動作確認

 

今回は、例として、デバッガのホストPC、ターゲットPC ともにWindows 10 (1703) x86 で行います。また、サンプルドライバをビルドする開発用PC はデバッガのホストPC と同一とします。

 

1.ターゲットPCへのUMDF2 ドライバのインストール

 

ターゲットPC UMDF2 ドライバをインストールします。今回は、例として、UMDF2 Toaster Sample wdffeaturedum.dll を使用します。

 

サンプルの入手とビルド方法は、以下のエントリの「1. サンプルの入手」と「2. サンプルのビルド」をご参照ください。

 

UMDF Version 2 Toaster Sample をインストールする

https://blogs.msdn.microsoft.com/jpwdkblog/2016/11/28/umdf-version-2-%e3%81%ae-toaster-sample-%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/

 

ビルドすると、\umdf2\func\featured\Debug\wdffeaturedum フォルダに以下の 3 つのファイルが生成されます。

 

wdffeaturedum.dll

wdffeaturedum.inf

wudf.cat

 

ターゲットPC C:\umdf2toaster というフォルダを作り、上記3 つのファイルをすべてコピーします。また、開発用PC C:\Program Files (x86)\Windows Kits\10\Tools\x86 にあるdevcon.exe も、ターゲットPC の同じC:\umdf2toaster フォルダにコピーします。

 

管理者権限でコマンドプロンプトを起動します。cd コマンドでC:\umdf2toaster フォルダに移動し、以下を実行します。

 


devcon install wdffeaturedum.inf root\toaster

 

ドライバーをインストールするかどうか確認するダイアログが表示されたら、そのままインストールしてください。以下が表示されたら成功です。

 


Device node created. Install is complete when drivers are installed

Updating drivers for root\toaster from C:\umdf2toaster\wdffeaturedum.inf.

Drivers installed successfully.

 

デバイスマネージャでも確認しておきます。

 

[スタート] を右クリックし、[デバイス マネージャー] を起動しますと、以下のように[Toaster] のノードに[Sample UMDF Toaster Driver featured] と表示されていることが確認できます。

 

clip_image001

 

 

2.ターゲットPCへのWDFVerifier.exe のコピー

 

WDK 10 がインストールされた開発側のPC には、以下のパスにwdfverifier.exe があります。

 

C:\Program Files (x86)\Windows Kits\10\Tools\x86

 

これをターゲットPC の任意のフォルダにコピーします。今回は、C:\umdf2toaster にコピーすることにします。

 

 

3.カーネルモード デバッガをターゲットPC にアタッチ

 

ホストPC 上にインストールしたカーネルモードデバッガ(windbg.exe) をターゲットPC にアタッチします。

 

Windbg.exe のインストールは以下のブログエントリをご参照ください。

 

デバッガ(WinDbg) をインストールする

https://blogs.msdn.microsoft.com/jpwdkblog/2016/03/07/%e3%83%87%e3%83%90%e3%83%83%e3%82%ac-windbg-%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/

 

カーネルデバッガの接続方法は、以下のブログエントリからご自身の環境にあったものをご参照ください。

 

Kernel Debugger 接続インターフェース

https://blogs.msdn.microsoft.com/jpwdkblog/2016/02/24/kernel-debugger/

 

シリアルケーブルでのカーネルモードデバッグ設定手順

https://blogs.msdn.microsoft.com/jpwdkblog/2016/03/15/%e3%82%b7%e3%83%aa%e3%82%a2%e3%83%ab%e3%82%b1%e3%83%bc%e3%83%96%e3%83%ab%e3%81%a7%e3%81%ae%e3%82%ab%e3%83%bc%e3%83%8d%e3%83%ab%e3%83%a2%e3%83%bc%e3%83%89%e3%83%87%e3%83%90%e3%83%83%e3%82%b0%e8%a8%ad/

 

Hyper-V 第二世代仮想マシンのGuest OS へのwindbg 接続方法

https://blogs.msdn.microsoft.com/jpwdkblog/2014/02/27/hyper-v-guest-os-windbg/

 

Hyper-Vなどの仮想OSwindbgをアタッチする方法

https://blogs.msdn.microsoft.com/jpwdkblog/2009/03/18/hyper-voswindbg/

 

 

4.WDFVerifier.exe によるターゲット PC の設定

 

ターゲットPC 上で、WDFVerifier.exe を管理者権限で実行し、[Global WDF Settings] タブを開きます。

下部の[Global User Mode Verifier Settings] の中の[Attempt to attach to kernel debugger if no user-mode debugger attaches at this time.] のチェックボックスをON にします。

 

clip_image002

 

[OK] を押して、以下の画面で[Yes] を押します。

 

clip_image003

 

カーネルモード デバッガのCommand ウィンドウに以下のように表示されます。

 


UMDF: Breaking on load of module wdffeaturedum.dll

UMDF: Waiting 0 seconds for debugger to attach.

UMDF: No user-mode debugger found.

Breaking into kernel debugger.

Break instruction exception - code 80000003 (first chance)

001b:778e4160 cc              int     3

 

そのままg Command ウィンドウの kd> に入力してEnter を押し、ターゲットPC の動作を再開します。

 

ターゲットPC を再起動します。

 

 

5.動作確認

 

ターゲットPC を再起動すると、上記と同じように、wdffeaturedm.dll のロード時にカーネルモード デバッガにブレークインしてくれます。

 

Wdffeaturedum.dll のシンボルファイル(wdffeaturedum.pdb) が、開発用PC \umdf2\func\featured\Debug のフォルダにあるので、シンボルパスにそれを追加します。シンボルパスの設定については、以下のブログエントリの「4. シンボルファイルの設定」をご参照ください。

 

メモリダンプに!analyze -v するまで・後編~ ダンプを開く~

https://blogs.msdn.microsoft.com/jpwdkblog/2009/06/11/analyze-v/

 

以下のコマンドで、wdffeaturedum.dll のロード時とシャットダウン時のwdffeaturedum.dll の処理でブレークインできるようにブレークポイントを貼り、g でターゲットPC の動作を再開します。

 


bp wdffeaturedum!DriverEntry

bp wdffeaturedum!ToasterEvtDeviceD0Exit

 

wdffeaturedum!DriverEntry でブレークインします。

 


kd> g

Breakpoint 0 hit

wdffeaturedum!DriverEntry:

001b:6c951460 55              push    ebp

kd> knL

# ChildEBP RetAddr

00 02eff090 6c95215e wdffeaturedum!DriverEntry

01 02eff0b0 001448c0 wdffeaturedum!FxDriverEntryUmWorker+0x127

02 02eff108 00144f22 WUDFHost!InitializeFlatCApiDriver+0x87

03 02eff1fc 001455f4 WUDFHost!CWudfModuleTable::LoadComponentAndCreateInstance+0x531

04 02eff22c 00145692 WUDFHost!CWudfModuleTable::LoadComponentAndCreateInstanceEx+0x63

05 02eff258 0013fb63 WUDFHost!CWudfModuleTable::LoadFrameworkAndDriver+0x66

06 02eff310 0012e484 WUDFHost!CWudfDeviceStack::LoadDrivers+0x13e

07 02eff4cc 6fe8edcc WUDFHost!CLpcNotification::Message+0x334

08 02eff534 6fe8f33f WUDFPlatform!WdfLpcPort::ProcessMessage+0x2cc

09 02eff55c 6fe8f42d WUDFPlatform!WdfLpcCommPort::ProcessMessage+0x1ff

0a 02eff5a0 6fe8f57c WUDFPlatform!WdfLpcConnPort::ProcessMessage+0xcd

0b 02eff680 00130a86 WUDFPlatform!WdfLpc::RetrieveMessage+0xdc

0c 02eff694 00130a41 WUDFHost!MessageAvailableThunk+0x26

0d 02eff6a8 0013261d WUDFHost!CThreadpool::WorkerThread+0x51

0e 02eff6b0 7795cf0f WUDFHost!ThreadPoolWorkerThunk+0xd

0f 02eff6dc 7795ce30 ntdll!TppExecuteWaitCallback+0x88

10 02eff6f8 7794244f ntdll!TppWaitCompletion+0x80

11 02eff8b0 75a19ba4 ntdll!TppWorkerThread+0x58f

12 02eff8c4 7797ac9b KERNEL32!BaseThreadInitThunk+0x24

13 02eff90c 7797ac6f ntdll!__RtlUserThreadStart+0x2b

14 02eff91c 00000000 ntdll!_RtlUserThreadStart+0x1b

 

OS をシャットダウンすると、wdffeaturedum!ToasterEvtDeviceD0Exit でブレークインします。

 


kd> g

Breakpoint 1 hit

wdffeaturedum!ToasterEvtDeviceD0Exit:

001b:6c951370 55              push    ebp

kd> knL

# ChildEBP RetAddr

00 02efef04 6c7a7fdb wdffeaturedum!ToasterEvtDeviceD0Exit

01 02efef20 6c7a3c62 WUDFx02000!FxPnpDeviceD0Exit::InvokeClient+0x2b

02 02efef3c 6c7a9e59 WUDFx02000!FxPrePostCallback::InvokeStateless+0x39

03 (Inline) -------- WUDFx02000!FxPnpDeviceD0Exit::Invoke+0xf

04 02efef5c 6c7a9c8d WUDFx02000!FxPkgPnp::PowerGotoDxIoStopped+0x101

05 02efef64 6c7a9a6c WUDFx02000!FxPkgPnp::PowerGotoDNotZeroIoStopped+0xd

06 02efefb4 6c7aa899 WUDFx02000!FxPkgPnp::PowerEnterNewState+0x141

07 02efefd8 6c7aa6c2 WUDFx02000!FxPkgPnp::PowerProcessEventInner+0x1a6

08 02eff000 6c7ac849 WUDFx02000!FxPkgPnp::PowerProcessEvent+0x160

09 (Inline) -------- WUDFx02000!FxPkgFdo::LowerDevicePower+0xf

0a 02eff01c 6c7acbe3 WUDFx02000!FxPkgFdo::DispatchDeviceSetPower+0xc6

0b 02eff028 6c79f9a0 WUDFx02000!FxPkgFdo::_DispatchSetPower+0x23

0c 02eff054 6c76c6b5 WUDFx02000!FxPkgPnp::Dispatch+0x2e0

0d 02eff07c 6c79150c WUDFx02000!DispatchWorker+0x6a

0e (Inline) -------- WUDFx02000!FxDevice::Dispatch+0x1f

0f 02eff0a0 6c78e450 WUDFx02000!FxDevice::DispatchWithLock+0xba

10 02eff0a8 6c7945c9 WUDFx02000!FxDevice::DispatchWithLockUm+0x10

11 02eff0d0 0014044d WUDFx02000!FxMessageDispatch::DispatchPnP+0xa9

12 02eff20c 00137d01 WUDFHost!CWudfDeviceStack::OnDispatchPnp+0x1d3

13 02eff21c 00134275 WUDFHost!CWudfPnpIrp::Dispatch+0x11

14 02eff248 0013aca4 WUDFHost!CWudfDeviceStack::Forward+0x6865

15 02eff268 0013afea WUDFHost!CLpcNotification::UnloadSafeDispatchIrp+0x3a

16 02eff2dc 0013a655 WUDFHost!CLpcNotification::WudfPnpHandler+0x20a

17 02eff304 0012fe0a WUDFHost!CLpcNotification::ProcessPnpPowerIrp+0xd5

18 02eff4cc 6fe8edcc WUDFHost!CLpcNotification::Message+0x1cba

19 02eff534 6fe8f33f WUDFPlatform!WdfLpcPort::ProcessMessage+0x2cc

1a 02eff55c 6fe8f42d WUDFPlatform!WdfLpcCommPort::ProcessMessage+0x1ff

1b 02eff5a0 6fe8f57c WUDFPlatform!WdfLpcConnPort::ProcessMessage+0xcd

1c 02eff680 00130a86 WUDFPlatform!WdfLpc::RetrieveMessage+0xdc

1d 02eff694 00130a41 WUDFHost!MessageAvailableThunk+0x26

1e 02eff6a8 0013261d WUDFHost!CThreadpool::WorkerThread+0x51

1f 02eff6b0 7795cf0f WUDFHost!ThreadPoolWorkerThunk+0xd

20 02eff6dc 7795ce30 ntdll!TppExecuteWaitCallback+0x88

21 02eff6f8 7794244f ntdll!TppWaitCompletion+0x80

22 02eff8b0 75a19ba4 ntdll!TppWorkerThread+0x58f

23 02eff8c4 7797ac9b KERNEL32!BaseThreadInitThunk+0x24

24 02eff90c 7797ac6f ntdll!__RtlUserThreadStart+0x2b

25 02eff91c 00000000 ntdll!_RtlUserThreadStart+0x1b

 

 

<参考文献>

How to Enable Debugging of a UMDF Driver

https://docs.microsoft.com/ja-jp/windows-hardware/drivers/wdf/enabling-a-debugger

 

WDF Verifier Control Application

  https://docs.microsoft.com/ja-jp/windows-hardware/drivers/devtest/wdf-verifier-control-application

 

 

以上の内容がお役に立ちましたら幸いです。

 

WDK サポートチーム 津田

Skip to main content