Snoozy

1.Sleep-inducing; tedious.

Windowsにカーネルドライバを読み込ませてみる

Windowsカーネルドライバを読み込ませてみる

カーネルドライバを作成し,Windowsシステムにロードさせてみる.

まず以下を参考にドライバ開発環境を用意する.

初めてのドライバーの作成 - Windows drivers | Microsoft Docs

環境

VirtualBox上にWindowsホストを立て必要物をインストールする.

バージョン情報は以下の通り.

// VirtualBox
バージョン 6.1.2 r135662 (Qt5.6.2)
// Windows
C:\Users\victim>ver

Microsoft Windows [Version 10.0.18363.592]

カーネルドライバ開発必要物

VirtualBox上のWindowsホストに以下をインストールする.

  1. Visual Studio
  2. Windows SDK
  3. Windows Driver Kit (WDK)

Visual Studio 2019 のインストール

以下のリンクからVisual Studioをインストールする.

Visual Studio: ソフトウェア開発者とチーム向けの IDE およびコード エディター

Windows SDKのインストール

続いてSDKをインストールする.

Visual Studio付属のインストーラーを利用する.

f:id:snoozekvn:20200224012419p:plain

Windows Driver Kit (WDK)のインストール

WDKは専用ページからインストーラーをダウンロードしてくる必要がある

Windows Driver Kit (WDK) のダウンロード - Windows drivers | Microsoft Docs

インストーラーに従いインストールするだけでよく,そのほかの操作は必要ない.

カーネルドライバの作成

以下を参考にHelloWorldを出力するドライバを作成する.

Hello World Windows ドライバーの作成 (KMDF) - Windows drivers | Microsoft Docs

まずVisualStudioのプロジェクトからKernel Mode Driver, Empty (KMDF)を選択する.

f:id:snoozekvn:20200224012430p:plain

続いてソースファイルにkmdfHelloWorld.cを追加する.

今回は動作確認が目的なので処理内容は何でもよい.

デバッグビューに文字列を出力する以下のようなコードを用意した.

#include <ntddk.h>
#include <wdm.h>

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObje,
        PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(pDriverObje);
    UNREFERENCED_PARAMETER(RegistryPath);
    DbgPrint("Hello World\n");
    return STATUS_SUCCESS;
}

これをビルドしようとすると筆者の環境ではSpectre軽減策に関するコンパイルエラーがでた.

これは「プロジェクト」内の「プロパティ」を選択し,「C/C++」の「コード生成」を選択,「Spectre軽減策」をオフにすることで抑制できる(なおSpectre軽減策を含むビルドツールはVisual Studio Installerからインストールできる).

f:id:snoozekvn:20200224012427j:plain

うまくビルドできればDebugフォルダ内にkmdfHelloWorld.sysが作成されるはず.

ドライバのロード

ドライバをシステムにロードする方法はいろいろあり,

  1. scコマンドからサービスを登録する
  2. OSC loaderのようなツールを使用する
  3. 専用ローダーを自作する

などがある.

今回はscコマンドを使用してドライバをロードする.

以下のコマンドでサービスとしてドライバを登録する.

sc create [ServiceName] binPath="[DriverPath]" type=kernel

この時,ProcessHackerを起動しておくと,ドライバの読み込み成功時にポップアップ通知してくれるので成功可否がわかりやすい.

サービスの開始

以下のコマンドで作成したサービスを開始する.これによりドライバがシステムにロードされる.

sc start [ServiceName]

ただし,デフォルトでは以下のように署名なしドライバはロードできない.

f:id:snoozekvn:20200224012423p:plain

署名無しドライバを読み込ませるには追加の設定が必要となる.

「署名付きドライバの強制」のオフ

デフォルトのWindows10では署名付きドライバのみロードが許される.

この「署名付きドライバの強制」をオフにするには以下のうちいずれかを行い,再起動すればよい.

CUI操作で「署名付きドライバの強制」をオフにする方法

bcdedit.exeでブート構成データを調整し再起動する.

bcdedit.exe  /set testsigning on

GUI操作で「署名付きドライバの強制」をオフにする方法

スタートボタン内から[電源] をクリックしてShiftキーを押しながら [再起動]をクリックする.

トラブルシューティング」→「詳細オプション」→ 「スタートアップ設定」と進み,以下の画面へ進む.

f:id:snoozekvn:20200224013150j:plain

ドライバの動作確認

DebugViewを管理者権限で起動し,「Capture Kernel」を選択する.

この状態で,再度サービス開始コマンドを発行すれば,ドライバが正常にロードされHelloWorldがDebugViewに出力される.

www.youtube.com

以上.

参考

proc-cpuinfo.fixstars.com

inaz2.hatenablog.com