このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
前回までは、簡単なデバイスドライバを作成し、DbgPrint関数によるログ出力だけでドライバの基本動作を確認するというものでしたが、今回は本格的なカーネルデバッグを行うための手順について紹介します。Windowsのカーネルデバッグは、
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windows-debugging
に記載されているように、実際にドライバを動作させるターゲットPCと、デバッガを起動してデバッグ作業を行うホストPCとを接続し、PC間の通信によって行います。実ハードウェアを制御するデバイスドライバの開発においては、ターゲットPCはホストPCとは物理的に独立しており、外部インタフェース(例えば、シリアルケーブルやIEEE 1394、USBなど)を通して接続した構成でデバッグを行いますが、今回は仮想マシン環境でゲストOSをターゲットとしてホストOSと接続しながらデバッグを行います。
最新のWDKは、Visual Studioと連携した統合開発環境になっており、デバッグ作業もVisual Studio上で行うことができますが、ここでは前回までと同様Windows 7以前のWDKを使用していることから、Windows Debugger (以下、WinDbg) を用いてデバッグを行います。
仮想マシン環境でカーネルデバッグを行うためには、仮想マシン上のゲストOSがホストOSと通信するために、以下のように名前つきパイプを用いた仮想的なシリアルポートを用意します。
この設定により、ゲストOS側では名前つきパイプがシリアルポートとして見えるため、物理的なシリアルポートを用いた通常のカーネルデバッグと同様、以下の手順でカーネルデバッグを有効にします。ここで、具体的なシリアルポートの番号は環境に依存します。
C:\Windows\system32>bcdedit /set debug on
The operation completed successfully.
C:\Windows\system32>bcdedit /dbgsettings serial debugport:2 baudrate:115200
The operation completed successfully.
WinDbgでカーネルデバッグを有効にするには「File」メニューの「Kernel Debug…」を選択し、以下のダイアログ上でカーネルデバッグの設定を行った上で、「OK」ボタンをクリックして実行します。「Port」には、仮想マシンのシリアルポート設定におけるパイプの名前を指定します。
WinDbgを実行してターゲットPCに接続されると、WinDbgのコマンドウィンドウ上にその旨を示すメッセージが出力されます。
ホストPC側でドライバを修正して再ビルドすると、そのドライバファイルをターゲットPCにコピーしてドライバを再起動する必要がありますが、カーネルデバッグ環境を使えば、ホストPCとターゲットPC間の接続を通してドライバのファイル(.sysファイル)を自動的にダウンロードすることができます。
このためには、まず、対象のドライバファイル名 (ターゲットPC上のパス) と、ホストPC側のパスを以下のように関連づけて記述した.iniファイルを作成する必要があります。
map
\Systemroot\system32\drivers\sample1.sys
Z:\Projects\WinDrvSample\sample1\objchk_win7_x86\i386\sample1.sys
その後、WinDbgをターゲットPCに接続した後、作成した.iniファイルを読み込むことによって、ダウンロードが可能になります。
kd> .kdfiles z:\projects\WinDrvSample\mymap.ini
KD file assocations loaded from 'z:\projects\WinDrvSample\mymap.ini'
ターゲットPC上でドライバの起動が行われる際には、自動的にドライバファイルがホストPCからダウンロードされて実行されます。
KD: Accessing 'Z:\Projects\WinDrvSample\sample1\objchk_win7_x86\i386\sample1.sys' (\SystemRoot\system32\drivers\sample1.sys)
File size 4KKdPullRemoteFile(841AED48): About to overwrite \SystemRoot\system32\drivers\sample1.sys and preallocate to e00
KdPullRemoteFile(841AED48): Return from ZwCreateFile with status 0
.
WinDbgを用いたデバッグは、GUIのメニューを用いて行うこともできますが、今回はコマンドウィンドウ上のコマンド入力により行う方法をいくつか紹介します。
kd> bp sample1!SampleUnload
kd> bl
0 e 90f71010 0001 (0001) sample1!SampleUnload
kd> kb
ChildEBP RetAddr Args to Child
807e5cc4 829bd447 865ede78 92ba0a00 841aed48 sample1!SampleUnload [z:\projects\windrvsample\sample1\sample1.c @ 7]
807e5d00 82889f2b 92ba0a00 00000000 841aed48 nt!IopLoadUnloadDriver+0x1e
807e5d50 82a2a66d 00000001 90838d71 00000000 nt!ExpWorkerThread+0x10d
807e5d90 828dc0d9 82889e1e 00000001 00000000 nt!PspSystemThreadStartup+0x9e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x19
kd> dt DriverObject
Local var @ 0x807e5ccc Type _DRIVER_OBJECT*
0x865ede78
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : (null)
+0x008 Flags : 0x13
+0x00c DriverStart : 0x90f70000 Void
+0x010 DriverSize : 0x6000
+0x014 DriverSection : 0x8654ec00 Void
+0x018 DriverExtension : 0x865edf20 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\sample1"
+0x024 HardwareDatabase : 0x82b86250 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0x90f7403e long sample1!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0x90f71010 void sample1!SampleUnload+0
+0x038 MajorFunction : [28] 0x828cd437 long nt!IopInvalidDeviceRequest+0
今回は、Windowsドライバのカーネルデバッグの基本手順を、前回の投稿で作成した簡単なドライバを用いて紹介しました。通常は、ドライバを動かすターゲットPCとデバッガを実行するホストPCとを物理的に接続した構成でデバッグを行いますが、名前つきパイプによりホストOSとゲストOSを接続することで、ホストPCと同一ハードウェア上の仮想マシンでデバッグを行えることを確認しました。
コンピュータビジョンセミナーvol.2 開催のお知らせ - ニュース一覧 - 株式会社フィックスターズ in Realizing Self-Driving Cars with General-Purpose Processors 日本語版
[…] バージョンアップに伴い、オンラインセミナーを開催します。 本セミナーでは、...
【Docker】NVIDIA SDK Managerでエラー無く環境構築する【Jetson】 | マサキノート in NVIDIA SDK Manager on Dockerで快適なJetsonライフ
[…] 参考:https://proc-cpuinfo.fixstars.com/2019/06/nvidia-sdk-manager-on-docker/ […]...
Windowsカーネルドライバを自作してWinDbgで解析してみる① - かえるのほんだな in Windowsデバイスドライバの基本動作を確認する (1)
[…] 参考:Windowsデバイスドライバの基本動作を確認する (1) - Fixstars Tech Blog /proc/cpuinfo ...
2021年版G検定チートシート | エビワークス in ニューラルネットの共通フォーマット対決! NNEF vs ONNX
[…] ONNX(オニキス):Open Neural Network Exchange formatフレームワーク間のモデル変換ツー...
YOSHIFUJI Naoki in CUDAデバイスメモリもスマートポインタで管理したい
ありがとうございます。別に型にこだわる必要がないので、ユニバーサル参照を受けるよ...