User-mode Raw Disk Access

This page describes DskACL, a set of utilities to change access control for a disk drive, list disk information and lock a disk for exclusive access. It is provided free of charge, with no warranties! See LICENSE.txt for more information. No installation is required to run these utilities.

Background

On Windows NT, only members of the Administrators group have access to perform direct disk I/O, without going through the filesystem. However, with the advent of virtual machines it may be desirable that such access should be allowed to certain disks also for regular accounts in order to run with only necessary permissions. Thus the need for a utility to control such access. Reasons for using direct disk access is that it facilitates dual-boot, improves performance of the guest machine and makes it easier to transfer files between systems. It will also offer a somewhat better recoverability in the case of a powerout.

It should be noted that this utility only employs documented routines in the operating system and does not expose any security holes. It cannot be used to elevate a user beyond designated privileges. An Administrator account is needed to do the initial grant of access.

Setup that must be done once as Administrator

Retrieve the identifier for the disk

Run the ShowDsks utility in disk mode:

cscript /nologo showdsks.vbs -d

The first column output of this command is the disk number; you can use this to create the Win32-reachable path \\.\PHYSICALDRIVE«x». Once this number is assigned by the operating system it will not change as long as the disk is attached, but it may change the next time the disk is attached subject to which other disks that have been attached in the meantime.

In the second column, a device identifier will be returned. It has the form USBSTOR\DISK&VEN_«vendor»&PROD_«product»&REV_«revision»\«serial»&0. (The serial number seems to be a hexadecimal encoding of the serial using a 16-bit little endian format, i.e. every pair of bytes should be swapped before converting it to ASCII). Use this information to verify that you indeed are looking at the correct disk. Note that some inexpensive USB devices may not have a serial number. In that case, the Plug'n'Play Manager will invent one for the duration of the attachment only; on subsequent attachments in may differ.

If a string is given after the -d argument, only the disks that have a device ID with this prefix will be listed. This can be used to for instance limit the search to all USB devices.

Check which rights are granted to the drive

Run the SubInAcl utility from the Support Tools to see which accesses that has already been granted for the drive. The default is that only System and the builtin Administrator account can write to the disk.

subinacl /noverbose /file \\.\physicaldrive«x» /display=sddl

where «x» is the disk number that you retrieved earlier with ShowDsks. (If you are running Windows XP, you'll need an updated version of SubInAcl for this to work correctly. The link to the updated version can be found in the References section).

Changing the access control list of the drive

You can change the access for the drive using the SubInAcl utility but it will only last until the device is detached, and you'll have to be an Administrator every time you do so. This is because it alters the live, volatile kernel object.

In order to make the change durable, we'll have to write it to the security descriptor in the Registry which is read when the disk is attached and the corresponding kernel object created. It is located in the key HKLM\SYSTEM\CurrentControlSet\Enum\«device-ID»\Security, but this key is protected and hidden from view, even for the System account! However, there is an API to change it, and the DskACL utility is a command-line front-end for this API. You can invoke the utility like this:

dskacl -i "«device-ID»" -r

where the «device-ID» can be found with the ShowDsks utility. Note the use of quotation marks around the device identifier to escape the use of ampersands in it that would otherwise be interpreted by the command line shell.

By default, it grants (in addition to System and Administrators) read and write access to the drive for members of the Power Users group. If you want a different setup, you'll have to compose the SDDL string that should be applied and submit that to the utility as well (using the -s option). Check the reference section for articles that describes this syntax.

Also note the -r argument at the end; it causes the device to be reattached so that the new access rights comes into effect immediately; the access rights are only read for the drive when it is connected so you would otherwise have to detach and reattach it again. Needless to say, this is a bad idea if you have any files open on the drive at the time. The new rights can be verified using the SubInAcl utility as show previously.

Actions to do as a regular user

Create a virtual disk

You'll have to create a "virtual" disk that refers to the physical disk:

VBoxManage -nologo internalcommands createrawvmdk -filename «path-to.vmdk» -rawdisk \\.\physicaldrive«x»

This disk can then be attached to a virtual machine like any other virtual disks. Any I/O from the guest will be forwarded to the physical drive.

There is also the possibility of creating a virtual disk which can only refer to some partitions on the disk, and which redirects the master boot record. This feature is useful if you want to boot from another partition on the same disk as the host operating system. I won't recommend it if you have a rotational disk since head movement cannot be optimized, but sometimes you have no choice.

Verify that the drive is in the same slot

Note that the virtual disk refers to the numerical index given to the disk and recall that this index will change if the order of attachment changes. Thus, it would be good practice to verify that the disk currently attached at a certain index match the supposed identifier before doing raw access to it. This can be done by running the ShowDsks utility in "partition" mode:

cscript /nologo showdsks.vbs -p "«device-ID»" «partition-number»

Output from this command will be information about the partitions found on the disk that has the given device identifier, any recognized file systems on those partitions, drive letter that has been assigned and the volume serial number. You can match this output against the prerequisites and stop before booting the guest if there is a discrepancy.

Lock any mounted file systems

If you use a file system in the guest that is also recognized by the host (i.e. FAT or NTFS), the volume should be locked and dismounted to avoid two operating systems writing to the same on-disk structures without any coordination. The Xclusive utility will keep the drive locked while executing another command and unlock it afterward:

xclusive \\.\«drive»: wscript launchvm.vbs «virtual-machine-name»

This utility exists both in a console variant (.com) and a GUI variant (.exe). The LaunchVM is a helper script that starts the guest machine in VirtualBox and wait until the guest is stopped before it is run. In that way, only one system has full control of the drive at any time. (Before I discovered the automation API of VirtualBox I wrote an alternative script for this called StartVM which does the same thing but only with command-line tools).

Note that it is a volume that is locked, not the disk, since we want the file system to release its handle of the disk. That is why a drive letter and not a disk index is used to lock it. If you need to lock more than one partition, then these commands must be nested. When the volume is eventually unlocked, the file system driver on the host will remount it, updated with the changes done by the guest machine.

Disks, partitions and volumes

You may wonder if it is possible to grant access to just one partition and not the entire disk: Unfortunately, it is not. The reason is twofold: First, Windows store security information for devices, not partitions in the Registry. When a device is attached, it is inspected and from that point forward the kernel objects that addresses the partitions (\Device\Harddisk«x»\Partition«y») are created. Second, there is no easy way to address a partition in user-mode. User-mode only has the concept of volumes, which refers to the filesystems within those partitions. Hence, virtualization solutions rather address the entire disk and read the partition table themselves.

You can of course create a virtual disk that only refers to certain partitions so that the guest machine can only see those, but the user which runs the virtual machine will need full read access to the complete disk on the host and this may be a security issue.

Colophon

These utilities have been compiled using the Windows Driver Development Kit (DDK) and the Support Tools that accompanies the operating system. They have been tested on Windows XP Service Pack 3. No disks were hurt in the production of these utilities. The source code is written in C and VBScript, using NMake to control dependencies.

Use the bundled build.cmd script to drive the build process. If given the argument clean it will clear the build artifacts. Without any arguments, it will rebuild all outdated outputs.

The author can be reached at rlndkfmn+dskacl@gmail.com. Note however that unsolicited requests for usage support will not be answered, nor will any help be provided for recovering from unintended consequences (such as overwriting your own disk)!

Downloads

Source code can be retrieved from the following repositories:

git clone git://github.com/RolKau/dskacl.git

git clone http://kaufmann.no/repo/dskacl.git

or downloaded from the following locations:

dskacl-1_0_0-i386.cab 32-bits binaries (last update: 2012-01-18) (MD5sum: c0b22c775f609a71f4ecf0c88b7c1cfc)
dskacl-1_0_0-amd64.cab 64-bits binaries (last update: 2012-01-18) (MD5sum: 957174cc29d59a6d1e07014c588e92e0)
dskacl-1_0_0-src.cab Source code

References

StackOverflow post in which Oleg Kiriljuk shows how to enumerate devices

Updated SubInAcl utility

OSR: Inside Driver & Device Security

Understanding SDDL syntax

LockDismount utility by TheK

Windows XP Service Pack 2 Support Tools

DDK for Windows Server 2003 Service Pack 1, Build 3790.1830

Microsoft Windows™, Windows NT™ and Windows XP™ are trademarks of Microsoft Corp., VirtualBox™ is a trademark of Oracle Corp.