
SoftICEのようなWindows 11用カーネルデバッガ
BugChecker は、Windows 11(および Windows XP もサポート: Windows XP から 11 までの x86 および x64 バージョンに対応)向けの、SoftICE に似たカーネルおよびユーザーデバッガです。BugChecker は、WinDbg や KD のように、デバッグ対象のシステムに接続するための2台目のマシンを必要としません。このバージョンの BugChecker(20年前に開発されたオリジナル版とは異なり)は、NTOSKRNL 内部の非公開 KD API を活用しています。KD API により、WinDbg/KD は仮想メモリの読み書き、レジスタの読み書き、アドレスへのブレークポイント設定などの呼び出しを行うことができます。
対照的に、オリジナルの BugChecker は、SoftICE と同様に、複数のカーネル API(公開および非公開の両方)をフックし、APIC を制御し、IPI を送信するなどして、システムを「乗っ取る」方法を採用していました。このアプローチは、サポートされるすべての Windows のバージョンおよびサブバージョン(関数シグネチャレベル)だけでなく、可能なすべてのハードウェア構成との互換性を確保する必要があるため、複雑さが指数関数的に増加し(システムの安定性が低下します)。さらに、20年後の現在、PatchGuard がこの解決策を不可能にしています。
これに対して、このバージョンの BugChecker は、カーネル内の KdSendPacket および KdReceivePacket への呼び出しをインターセプトすることで、外部のカーネルデバッガを実行している2番目のシステムとしてデバッグ対象のマシンに自身を提示しますが、実際にはすべてが同一マシン上で行われます。通常、これは KDCOM.DLL を置き換え(Windows で KD API のシリアルケーブル通信を実装するモジュールです)、システムをカーネルデバッグモードで起動することで実現されます。このアプローチ(VirtualKD に触発されています)は、複雑さを軽減し、安定性と互換性(および移植性、例えば ARM への対応や、モジュール性。低レベルのデバッガ機能は KdXxxPacket の背後に実装され、カスタム実装に置き換えることができます)を向上させます。さらに、起動時に(「偽の」ではありますが)カーネルデバッガが存在することで、Windows は PatchGuard を無効にします。
現時点では、BugChecker は入力に PS/2 キーボード、出力にリニアフレームバッファを必要とします。最近のノートパソコンの多くに内蔵されているキーボードは依然として PS/2 であることに注意してください。
Windows 11 22H2、VirtualBox 7.0.4 上での BugChecker のデモ。ユーザーモードスレッドの実行フローを変更する JavaScript ブレークポイント条件を作成しています。
非常に制限された環境(Raspberry Pi 4、4GB RAM)で、QEMU 上の Windows XP(512MB RAM)を介して BugChecker を実行。ユーザーモードからカーネルへのすべての SYSENTER 呼び出しをログに記録するためにブレークポイントを使用。サービスインデックスは JavaScript 配列に保存されます。
HP Pavilion Dv2000(PS/2 キーボード搭載の古い PC)のベアメタル上で直接 BugChecker を実行。OS は Windows 7 Home 32bit。
BugChecker をインストールおよび使用する際は、セキュアブートが無効になっていることを確認してください。通常は後で再度有効にできます。VMware または VirtualBox を使用している場合、仮想マシンの設定でセキュアブートを無効にできます。
Windows 8、10、11 を使用している場合は、bcdedit /set "{current}" bootmenupolicy legacy コマンドを使用して、レガシーブートメニューを有効にすることも検討してください。これにより、起動中に BugChecker のブートオプションを選択し、同時にドライバ署名の強制を無効にできるため、よりスムーズな体験が可能になります。
最初のステップは、Symbol Loader を起動することです:

必要であれば、「Disable Display Drvs」ボタンをクリックしてディスプレイドライバを無効にします。同じことは Windows のデバイスマネージャーでも実行できます。ディスプレイドライバを無効にすると、システムの再起動後も無効のままになります。BugChecker を使用しない場合、後でいつでも再び有効にできます。
ここでのポイントは、BugChecker がインターフェイスを描画するために、32ビット/ピクセル形式のリニアフレームバッファを必要とすることです。ディスプレイドライバを無効にすると、Windows は UI 描画のハードウェアアクセラレーションを破棄し、VGA 互換モードにフォールバックします。ベアメタルまたは VMware で実行する場合は、ディスプレイドライバを無効にする必要があります。VirtualBox で実行する場合は、後述するようにディスプレイドライバを無効にするか、BugChecker.dat の vm_screen 設定を設定する必要があります。QEMU で実行する場合は、ディスプレイドライバを無効にする必要はありませんが、「-vga std」ディスプレイデバイスを指定してください。
VGA 互換モードは最大画面解像度を制限する可能性があることに注意してください。VMware は最大解像度 1152x864 に制限されます。「-vga std」ディスプレイデバイスを使用した QEMU では、この制限はありません。
興味深いことに、BugChecker が複数のグラフィックスカードを搭載したシステムにインストールされている場合、1つのグラフィックスカードのディスプレイドライバのみを無効にすることが可能で、そのカードは BugChecker UI を表示する画面に接続されます。2つ目のカード(メインディスプレイとして設定)は、OpenGL や DirectX サポートを含むすべての 2D および 3D アクセラレーション機能を保持します(注: VMware、Windows 11、DisplayLink ディスプレイでテスト済み)。
次に、「Start Driver」をクリックし、続いて「Auto Detect」、最後に「Save」をクリックします。「Auto Detect」はフレームバッファの幅、高さ、物理アドレス、ストライドを自動的に判別できるはずです。ただし、これらの設定を手動で指定することもできます(終了時に必ず「Save」をクリックしてください)。「Stride」が 0 の場合、ドライバの起動時に「Width」* 4 として自動計算されます。「Address」(フレームバッファの物理アドレス)は、Windows デバイスマネージャーでディスプレイデバイスの「プロパティ」を開き、「リソース」タブで確認できます。
次に、「KDCOM Hook Method」セクションで「Callback」をクリックし、「Copy/Replace Kdcom」をクリックします。その後、システムを再起動できます。
このセットアッププロセスは一度だけ実行する必要があり、必要に応じてディスプレイドライバを再び有効にできます。ただし、BugChecker を使用する際は、設定によってはディスプレイドライバを再度無効にする必要があります。
BugChecker.dat の vm_screen 設定により、Symbol Loader で事前に画面解像度を指定したり、ディスプレイドライバを無効にしたりすることなく、VirtualBox 内で BugChecker デバッガ UI を開くことができます。
このアイデアは、仮想ディスプレイデバイスの I/O ポートとコマンドバッファに直接書き込むことで、現在の画面解像度を取得し、フレームバッファの更新をハイパーバイザーに通知するというものです。
このソリューションは X.org xf86-video-vmware ドライバに触発されました。
このソリューションは VirtualBox VM でのみ機能し、BugChecker.dat ファイルを手動で編集する必要があります:

これは実験的な機能です。将来的には、この設定は Symbol Loader によって自動的に追加される予定です。
コマンド名と構文は、オリジナルの SoftICE for NT のものにできるだけ近づけて選択されています: