Tag Archives: virt-win-reg

Tip: Enable minidumps in a Windows guest

You can use virt-win-reg to enable minidumps in Windows guests. Quite easily as it happens.

First prepare a file crashcontrol.reg containing:

; NB: This assumes CurrentControlSet == ControlSet001
; See "CurrentControlSet etc." in virt-win-reg(1)

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CrashControl]
"AutoReboot"=dword:00000000
"CrashDumpEnabled"=dword:00000003
"DumpFile"=str(2):"%SystemRoot%\MEMORY.DMP"
"LogEvent"=dword:00000001
"MinidumpDir"=str(2):"%SystemRoot%\Minidump"
"MinidumpsCount"=dword:00000032
"Overwrite"=dword:00000001

The key fields are AutoReboot, which you probably want to set to 0 to stop the guest from automatically rebooting when it gets a BSOD, and CrashDumpEnabled for which you can read the docs here.

Then import this into the guest (which must not be running):

$ virt-win-reg --merge GuestName crashcontrol.reg

Leave a comment

Filed under Uncategorized

New in libguestfs 1.12: HKEY_USERS in virt-win-reg

In this series of posts I’ll be looking at what’s new in the forthcoming release of libguestfs 1.12.

In 1.12 you will be able to use virt-win-reg to list out and update Windows user preferences stored in HKEY_USERS keys.

There are two ways to use this. You can either specify a User SID like:

virt-win-reg Windows 'HKEY_USERS\S-1-5-19\Software\Policies'

or (as a libguestfs extension) you can specify a local user name directly:

virt-win-reg Windows 'HKEY_USERS\rjones\Control Panel'

Leave a comment

Filed under Uncategorized

Tip: Using a backing file to record file and registry changes, addendum

Part 1, part 2, and part 3

Inspired by the tricky and slow method to pull out file metadata that I showed in part 2 I added some features to virt-ls to make this much easier. These features are not yet in virt-ls. You will either have to apply this patch series or wait for libguestfs ≥ 1.11.9.

With the forthcoming virt-ls -lR option you will be able to extract the file metadata from a virtual machine easily. The output format is designed so that simple grep patterns can be used to detect interesting things in the output.

For example to display the names of all setuid and setgid files in the VM:

# virt-ls -lR -d guest / | grep '^- [42]'
- 4755      12544 /bin/cgexec -
- 4755      32448 /bin/fusermount -
- 4755      78648 /bin/mount -
- 4755      43160 /bin/ping -
- 4755      47888 /bin/ping6 -
- 4755      34904 /bin/su -
- 4755      50432 /bin/umount -
[...]

To display all public writable directories:

# virt-ls -lR -d guest / | grep '^d ...7'
d 1777      12288 /tmp -
d 1777       4096 /tmp/.ICE-unix -
d 1777       4096 /tmp/.X11-unix -
d 1777       4096 /var/tmp -

To display files larger than 10MB in home directories:

# virt-ls -lR -d guest /home | awk '$3 >= 10*1024*1024'

Find regular files modified in the last 24 hours:

# virt-ls -lR -d guest --time-days / |
    grep '^-' |
    awk '$6 < 1'
[...]
- 0600        138   0   0   0 /home/rjones/.Xauthority
- 0600         69   0   0   0 /root/.xauthsdYvWC
- 0444         11   0   0   0 /tmp/.X0-lock
[...]

Also filesystem comparisons are made much simpler. So to display changes in files between a snapshot and the latest version of a VM you would simply do:

# virt-ls -lR -a snapshot.img / --uids --time-t --checksum > old
# virt-ls -lR -a current.img / --uids --time-t --checksum > new
# diff -u old new | less

2 Comments

Filed under Uncategorized

Tip: Using a backing file to record file and registry changes, part 3

In the first part I showed you that you can use libguestfs directly on QEMU snapshots and backing files, and this can be used to forensically look at changes made to virtual machines, eg. by installing new software. In the second part yesterday I showed you how to look for files that have changed.

Today we’ll look at differences in the Windows registry.

Although the Windows registry is stored in hive files, because these files are complex binary structures it makes sense to examine them at a higher level using a library like hivex, or the high level tool I wrote virt-win-reg.

Using virt-win-reg we can examine each hive that virt-win-reg supports separately, and use “diff” to list differences:

$ virt-win-reg backing.qcow2 'HKLM\SYSTEM' > system.without-chrome
$ virt-win-reg win7.qcow2 'HKLM\SYSTEM' > system.with-chrome
$ virt-win-reg backing.qcow2 'HKLM\SOFTWARE' > software.without-chrome
$ virt-win-reg win7.qcow2 'HKLM\SOFTWARE' > software.with-chrome

There were no significant changes to the HKEY_LOCAL_MACHINE\SYSTEM hive, but Chrome made many additions to the SOFTWARE hive, for example:

+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ChromeHTML]
+@=str(1):"Chrome HTML Document"
+"URL Protocol"=str(1):""
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ChromeHTML\DefaultIcon]
+@=str(1):"C:\Users\rjones\AppData\Local\Google\Chrome\Application\chrome.exe,0"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ChromeHTML\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ChromeHTML\shell\open]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ChromeHTML\shell\open\command]
+@=str(1):"\"C:\Users\rjones\AppData\Local\Google\Chrome\Application\chrome.exe\" -- \"%1\""

Note that you can make the output more readable by using the --unsafe-printable-strings option (but note that it’s called “unsafe” for a reason).

Chrome appears to have modified the list of CA certificates — should I be worried?

There is an addendum to this coming tomorrow morning.

2 Comments

Filed under Uncategorized

Tip: Using a backing file to record file and registry changes, part 2

In the first part I showed you that you can use libguestfs directly on QEMU snapshots and backing files, and this can be used to forensically look at changes made to virtual machines, eg. by installing new software.

Given the backing file and changes from yesterday, we can also look at differences in file content and permissions on files — in other words, what existing files did the Google Chrome installer change in the Windows guest?

A simple and easy way to do this is to instruct guestfish to export the whole filesystem as a tarball, which we’ll use on the host to compare file permissions and sizes:

$ guestfish --ro -i -a backing.qcow2 tar-out / - |
    tar tvvf - | sort -k6 > files.without-chrome
$ guestfish --ro -i -a win7.qcow2 tar-out / - |
    tar tvvf - | sort -k6 > files.with-chrome
$ diff -u files.without-chrome files.with-chrome | less
[... 1,677 lines of output ...]
--rwxrwxrwx root/root    1157779 2011-06-02 11:06 ./Windows/WindowsUpdate.log
+-rwxrwxrwx root/root    1221259 2011-06-03 10:04 ./Windows/WindowsUpdate.log

What did I find out? As well as adding its own files to AppData/Local, Chrome also made changes to all of the registry hives, and as a result of installing new files, many internal Windows indexes were updated.

This technique will miss several changes which might be important to you: it will miss files that have had their content changed, but the file size and modification date didn’t change. And it will omit changes to extended attributes such as file forks, NT symbolic links and so on. If you want to list those changes too, you have to get down and dirty in the libguestfs API. This posting would be a good place to start.

Tomorrow we’ll look at changes in the Windows registry.

Leave a comment

Filed under Uncategorized

Tip: Using a backing file to record file and registry changes, part 1

Gary asked if it is possible to examine a KVM snapshot or backing file and perhaps list out the files and so on that had changed between the backing file and the current image.

It’s possible to use libguestfs to examine the changes, and in this three part series I’ll show you how.

I want to examine the file and Windows registry changes that happen when I install Google Chrome for Windows.

I first set up a Windows guest with a backing file, and I made sure the backing file was committed just before Chrome was downloaded and installed:

$ ll win7.qcow2 backing.qcow2 
-rw-r--r--. 1 qemu qemu 10099228672 Jun  3 10:40 backing.qcow2
-rw-r--r--. 1 root root    60555264 Jun  3 10:40 win7.qcow2

Then I installed Chrome in the guest, and as you can see the win7.qcow2 file (containing just changes) is much larger while the backing file has stayed the same:

$ ll win7.qcow2 backing.qcow2 
-rw-r--r--. 1 qemu qemu 10099228672 Jun  3 10:40 backing.qcow2
-rw-r--r--. 1 root root   682164224 Jun  3 11:08 win7.qcow2

Getting a list of files that have been added or removed by installing Chrome is easy. Note that this does not show files that have been modified (we’ll get to that in the next part). Note #2 because of a bug in WordPress, you have to type “backslash zero” where it says “NUL” below.

$ guestfish --ro -i -a win7.qcow2 find0 / - |
    tr 'NUL' '\n' | sort > files.with-chrome
$ guestfish --ro -i -a backing.qcow2 find0 / - |
    tr 'NUL' '\n' | sort > files.without-chrome
$ diff -u files.without-chrome files.with-chrome |
    less
[...]
+Users/rjones/AppData/Local/Google
+Users/rjones/AppData/Local/Google/Chrome
+Users/rjones/AppData/Local/Google/Chrome/Application
+Users/rjones/AppData/Local/Google/Chrome/Application/11.0.696.71
+Users/rjones/AppData/Local/Google/Chrome/Application/11.0.696.71/avcodec-52.dll
[...]
 Users/rjones/Desktop
 Users/rjones/Desktop/desktop.ini
+Users/rjones/Desktop/Google Chrome.lnk
 Users/rjones/Documents
 Users/rjones/Documents/desktop.ini

Google Chrome doesn’t (or can’t?) install anything under Program Files, instead preferring to install itself completely within AppData/Local in the user’s home directory.

In the next part I’ll show you how to find out when file contents, size or permissions have changed, and in the third part, we’ll look at Windows registry changes.

Leave a comment

Filed under Uncategorized

virt-win-reg can now read and write HKEY_USERS (Windows user preferences)

In libguestfs 1.11.7 (and some further patches in git) ≥ 1.11.8 you can now use virt-win-reg to list out and update Windows user preferences stored in HKEY_USERS keys.

There are two ways to use this. You can either specify a User SID like:

virt-win-reg Windows 'HKEY_USERS\S-1-5-19\Software\Policies'

or (as a libguestfs extension) you can specify a local user name directly:

virt-win-reg Windows 'HKEY_USERS\rjones\Control Panel'

Leave a comment

Filed under Uncategorized

Tip: Change the background image in a Windows VM

Thanks to Tom Horsley who worked out how to do this for Windows XP guests (the technique is probably different for other versions of Windows).

Here is Tom’s script and here are more of his KVM tips.

2 Comments

Filed under Uncategorized

Tip: Another way to get the IP address of a virtual machine

In this earlier post several ways were discussed of getting the IP address of a virtual machine (specifically if the VM is acquiring a different address each time from DHCP).

Another way is to use virt-cat or virt-win-reg to grab the information out of the virtual machine itself.

When a VM acquires an IP address from DHCP then it writes the address to a log file, or in the Windows case updates the Windows Registry. The idea is simply that we’ll read the information from the VM’s log files or the Registry.

The details vary depending on the precise guest type, and probably we should wrap this up in a nice virt tool. But here’s how you would do it for Fedora/RHEL and Windows guests:

# virt-cat RHEL60x64 /var/log/messages | grep 'dhclient.*bound to'
Mar 30 19:56:22 rhel60x64 dhclient: bound to 192.168.122.220 -- renewal in 1527 seconds.
Mar 30 20:21:49 rhel60x64 dhclient: bound to 192.168.122.220 -- renewal in 1375 seconds.
Mar 30 20:44:44 rhel60x64 dhclient: bound to 192.168.122.220 -- renewal in 1287 seconds.
Mar 30 21:06:11 rhel60x64 dhclient: bound to 192.168.122.220 -- renewal in 1461 seconds.
# virt-win-reg Win7x32 \
  'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters' | \
  grep DhcpIPAddress
"DhcpIPAddress"=hex(1):31,00,39,00,32,00,2e,00,31,00,36,00,38,00,2e,00,31,00,32,00,32,00,2e,00,31,00,37,00,38,00,00,00

In the Windows case you need to note that ControlSet001 isn’t always the right control set — consult this note in the virt-win-reg man page to find the correct way to do this. Furthermore virt-win-reg prints out the hex-encoded UTF16-LE string, which requires a little bit of conversion to produce a printable string (192.168.122.178 in this instance).

Update: To add to all the other methods from the previous post, and the method described above, Eric Blake also points out that nwfilter can sniff IP addresses used by VMs.

2 Comments

Filed under Uncategorized

Tip: Updating the Windows registry using libguestfs and hivex

virt-win-reg is a high level tool for merging Registry changes into a Windows virtual machine, and it’s relatively simple to use. You can also do the same thing using the libguestfs and hivex APIs directly, but it’s a little bit more complicated. This posting explains how to do it the low-level way.

First understand how the Windows Registry is stored in a VM: Although in Windows it appears as a single tree with top level nodes called things like HKEY_LOCAL_MACHINE and HKEY_USERS, this is not how Windows actually stores it. The Registry is split across several files called hives. Hivex is a C library for editing this proprietary file format.

A hive file contains a part of the Registry tree. The main hives of interest are called SOFTWARE, SYSTEM, SECURITY and SAM (without any file extension) and they live in the %systemroot%\System32\Config directory. These hives correspond to HKEY_LOCAL_MACHINE\SOFTWARE, HKEY_LOCAL_MACHINE\SYSTEM etc. There are also per-user hives stored in a location that depends on the version of Windows.

Another thing to understand about the Registry is that when Windows is running it synthesizes “symbolic keys” which don’t really exist in the hive file itself. The most important example is CurrentControlSet which is really a link to ControlSetXXX as explained in more detail here.

The plan for modifying a Windows Registry in an offline guest is therefore:

  1. Locate the hive file containing the key we want to modify.
  2. Download it to a local temporary directory.
  3. Modify it with hivex.
  4. Upload it back to the Windows VM.

(This is essentially what virt-win-reg does).

Below is a Python program which demonstrates how to change the hostname of a Windows VM using the APIs directly. The hostname is stored in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters in the key Hostname. Notice from the name that this is located in the SYSTEM hive file, and in this case I’m going to assume that CurrentControlSet is a link to ControlSet001 but in reality you’d probably want to read this and do it right.

A final note: Although this changes the Hostname registry key correctly, Windows doesn’t use this key for very much (in particular, this is not the name of the machine), and also it appears that Windows will overwrite this key with whatever name it gets from a DHCP server. It’s only an example though …

#!/usr/bin/python

import guestfs
import hivex

windows_domain = "Win7x32"

# Windows strings stored in the registry have a trailing NUL
new_hostname = "win7x32\0"

# Use libguestfs to download the HKEY_LOCAL_MACHINE\SYSTEM hive.
g = guestfs.GuestFS ()
g.add_domain (windows_domain)
g.launch ()

roots = g.inspect_os ()
root = roots[0]
g.mount_options ("", root, "/")

systemroot = g.inspect_get_windows_systemroot (root)
path = "%s/system32/config/system" % systemroot
path = g.case_sensitive_path (path)
g.download (path, "/tmp/system")

# Open the hive file for writing.
h = hivex.Hivex ("/tmp/system", write=True)

# Navigate down to the TCP/IP parameters.
key = h.root ()
key = h.node_get_child (key, "ControlSet001")
key = h.node_get_child (key, "Services")
key = h.node_get_child (key, "Tcpip")
key = h.node_get_child (key, "Parameters")

# Get the old hostname.
val = h.node_get_value (key, "Hostname")
old_hostname = h.value_value (val)

# Keep the old type (probably 1 = string)
type = old_hostname[0]

# The registry key is encoded as UTF-16LE.
old_hostname = old_hostname[1].decode ('utf-16le').encode ('utf-8')

print "old hostname = %s" % old_hostname

# Change the hostname.
new_hostname = new_hostname.encode ('utf-16le')
new_value = { 'key': "Hostname", 't': type,
              'value': new_hostname }
h.node_set_value (key, new_value)

# Commit the changes to the hive.
h.commit (None)

# Upload the hive back to the guest.
g.upload ("/tmp/system", path)

# This is only needed for libguestfs < 1.5.24, but
# it won't hurt for newer versions.
g.sync ()

Leave a comment

Filed under Uncategorized