>From d5434c35de33a8f12524e4a9169d788635acefb6 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Fri, 26 Mar 2010 11:46:44 +0000 Subject: [PATCH 2/2] hivexregedit: Low-level tool for merging and export in regedit format. --- .gitignore | 2 + Makefile.am | 2 +- README | 3 + configure.ac | 1 + regedit/Makefile.am | 43 +++++++ regedit/hivexregedit | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++ regedit/run-locally | 52 +++++++++ 7 files changed, 398 insertions(+), 1 deletions(-) create mode 100644 regedit/Makefile.am create mode 100755 regedit/hivexregedit create mode 100755 regedit/run-locally diff --git a/.gitignore b/.gitignore index 997bbcf..bd99122 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ hivex-*.tar.gz html/hivex.3.html html/hivexget.1.html html/hivexml.1.html +html/hivexregedit.1.html html/hivexsh.1.html images/large images/mklarge @@ -95,6 +96,7 @@ po/remove-potcdate.sin python/*.pyc python/hivex-py.c python/hivex.py +regedit/hivexregedit.1 sh/*.1 sh/hivexsh stamp-h1 diff --git a/Makefile.am b/Makefile.am index 1a34e15..95b1dbb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ SUBDIRS += ocaml endif if HAVE_PERL -SUBDIRS += perl +SUBDIRS += perl regedit endif # Not yet written. diff --git a/README b/README index ffcbb26..ae3d159 100644 --- a/README +++ b/README @@ -92,6 +92,9 @@ python/ are welcome (please modify generator/generator.ml to add them). +regedit/ + Regedit-like registry merging tool. + sh/ Interactive shell. This also contains the old 'hivexget' diff --git a/configure.ac b/configure.ac index 11f14ea..8d24848 100644 --- a/configure.ac +++ b/configure.ac @@ -433,6 +433,7 @@ AC_CONFIG_FILES([Makefile ocaml/Makefile ocaml/META perl/Makefile perl/Makefile.PL po/Makefile.in + regedit/Makefile sh/Makefile xml/Makefile]) AC_OUTPUT diff --git a/regedit/Makefile.am b/regedit/Makefile.am new file mode 100644 index 0000000..ab286cd --- /dev/null +++ b/regedit/Makefile.am @@ -0,0 +1,43 @@ +# hivex +# Copyright (C) 2010 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +EXTRA_DIST = \ + hivexregedit \ + run-locally + +bin_SCRIPTS = hivexregedit + +man_MANS = hivexregedit.1 + +hivexregedit.1: hivexregedit + $(POD2MAN) \ + --section 1 \ + -c "Windows Registry" \ + --name "hivexregedit" \ + --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ + $< > $@-t; mv $@-t $@ + +noinst_DATA = \ + $(top_builddir)/html/hivexregedit.1.html + +$(top_builddir)/html/hivexregedit.1.html: hivexregedit + mkdir -p $(top_builddir)/html + cd $(top_builddir) && pod2html \ + --css 'pod.css' \ + --htmldir html \ + --outfile html/hivexregedit.1.html \ + regedit/hivexregedit diff --git a/regedit/hivexregedit b/regedit/hivexregedit new file mode 100755 index 0000000..0ad1352 --- /dev/null +++ b/regedit/hivexregedit @@ -0,0 +1,296 @@ +#!/usr/bin/perl -w +# Copyright (C) 2010 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +use warnings; +use strict; + +use Win::Hivex; +use Win::Hivex::Regedit qw(reg_import reg_export); + +use Pod::Usage; +use Getopt::Long; + +=encoding utf8 + +=head1 NAME + +hivexregedit - Merge and export Registry changes from regedit-format files. + +=head1 SYNOPSIS + + hivexregedit --merge [--prefix prefix] [--encoding enc] \ + hivefile [regfile] + + hivexregedit --export [--prefix prefix] hivefile key > regfile + +=head1 DESCRIPTION + +Please note hivexregedit is a low-level tool for manipulating hive +files directly. To merge or export registry changes to Windows +virtual machines it's better to use L. + +Given a local binary ("hive") file, there are two modes. C<--merge> +imports (merges) changes from a regedit-format file into the hive. It +is similar to using the C switch in Windows regedit.exe. + +C<--export> exports a Registry key (recursively) into the regedit format. + +=head2 ENCODING + +C expects that regedit files have already been reencoded +in the local encoding. Usually on Linux hosts, this means UTF-8 with +Unix-style line endings. Since Windows regedit files are often in +UTF-16LE with Windows-style line endings, you may need to reencode the +whole file before or after processing. + +To reencode a file from Windows format to Linux (before processing it +with the C<--merge> option), you would do something like this: + + iconv -f utf-16le -t utf-8 < win.reg | dos2unix > linux.reg + +To go in the opposite direction, after using C<--export> and before +sending the file to a Windows user, do something like this: + + unix2dos linux.reg | iconv -f utf-8 -t utf-16le > win.reg + +For more information about encoding, see L. + +If you are unsure about the current encoding, use the L +command. Recent versions of Windows regedit.exe produce a UTF-16LE +file with Windows-style (CRLF) line endings, like this: + + $ file software.reg + software.reg: Little-endian UTF-16 Unicode text, with very long lines, + with CRLF line terminators + +This file would need conversion before you could C<--merge> it. + +=head2 SHELL QUOTING + +Be careful when passing parameters containing C<\> (backslash) in the +shell. Usually you will have to use 'single quotes' or double +backslashes (but not both) to protect them from the shell. + +=head2 CurrentControlSet etc. + +Registry keys like C don't really exist in the +Windows Registry at the level of the hive file, and therefore you +cannot modify these. Replace this with C, and +similarly for other C keys. + +=head1 EXAMPLE + + $ virt-cat WindowsGuest /Windows/System32/config/software > software.hive + $ hivexregedit --export \ + --prefix 'HKEY_LOCAL_MACHINE\SOFTWARE' \ + software.hive '\Microsoft' > ms-keys.reg + + $ hivexregedit --merge system.hive \ + --prefix 'HKEY_LOCAL_MACHINE\SYSTEM' additions.reg + +=head1 OPTIONS + +=over 4 + +=cut + +my $help; + +=item B<--help> + +Display help. + +=cut + +my $debug; + +=item B<--debug> + +Enable debugging in the hivex library. This is useful for diagnosing +bugs and also malformed hive files. + +=cut + +my $merge; + +=item B<--merge> + + hivexregedit --merge [--prefix prefix] [--encoding enc] \ + hivefile [regfile] + +Merge C (a regedit-format text file) into the hive +C. If C is omitted, then the program reads from +standard input. (Also you can give multiple input files). + +C<--prefix> specifies the Windows Registry prefix. It is almost +always necessary to use this when dealing with real hive files. + +C<--encoding> specifies the encoding for unmarked strings in the +input. It defaults to C which should work for recent +versions of Windows. Another possibility is to use C. + +=cut + +my $export; + +=item B<--export> + + hivexregedit --export [--prefix prefix] hivefile key > regfile + +C is a path within the hive C. (The key should not +contain any prefix and should be quoted to defend backslashes from the +shell). The key is exported, recursively, to standard output in the +textual regedit format. + +C<--prefix> specifies the Windows Registry prefix. It is almost +always necessary to use this when dealing with real hive files. + +=cut + +my $prefix; + +=item B<--prefix> prefix + +Hive files and Windows Registry key names are indirectly related. For +example, inside the software hive, all keys are stored relative to +C. Thus +C appears in the hive file as +C<\Microsoft>. + +The hive format itself does not store this prefix, so you have to +supply it based on outside knowledge. (L, amongst +other things, already knows about this). + +Usually it is sufficient to pass the parameter +C<--prefix 'HKEY_LOCAL_MACHINE\SOFTWARE'> or similar when doing +merges and exports. + +=cut + +my $encoding; + +=item B<--encoding> UTF-16LE|ASCII + +When merging (only), you may need to specify the encoding for strings +to be used in the hive file. This is explained in detail in +L. + +The default is to use UTF-16LE, which should work with recent versions +of Windows. + +=back + +=cut + +GetOptions ("help|?" => \$help, + "debug" => \$debug, + "merge|import" => \$merge, + "export" => \$export, + "prefix=s" => \$prefix, + "encoding=s" => \$encoding, + ) or pod2usage (2); +pod2usage (1) if $help; + +if ($merge && $export) { + die "hivexregedit: cannot use --merge and --export at the same time\n" +} + +unless ($merge || $export) { + die "hivexregedit: use --merge or --export, see the manpage for help\n" +} + +if ($export && defined $encoding) { + die "hivexregedit: --encoding has no effect when used with --export\n" +} + +if ($merge) { # --merge (reg_import) + if (@ARGV < 1) { + die "hivexregedit --merge hivefile [input.reg ...]\n" + } + + my $hivefile = shift @ARGV; + + my $h = Win::Hivex->open ($hivefile, write => 1, debug => $debug); + + # Read from stdin unless other files have been specified. + unshift (@ARGV, '-') unless @ARGV; + + foreach (@ARGV) { + open FILE, $_ or die "$_: $!"; + reg_import (\*FILE, sub { + local $_ = shift; + # Remove prefix from the start of the path, matching + # case insensitively. + if (defined $prefix) { + my $len = length $prefix; + if (length $_ >= $len && + lc (substr ($_, 0, $len)) eq lc ($prefix)) { + $_ = substr ($_, $len); + } + } + ($h, $_) + }); + } + + $h->commit (undef); +} else { # --export (reg_export) + if (@ARGV != 2) { + die "hivexregedit --export hivefile key\n" + } + + my $hivefile = shift @ARGV; + my $key = shift @ARGV; + + my $h = Win::Hivex->open ($hivefile, debug => $debug); + + print "Windows Registry Editor Version 5.00\n\n"; + + reg_export ($h, $key, \*STDOUT, prefix => $prefix); +} + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, +L. + +=head1 AUTHOR + +Richard W.M. Jones L + +=head1 COPYRIGHT + +Copyright (C) 2010 Red Hat Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/regedit/run-locally b/regedit/run-locally new file mode 100755 index 0000000..9d9cca9 --- /dev/null +++ b/regedit/run-locally @@ -0,0 +1,52 @@ +#!/usr/bin/perl +# Copyright (C) 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# This script sets up the environment so you can run hivexregedit in +# place without needing to do 'make install' first. +# +# Use it like this: +# ./run-locally [usual hivexregedit args ...] +# eg: +# ./run-locally --export software.hive '\Microsoft' + +use strict; +use warnings; + +use File::Basename qw(dirname); +use File::Spec; +use Cwd qw(abs_path); + +my $path = $0; + +# Follow symlinks until we get to the real file +while(-l $path) { + my $link = readlink($path) or die "readlink: $path: $!"; + if(File::Spec->file_name_is_absolute($link)) { + $path = $link; + } else { + $path = File::Spec->catfile(dirname($path), $link); + } +} + +# Get the absolute path of the parent directory +$path = abs_path(dirname($path).'/..'); + +$ENV{LD_LIBRARY_PATH} = $path.'/lib/.libs'; +$ENV{PERL5LIB} = $path.'/perl/blib/lib:'.$path.'/perl/blib/arch'; + +#print (join " ", ("$path/regedit/hivexregedit", @ARGV), "\n"); +exec('perl', "$path/regedit/hivexregedit", @ARGV); -- 1.6.6.1