From 2dbe26c372fe102b4c77cb6a3ecfa435117a4ec3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 17 May 2011 13:16:17 +0100 Subject: virt-win-reg: Support HKEY_USERS keys. This adds support for various Registry keys under HKEY_USERS (user preferences). (1) HKEY_USERS\ where is a User SID. For example: # virt-win-reg Windows 'HKEY_USERS\S-1-5-19' lists out the LocalService user's registry. (2) HKEY_USERS\ where is a Windows local username (this is a libguestfs extension). For example: # virt-win-reg Windows 'HKEY_USERS\rjones' lists out the user preferences of user 'rjones'. HKU can be used as an abbreviation for HKEY_USERS. Merging is also supported. --- tools/virt-win-reg | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/virt-win-reg b/tools/virt-win-reg index 1018e116..333bd158 100755 --- a/tools/virt-win-reg +++ b/tools/virt-win-reg @@ -399,6 +399,52 @@ sub map_path_to_hive $path = defined $1 ? $1 : "\\"; $prefix = "HKEY_LOCAL_MACHINE\\.DEFAULT"; } + elsif (/^\\?(?:HKEY_USERS|HKU)\\(S-1-5-[-\d]+)(\\.*)?$/i) { + my $sid = $1; + $hiveshortname = $sid; + $prefix = "HKEY_USERS\\$sid"; + $path = defined $2 ? $2 : "\\"; + # This requires a recursive call to download the SOFTWARE hive. + $hivefile = lookup_pip_of_user_sid ($sid) . "/ntuser.dat"; + } + elsif (/^\\?(?:HKEY_USERS|HKU)\\LocalSystem(\\.*)?$/i) { + my $sid = "S-1-5-18"; + $hiveshortname = $sid; + $prefix = "HKEY_USERS\\$sid"; + $path = defined $1 ? $1 : "\\"; + # This requires a recursive call to download the SOFTWARE hive. + $hivefile = lookup_pip_of_user_sid ($sid) . "/ntuser.dat"; + } + elsif (/^\\?(?:HKEY_USERS|HKU)\\LocalService(\\.*)?$/i) { + my $sid = "S-1-5-19"; + $hiveshortname = $sid; + $prefix = "HKEY_USERS\\$sid"; + $path = defined $1 ? $1 : "\\"; + # This requires a recursive call to download the SOFTWARE hive. + $hivefile = lookup_pip_of_user_sid ($sid) . "/ntuser.dat"; + } + elsif (/^\\?(?:HKEY_USERS|HKU)\\NetworkService(\\.*)?$/i) { + my $sid = "S-1-5-20"; + $hiveshortname = $sid; + $prefix = "HKEY_USERS\\$sid"; + $path = defined $1 ? $1 : "\\"; + # This requires a recursive call to download the SOFTWARE hive. + $hivefile = lookup_pip_of_user_sid ($sid) . "/ntuser.dat"; + } + elsif (/^\\?(?:HKEY_USERS|HKU)\\(.*?)(\\.*)?$/i) { + $hiveshortname = "user_$1"; + $prefix = "HKEY_USERS\\$1"; + $path = defined $2 ? $2 : "\\"; + # XXX We should probably look this up properly. + if (is_dir_nocase ("/Users/$1")) { + $hivefile = "/Users/$1/ntuser.dat" + } elsif (is_dir_nocase ("/Documents and Settings/$1")) { + $hivefile = "/Documents and Settings/$1/ntuser.dat" + } else { + die __x("virt-win-reg: {p}: cannot find user directory\n", + p => $1) + } + } else { die __x("virt-win-reg: {p}: not a supported Windows Registry path\n", p => $_) @@ -407,6 +453,59 @@ sub map_path_to_hive return ($hiveshortname, $hivefile, $path, $prefix); } +# Given a User SID, consult +# HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid +# and return the ProfileImagePath value. +sub lookup_pip_of_user_sid +{ + local $_; + my $sid = shift; + + my $path = + "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\". + $sid; + + my ($hiveshortname, $hivefile, $prefix); + ($hiveshortname, $hivefile, $path, $prefix) = map_path_to_hive ($path); + + download_hive ($hivefile, $hiveshortname) + unless -f "$tmpdir/$hiveshortname"; + + my @args = ("$tmpdir/$hiveshortname", $path, "ProfileImagePath"); + warn "running hivexget ", join (" ", @args), " ..." if $debug; + + my $fh; + open $fh, "-|", "hivexget", @args + or die "hivexget: see earlier errors: $!"; + $_ = <$fh>; + close $fh or die "hivexget: see earlier errors: $!"; + + chomp; + + # The contents of the registry are a windows path, possibly + # containing %systemroot%. Expand it and remove some other + # windows-isms. The caller will do case_sensitive_path for us, so + # we don't need to do that. + s/%systemroot%/$systemroot/; + s/^c://i; + s,\\,/,g; + + $_; +} + +sub is_dir_nocase +{ + local $_; + my $dir = shift; + + my $windir; + eval { $windir = $g->case_sensitive_path ($dir); }; + if ($@) { + return 0; + } + return $g->is_dir ($windir); +} + # Download a named hive file. Die on failure. sub download_hive { @@ -456,15 +555,35 @@ sub upload_hive The program currently supports Windows NT-derived guests starting with Windows XP through to at least Windows 7. -Registry support is done for C, -C, C, -C and C. +The following Registry keys are supported: + +=over 4 + +=item C + +=item C + +=item C + +=item C + +=item C + +=item C> + +where I is a Windows User SID (eg. C). + +=item C> + +where I is a local user name (this is a libguestfs extension). + +=back You can use C as a shorthand for C, and C for C. -C and C are B supported at -this time. +The literal keys C and C are not +supported (there is no "current user"). =head1 ENCODING -- cgit