mrb's blog

Booting unmodified Windows 10 over USB

Keywords: registry

When I buy a laptop, the first thing I do is netboot into a PXE Linux environment and make a full raw disk image backup of the pre-installed Windows OS. I pipe dd if=/dev/sda or dd if=/dev/nvme0n1 into lz4 (much faster than gzip) and write the image on a fileserver. No matter how large the disk is, the image usually shrinks down to 20-30 GB because, well, there are usually only 20-30 GB of files on the drive. The empty NTFS blocks compress very well.

I then wipe Windows and install a Linux distribution.

Years later when I donate or sell the laptop, I restore the raw disk image. Not only does this restore the Windows OEM image, but because all sectors are overwritten, it securely wipes the disk. Very good for security.

The image backup I made turned out very useful today. I needed to update the firmware for the trackpoint of my ThinkPad X1 Carbon laptop. However the firmware update is only possible using a Windows 10 utility.

Booting from USB

Here is how I got Windows running on my laptop, without reimaging or swapping or repartitioning the internal drive.

Write the image to a USB drive

I wrote the factory Windows 10 disk image to an external USB drive (unlz4 <image.lz4 >/dev/sda). Being a full disk image, it includes 4 partitions: EFI System partition, Microsoft Reserved partition, Basic data partition, Recovery partition.

Set BootDriverFlags to 0x14

If you try to boot from the external USB drive as is, Windows 10 will error out during boot (INACCESSIBLE_BOOT_DEVICE).

The key to make it work is to edit the obscure registry value BootDriverFlags to change it from 0x0 to 0x14. The value is located under HKLM\SYSTEM\HardwareConfig\{...uuid...} and can be edited by mounting the C: partition in Linux, and using the chntpw utility:

$ chntpw -e /path/to/mounted/Windows/System32/config/SYSTEM

List the {...uuid...} subkey under HardwareConfig:

> ls HardwareConfig
Node has 1 subkeys and 2 values
  key name
  <{ca7bc4cc-350d-11b2-a85c-95cecf0de0fa}>
  size     type              value name             [value if type DWORD]
    78  1 REG_SZ             <LastConfig>
     4  4 REG_DWORD          <LastId>                   0 [0x0]

Edit BootDriverFlags with ed to set it to 0x14:

> ed HardwareConfig\{ca7bc4cc-350d-11b2-a85c-95cecf0de0fa}\BootDriverFlags
EDIT: <HardwareConfig\{ca7bc4cc-350d-11b2-a85c-95cecf0de0fa}\BootDriverFlags> of type REG_DWORD (4) with length 4 [0x4]
DWORD: Old value 0 [0x0], enter new value (prepend 0x if hex, empty to keep old value)
-> 0x14
DWORD: New value 20 [0x14], 

Finally save the changes with q:

> q

BootDriverFlags is so obscure that it is barely documented. Some online resources say the value is under HKLM\System\CurrentControlSet\Control or HKLM\SYSTEM\HardwareConfig\ but they are wrong. The value is under HKLM\SYSTEM\HardwareConfig\{...uuid...}.

That is it. Changing a single registry key is all that is needed to make an OEM Windows 10 image boot from a USB drive.

Comments