Article

2018年5月24日

これまで「Windowsデバイスドライバの基本動作を確認する」などでWindowsのカーネルモードデバイスドライバに関するBlog記事を書いてきましたが、ここからは具体的な用途をもつデバイスドライバを題材として、Windowsデバイスドライバに関連する技術調査を行った結果を紹介していこうと思います。

今回は、WDK (Windows Driver Kit) のサンプルデバイスドライバに含まれているRAMDiskドライバを動かしてみるとともに、一部修正を加えることでドライバの挙動がどう変化するかを調査した結果について報告します。

このドライバは、WDF (Windows Driver Foundation) の KMDF (Kernel Mode Driver Framework) に基づくドライバで、それ自身が FAT (File Allocation Table) のファイルシステムを構築してRAMDiskとして動作するようになっており、レジストリで以下のパラメータを設定することができます。

  • ドライブレター (DriveLetter)
    • デフォルトは “R:”
  • ディスクサイズ (DiskSize)
    • デフォルトは0x100000 (1 MiB = 1,048,576バイト)

インストールと基本動作確認

サンプルRAMDiskドライバのインストールは、このドライバの説明に記載されているとおり、WDK付属のアプリケーションである Windows Device Console (devcon) を使って、以下の手順で行いました。

C:\Setup\WdfRamdisk>devcon install ramdisk.inf ramdisk
Device node created. Install is complete when drivers are installed...
Updating drivers for ramdisk from C:\Setup\WdfRamdisk\ramdisk.inf.
Drivers installed successfully.

デバイスマネージャを開くと、デバイスが追加されている様子を確認することができます。

しかし、エクスプローラを起動してもRAMDiskのドライブ (“R:”) が見えません。Administratorとしてコマンドプロンプトを起動してみると、Rドライブに移動して、その下にファイルを作ったり、ファイルの中身を参照したりすることができますが、一般ユーザの権限でコマンドプロンプトを起動しただけでは、Rドライブにアクセスすることはできません。

アクセス制御リストの変更と動作確認

Windowsのデバイスドライバは、デバイスを管理するデータ構造であるデバイスオブジェクトを生成するために IoCreateDevice() 関数を使用しますが、この関数で生成されたデバイスオブジェクトの使用は制限されており、Administratorしかアクセスすることができません。デバイスオブジェクトへのアクセス権限を変更するためには、IoCreateDeviceSecure() 関数を用いてデバイスオブジェクトを生成し、その際、誰からのどのようなアクセスを許可するかを SDDL (Security Description Definition Language) という文字列によって指定する必要があります。

今回使用したWDKのサンプルRAMDiskドライバは、KMDFベースのドライバなので、IoCreateDeviceSecure()を直接呼び出すわけではなく、KMDFのデバイスクラスのインスタンスを生成する際に、以下のような形で  WdfDeviceInitAssignSDDLString() 関数を用いてSDDLを指定します。

    // SDDLを指定
    WdfDeviceInitAssignSDDLString(DeviceInit, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL);

    // デバイスオブジェクトを生成
    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

WDK提供のヘッダファイルwdmsec.hには、よく使うSDDLの文字列が定義されています。今回は、以下の5種類のSDDLについて、それを指定したときにデバイスに対するアクセスがどのように変化するか、ユーザ見えの挙動の変化を調査しました。

  • SDDL_DEVOBJ_KERNEL_ONLY
    • カーネルモードのみからアクセス可能
    • ユーザモードからはアクセス不可
  • SDDL_DEVOBJ_SYS_ALL
    • カーネルモードのほか、System権限のユーザモードプロセスはアクセス可能
  • SDDL_DEVOBJ_SYS_ALL_ADM_ALL
    • カーネルモードのほか、System権限とAdministrator権限のユーザモードプロセスは全てのアクセスが可能
  • SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_R
    • カーネルモードのほか、System権限のユーザモードプロセスは全アクセス可能
    • Administrator権限のユーザモードプロセスは、Read/Writeと実行が可能
    • 一般ユーザ権限のプロセスはReadのみ可能
  • SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWS
    • カーネルモードのほか、System権限のユーザモードプロセスは全アクセス可能
    • Administrator権限、一般ユーザ権限および信頼されないユーザに対してRead/Writeと実行の権限が与えられる

上のSDDLを使用し、以下の(1) ~ (5)の操作に対する挙動を確認した結果を以下に示します。

  1. Administratorでコマンドプロンプトを起動してアクセス可能
  2. エクスプローラでドライブが表示される
  3. エクスプローラからドライブにアクセスできる
  4. エクスプローラからアプリケーションを起動してファイルを保存できる
  5. エクスプローラからアプリケーションを起動してファイル名を変更できる
SDDL (1) (2) (3) (4) (5)
SDDL_DEVOBJ_KERNEL_ONLY × × n/a n/a n/a
SDDL_DEVOBJ_SYS_ALL × n/a n/a n/a
SDDL_DEVOBJ_SYS_ALL_ADM_ALL × n/a n/a
SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_R × n/a
SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX ×

SDDL_DEVOBJ_KERNEL_ONLYは、カーネルモードからのアクセスのみ受け付けるもので、ユーザモードからはアクセスできないため、エクスプローラにドライブが表示されず、Administratorでコマンドプロンプトを起動してドライブにアクセスすることもできません。

SDDL_DEVOBJ_SYS_ALLは、System権限で動作しているユーザモードプロセスからはアクセスできるため、エクスプローラでドライブが表示されますが、アクセスすることはできません。また、Administratorからはアクセスできないため、Administratorでコマンドプロンプトを起動してもドライブにアクセスすることはできません。

SDDL_DEVOBJ_SYS_ALL_ADM_ALLは、Administratorからのアクセスは許可されるため、Administratorでコマンドプロンプトを起動することによりドライブにアクセスして、ファイルの作成や参照を行うことができますが、エクスプローラからドライブにアクセスすることはできません。

SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_Rは、一般ユーザからのReadアクセスが許可されるため、エクスプローラからドライブにアクセスすることができますが、Writeアクセスは許可されていないため、ファイルを保存することはできません。

SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWXは、一般ユーザによるRead/Writeアクセスおよび実行が許可されており、既存のファイルの修正と保存ができるようになっています。ただ、新規ファイルの作成や既存ファイルの名前変更などはできないようです。以下は、Administratorとして起動したコマンドプロンプト上で作成したファイルをエクスプローラからNotepadで開き、別名のファイルとして保存しようとしたときのエラーメッセージです。

このSDDLは、事前定義されたSDDLの中では最も広範囲でアクセスを許可するものですが、まだ一般ユーザが自由にアクセスできるというレベルではありません。事前定義のSDDLの宣言を含むヘッダファイル wdmsec.hを確認したところ、以下のような記述がありました。

//
// SDDL_DEVOBJ_SYS_ALL_ADM_ALL_WORLD_ALL_RES_ALL is listed for completeness.
// This ACL would give *any* user *total* access to the device, including the
// ability to change the ACL, locking out other users!!!!!
//
// As this ACL is really a *very* bad idea, it isn't exported by this library.
// Don't make an ACL like this!
//

/*
DECLARE_CONST_UNICODE_STING(
    SDDL_DEVOBJ_SYS_ALL_ADM_ALL_WORLD_ALL_RES_ALL,
    "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)(A;;GA;;;RC)"
    );

extern const UNICODE_STRING     SDDL_DEVOBJ_SYS_ALL_ADM_ALL_WORLD_ALL_RES_ALL;
*/

このSDDLは、全てのユーザに対して完全なアクセスを提供するものですが、これを使うのは推奨されておらず、wdmsecライブラリも公開していないとのことです。そこで、このSDDLをソースコード中に定義して、それを使うように修正してみました。

@@ -361,6 +361,9 @@ Return Value:
     WDFQUEUE                queue;
     DECLARE_CONST_UNICODE_STRING(ntDeviceName, NT_DEVICE_NAME);
 
+    // Give total access to any user
+    DECLARE_CONST_UNICODE_STRING(sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)(A;;GA;;;RC)");
+
     PAGED_CODE();
 
     UNREFERENCED_PARAMETER(Driver);
@@ -379,6 +382,9 @@ Return Value:
     WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
     WdfDeviceInitSetExclusive(DeviceInit, FALSE);
 
+    // Specify SDDL (Security Descriptor Definition Language) string to control access to the device
+    WdfDeviceInitAssignSDDLString(DeviceInit, &sddlString);
+
     //
     // Since this is a pure software only driver, there is no need to register
     // any PNP/Power event callbacks. Framework will respond to these

このようにすることで、エクスプローラ上で新しいファイルを生成したり、エディタで編集したファイルを別の名前で保存したりできるようになりました。

おわりに

本稿では、WDKのサンプルRAMDiskドライバを修正して、デバイスのアクセス権限を変更し、ドライバの外見えの動作がどう変化するかを調査した結果について紹介しました。次回以降は、実際にファイルアクセスを行うアプリケーションを使って、ドライバ内部の動きを見ていこうと思います。

About Author

hiro.sakamoto

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Recent Comments

Social Media