1

I was unfortunate enough to have my disk failing, AND for the failure to be exactly at the Windows registry file; eventually I got the Windows recovery to fail with:

Your PC/Device needs to be repaired
The operating system couldn't be loaded because the system registry file is missing or contains errors
File: \WINDOWS\system32\config\system
Error code: 0xc0000225

I have realized that at least \Windows\System32\config\SYSTEM and \Windows\System32\config\SOFTWARE are only 8 kB in size on the corrupt disk - and of course, Windows Recovery cannot help with this.

So, I cloned the failed drive, and then used Photorec to recover all recoverable files; and then I used the approach in grep beginning of file? to find all files that start with regf, which would make them candidates for Windows Registry hives:

find . -type f | while read file; do [[ "$(head -1 "$file" | tr -d '\0')" =~ ^regf ]] && ls -la "$file"; done > find_regf.txt

So I ended up with some 200+ files that are candidates for Windows Registry hives, but they are all named ./recup_dir.2/f0093640.reg, ./recup_dir.4/f0238192.reg and so on (a bit unfortunate naming, since .reg files are typically ASCII, and the hive files are binary, but OK).

So now I do not know which of those might be SYSTEM, SAM etc hives; from How to read Registry entries from disk archive? it seems these are the basic Windows Registry hive files:

Registry hive                 Supporting files
HKEY_LOCAL_MACHINE\SAM        Sam, Sam.log, Sam.sav
HKEY_LOCAL_MACHINE\Security   Security, Security.log, Security.sav
HKEY_LOCAL_MACHINE\Software   Software, Software.log, Software.sav
HKEY_LOCAL_MACHINE\System     System, System.alt, System.log, System.sav
HKEY_CURRENT_CONFIG           System, System.alt, System.log, System.sav, Ntuser.dat, Ntuser.dat.log
HKEY_USERS\DEFAULT            Default, Default.log, Default.sav

So, is there some sort of a binary signature, or a specific key or value, I could search for, to tell me if what kind of a Windows Registry file a given *.reg file is?

sdbbs
  • 1,692

1 Answers1

1

Well, apparently for the question as posed:

So, is there some sort of a binary signature, or a specific key or value,

... the answer is yes - though I still could not tell you in what way it is encoded in these files.

I went in a somewhat roundabout way: I realized there is a Python application https://github.com/andyjsmith/Registry-Spy which could open my recovered files, and for an opened file it prints (hive) Type, Hive Name, and (hive) Root Name. I realized the application was using the python-registry library, and so I whipped up a script that goes through the list with the find results in ls -la format, opens those files using python-registry, and it extracts info, and outputs some of the settings for a file; in the end. Here is the script

#!/usr/bin/env python3

import sys, os import time import datetime from Registry import Registry # pip3 install python-registry

""" LSLA_FILE_LIST expects txt lines in format of ls -la:

-rw-r--r-- 1 user user 16384 2025-03-08 10:18 ./recup_dir.2/f0093640.reg

So from 8th field onwards, the line is considered to contain a relative file path. Set DIR_PREFIX to turn it into an absolute file path. """

LSLA_FILE_LIST = "" DIR_PREFIX = ""

if not(LSLA_FILE_LIST) or not(DIR_PREFIX): print("Please set LSLA_FILE_LIST and DIR_PREFIX inside script; exiting") sys.exit(1)

class FileInfo(object): path = "" size = 0 mtime = 0 hive_type = "" hive_name = "" hive_root_name = "" hive_root_ts = None hive_root_ns = 0 # num subkeys

def str(self): file_time = datetime.datetime.fromtimestamp(self.mtime) return "size: {:10d} mtime: {} hrts {} ht: {} hn: {} hrn: {} hrns: {} path: {}".format( self.size, file_time.strftime("%Y/%m/%d, %H:%M:%S"), self.hive_root_ts if type(self.hive_root_ts) == str else self.hive_root_ts.strftime("%Y-%m-%d %H:%M:%S"), self.hive_type, self.hive_name, self.hive_root_name, self.hive_root_ns, self.path )

all_files = [] found_htypes = []

with open(LSLA_FILE_LIST) as lfile: for il, line in enumerate(lfile): line_parts = line.split() filename = " ".join(line_parts[7:]) filepath = os.path.normpath( os.path.join(DIR_PREFIX, filename) ) tfinf = FileInfo() tfinf.path = filepath tfinf.mtime = os.path.getmtime(filepath) # local_time = time.ctime(modification_time) tfinf.size = os.path.getsize(filepath) try: reg = Registry.Registry(filepath) #except (Registry.RegistryParse.ParseException, struct.error): except Exception as ex: tfinf.hive_type = "Unable to parse registry file " + str(ex); print(tfinf) continue tfinf.hive_type = "" + reg.hive_type().name try: tfinf.hive_root_ts = reg.root().timestamp() except Exception as ex: tfinf.hive_root_ts = "root ts " + str(ex) print(tfinf) continue tfinf.hive_root_ns = "" + str(reg.root().subkeys_number()) tfinf.hive_name = "" + reg.hive_name() tfinf.hive_root_name = "" + reg.root().name() typestr = "{} | {} | {}".format( tfinf.hive_type, tfinf.hive_name, "GUID" if tfinf.hive_root_name.startswith("{") else tfinf.hive_root_name ) found_type = -1 for ifh, fht in enumerate(found_htypes): if fht[0] == typestr: found_type = ifh fht[1] += 1 break if (found_type < 0): found_htypes.append([typestr, 1]) print(tfinf) #if il == 5: sys.exit(0)

print("Found hive types:") found_htypes = sorted(found_htypes, key = lambda x: x[0]) for ifh, fht in enumerate(found_htypes): print("{} ({})".format(fht[0], fht[1]))

The script outputs lines like this:

size:      73728 mtime: 2012/05/22, 02:00:19 hrts 2012-05-22 00:00:08 ht: SETTINGS hn: yb3d8bbwe\Settings\settings.dat hrn: Test hrns: 2 path: /path/to/photorec/recup_dir.2/f0116608.reg
size:      28672 mtime: 1901/12/13, 21:45:52 hrts 2021-05-18 12:59:36 ht: UNKNOWN hn:  hrn: ROOT hrns: 1 path: /path/to/photorec/recup_dir.2/f0075680.reg
size:      65536 mtime: 1901/12/13, 21:45:52 hrts 2021-04-17 06:03:11 ht: SAM hn: \SystemRoot\System32\Config\SAM hrn: ROOT hrns: 1 path: /path/to/photorec/recup_dir.32/f1933896.reg
size:   83886080 mtime: 1901/12/13, 21:45:52 hrts 2025-02-28 11:56:38 ht: SOFTWARE hn: emRoot\System32\Config\SOFTWARE hrn: ROOT hrns: 52 path: /path/to/photorec/recup_dir.344/f72283592.reg

At the end, it prints a summary of found hive types; there's a whole bunch of these (number in parentheses is the number of files that match):

UNKNOWN | c\SystemAppData\Helium\User.dat | Silodb330144-eaac-8292-419e-f8ca87a38583user_sid (1)
UNKNOWN | e\SystemAppData\Helium\User.dat | Silo5cc0cfe1-1780-6d74-419e-f8ca87a38583user_sid (1)
UNKNOWN | e\SystemAppData\Helium\User.dat | Silo797281b0-d1c3-247b-419e-f8ca87a38583user_sid (1)

... also these:

UNKNOWN | ekyb3d8bbwe\ActivationStore.dat | GUID (90)

... but ultinately it also found:

COMPONENTS | DOWS\System32\config\COMPONENTS | ROOT (1)
DEFAULT | temRoot\System32\Config\DEFAULT | ROOT (1)
NTUSER | files\NetworkService\NTUSER.DAT | ROOT (1) # several at different paths
SAM | \SystemRoot\System32\Config\SAM | ROOT (1)
SCHEMA | 32\SMI\Store\Machine\SCHEMA.DAT | ROOT (1)
SOFTWARE | emRoot\System32\Config\SOFTWARE | ROOT (1)
SYSTEM | SYSTEM | ROOT (1)
SYSTEM | \WINDOWS\System32\config\SYSTEM | $OFFLINE$SYSTEM (1)
USRCLASS | \Microsoft\Windows\UsrClass.dat | S-1-5-21-2898377688-1115364924-2527857830-1001_Classes (1)

... which look like something Windows may have used directly recently, and might warrant looking into.

sdbbs
  • 1,692