When triaging a live system or performing live forensic acquisition, we often need to copy registry hives from a disk. Currently, there are five common ways to do this:
- execute the “reg save <hive> <file>” command;
- call the RegSaveKeyEx/RegSaveKey routine from an acquisition tool;
- copy a hive file from an existing shadow copy;
- copy a hive file from a newly created shadow copy;
- directly read a hive file from an NTFS volume.
Are there any pros and cons of each way?
reg save <hive> <file>
Running this command is recommended in different sources, many DFIR practitioners and pentesters use it to grab registry hives from a live system. This command, however, is unable to export application hives.
If the root of a hive is given (e.g., HKLM\System), the reg tool calls the RegSaveKeyEx routine with the last argument set to REG_NO_COMPRESSION. Otherwise, the tool calls the RegSaveKey routine.
A Windows 10 version of the tool has an undocumented “/c” argument: when specified, the tool exports the hive using the RegSaveKeyEx routine with the last argument set to REG_LATEST_FORMAT. (Besides that, the tool operates as described.)
(And their Native API counterparts: NtSaveKeyEx/NtSaveKey.)
The first routine, RegSaveKeyEx, exports a given registry hive using one of these modes (as specified by the last argument to that routine):
- REG_STANDARD_FORMAT: the hive is exported using the “standard” format (the hive format version used is 1.3);
- REG_LATEST_FORMAT: the hive is exported using the “latest” format (the hive format version used is 1.5 <1>);
- REG_NO_COMPRESSION: the hive is exported as is (by copying its hive file <2> and including current in-memory modifications, if any).
<1> — actually, this is not the latest format version; the latest one is 1.6 (introduced in Windows 10);
<2> — a primary file.
The second routine, RegSaveKey, performs the same things as the first routine when its last argument is set to REG_STANDARD_FORMAT.
It’s also possible to export an application hive by first loading it using the RegLoadAppKey routine and then calling the RegSaveKeyEx routine (access to the hive file is required).
The REG_STANDARD_FORMAT and REG_LATEST_FORMAT arguments are suitable for exporting a registry tree under a given non-root key (a root key is fine too). With one of these arguments, a temporary hive is created and the registry tree (under a given key of a source hive) is copied to that hive. This temporary hive is then saved to a specified file.
The REG_NO_COMPRESSION argument deals with root keys only. In this case, a source hive (which is specified by its root key) is saved into a specified external file, as is. This will include most data from a hive file (see below) and in-memory data (not yet flushed to a disk).
When the root of a containerized hive is given, the kernel creates a temporary hive and copies a merged view into that hive; then this temporary hive is saved using the format version 1.5. This happens when trying to export a registry hive from inside of a container.
When the REG_STANDARD_FORMAT and REG_LATEST_FORMAT arguments are used, no deleted registry data is preserved in an exported file, because only allocated keys and values are copied into a temporary hive during the export.
(“No compression” means that registry data isn’t stored compactly. Two other options “compress” or, using a better term, defragment registry data by excluding unallocated space.)
When the REG_NO_COMPRESSION argument is used, most deleted registry data is preserved in an exported file with two exceptions.
First, data beyond the last hive bin isn’t written to an exported file. In my tests, this means that approximately 0.6% of recoverable deleted keys and values aren’t exported (but this type of deleted data remains in an original hive file, it’s not purged during the export).
Two files shown above have the same header but have different sizes:
$ du -b rs-soft.hive ftk-software
So, the hive file exported using the reg tool is smaller, because it doesn’t include remnant data after the last hive bin. (Another hive file, which was exported using a different method, includes such remnant data.)
Second, when exporting a containerized hive, no deleted registry data is preserved in an exported hive (because of a temporary hive used to store a merged view during the export).
It should be noted that layered keys metadata is absent in the exported hive too. In this case, it’s essential to export (using another method) both the base hive and the delta hive, since modifications made to registry keys and values found in the base hive are explicitly stated in the delta hive.
Shadow copies provide an easy way to access locked files. Reading a hive file from an existing shadow copy is less invasive, but it’s likely to produce out-of-date data. If you create a new shadow copy to obtain current data, you leave a large footprint (also, an old shadow copy can be deleted to free some disk space). And if you delete a newly created shadow copy, it’s not necessary removed (although some DFIR tools ignore offline shadow copies).
Since shadow copies are used for backups, they need to include consistent data. To achieve this, writers freeze and thaw data before and after the creation of a shadow copy.
For example, when you create a shadow copy, the Windows kernel freezes all registry hives and then allows the shadow copy service to proceed. The kernel thaws registry hives after a shadow copy being created is ready.
When registry hives are frozen, no changes to their files are allowed on a disk (“all write operations to the disk are stopped and that files are in a well-defined state for backup“). During the freeze operation, transaction log files are applied to corresponding hive files. Then, an applied transaction log file can be emptied.
Thus, the creation of a shadow copy often results in registry data being removed from transaction log files. Also, some registry data can be overwritten in hive files when transaction log files are applied.
Since transaction log files can hold updates to registry data up to an hour (by default), this effect should be considered during live response: this means that an examiner would only see the “after” state of a registry hive (with transaction logs applied), the “before” state (without transaction logs applied) will be lost.
Also, transaction log files may contain remnant log entries with old registry data. This data is lost when a transaction log file is emptied.
Reading locked files from a logical or physical volume using an NTFS parser like FTK Imager Lite and RawCopy is another way and it seems to be the least invasive. However, this isn’t always the case when reading from a logical drive, the NTFS driver can (and, actually, will) flush pending changes to file system metadata (like in-memory updates to last access timestamps).
So, when integrity of current NTFS metadata is important, tools should be used against a physical drive (like “\\.\PhysicalDrive0”), not a logical one (like “\\.\C:”). Obviously, reading a physical drive won’t work if software-based volume encryption is present.
A tool can capture a hive file in the middle of its update (when something is written to its clusters and the whole set of write operations hasn’t completed yet, this is exactly why there are freeze and thaw operations for shadow copies).
In Windows 8.1 and 10, updates to hive files are less frequent (by default, usually once in an hour) and registry data in transaction log files is checksummed, so the risk of capturing a hive file containing invalid data is lower and a transaction log file with some invalid blocks of registry data can be processed properly.