public AmcacheOld(string hive, bool recoverDeleted, bool noLogs) { _logger = LogManager.GetLogger("AmcacheOld"); RegistryHive reg; var dirname = Path.GetDirectoryName(hive); var hiveBase = Path.GetFileName(hive); List <RawCopy.RawCopyReturn> rawFiles = null; try { reg = new RegistryHive(hive) { RecoverDeleted = true }; } catch (IOException) { //file is in use if (RawCopy.Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } _logger.Warn($"'{hive}' is in use. Rerouting...\r\n"); var files = new List <string>(); files.Add(hive); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = RawCopy.Helper.GetFiles(files); var b = new byte[rawFiles.First().FileStream.Length]; rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length); reg = new RegistryHive(b, rawFiles.First().InputFilename); } if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); var log = LogManager.GetCurrentClassLogger(); if (logFiles.Length == 0) { if (noLogs == false) { log.Warn("Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception("Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } else { log.Warn("Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } } else { if (noLogs == false) { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var b = new byte[rawCopyReturn.FileStream.Length]; rawCopyReturn.FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length); var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, b); lt.Add(tt); } reg.ProcessTransactionLogs(lt, true); } else { reg.ProcessTransactionLogs(logFiles.ToList(), true); } } else { log.Warn("Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways..."); } } } reg.ParseHive(); var fileKey = reg.GetKey(@"Root\File"); var programsKey = reg.GetKey(@"Root\Programs"); UnassociatedFileEntries = new List <FileEntryOld>(); ProgramsEntries = new List <ProgramsEntryOld>(); if (fileKey == null || programsKey == null) { _logger.Error("Hive does not contain a File and/or Programs key. Processing cannot continue"); return; } //First, we get data for all the Program entries under Programs key _logger.Debug("Getting Programs data"); foreach (var registryKey in programsKey.SubKeys) { var ProgramName0 = ""; var ProgramVersion1 = ""; var Guid10 = ""; var UninstallGuid11 = ""; var Guid12 = ""; var Dword13 = 0; var Dword14 = 0; var Dword15 = 0; var UnknownBytes = new byte[0]; long Qword17 = 0; var Dword18 = 0; var VenderName2 = ""; var LocaleID3 = ""; var Dword5 = 0; var InstallSource6 = ""; var UninstallKey7 = ""; DateTimeOffset?EpochA = null; DateTimeOffset?EpochB = null; var PathListd = ""; var Guidf = ""; var RawFiles = ""; try { foreach (var value in registryKey.Values) { switch (value.ValueName) { case "0": ProgramName0 = value.ValueData; break; case "1": ProgramVersion1 = value.ValueData; break; case "2": VenderName2 = value.ValueData; break; case "3": LocaleID3 = value.ValueData; break; case "5": Dword5 = int.Parse(value.ValueData); break; case "6": InstallSource6 = value.ValueData; break; case "7": UninstallKey7 = value.ValueData; break; case "a": try { var seca = long.Parse(value.ValueData); if (seca > 0) { EpochA = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); } } catch (Exception) { //sometimes the number is way too big } break; case "b": var seconds = long.Parse(value.ValueData); if (seconds > 0) { EpochB = DateTimeOffset.FromUnixTimeSeconds(seconds).ToUniversalTime(); } break; case "d": PathListd = value.ValueData; break; case "f": Guidf = value.ValueData; break; case "10": Guid10 = value.ValueData; break; case "11": UninstallGuid11 = value.ValueData; break; case "12": Guid12 = value.ValueData; break; case "13": Dword13 = int.Parse(value.ValueData); break; case "14": Dword13 = int.Parse(value.ValueData); break; case "15": Dword13 = int.Parse(value.ValueData); break; case "16": UnknownBytes = value.ValueDataRaw; break; case "17": Qword17 = long.Parse(value.ValueData); break; case "18": Dword18 = int.Parse(value.ValueData); break; case "Files": RawFiles = value.ValueData; break; default: _logger.Warn( $"Unknown value name in Program at path {registryKey.KeyPath}: {value.ValueName}"); break; } } var pe = new ProgramsEntryOld(ProgramName0, ProgramVersion1, VenderName2, LocaleID3, InstallSource6, UninstallKey7, Guid10, Guid12, UninstallGuid11, Dword5, Dword13, Dword14, Dword15, UnknownBytes, Qword17, Dword18, EpochA, EpochB, PathListd, Guidf, RawFiles, registryKey.KeyName, registryKey.LastWriteTime.Value); ProgramsEntries.Add(pe); } catch (Exception ex) { _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}"); } } //For each Programs entry, add the related Files entries from Files\Volume subkey, put the rest in unassociated _logger.Debug("Getting Files data"); foreach (var registryKey in fileKey.SubKeys) { //These are the guids for volumes foreach (var subKey in registryKey.SubKeys) { var prodName = ""; int?langId = null; var fileVerString = ""; var fileVerNum = ""; var fileDesc = ""; var compName = ""; var fullPath = ""; var switchBack = ""; var peHash = ""; var progID = ""; var sha = ""; long binProdVersion = 0; ulong binFileVersion = 0; var linkerVersion = 0; var binType = 0; var isLocal = 0; var gProgramID = 0; int? fileSize = null; int? sizeOfImage = null; uint? peHeaderChecksum = null; DateTimeOffset?created = null; DateTimeOffset?lm = null; DateTimeOffset?lmStore = null; DateTimeOffset?linkDate = null; var hasLinkedProgram = false; try { //these are the files executed from the volume foreach (var keyValue in subKey.Values) { var keyVal = int.Parse(keyValue.ValueName, NumberStyles.HexNumber); switch (keyVal) { case ProductName: prodName = keyValue.ValueData; break; case CompanyName: compName = keyValue.ValueData; break; case FileVersionNumber: fileVerNum = keyValue.ValueData; break; case LanguageCode: langId = int.Parse(keyValue.ValueData); break; case SwitchBackContext: switchBack = keyValue.ValueData; break; case FileVersionString: fileVerString = keyValue.ValueData; break; case FileSize: fileSize = int.Parse(keyValue.ValueData); break; case SizeOfImage: sizeOfImage = int.Parse(keyValue.ValueData); break; case PEHeaderHash: peHash = keyValue.ValueData; break; case PEHeaderChecksum: peHeaderChecksum = uint.Parse(keyValue.ValueData); break; case BinProductVersion: binProdVersion = long.Parse(keyValue.ValueData); break; case BinFileVersion: binFileVersion = ulong.Parse(keyValue.ValueData); break; case FileDescription: fileDesc = keyValue.ValueData; break; case LinkerVersion: linkerVersion = int.Parse(keyValue.ValueData); break; case LinkDate: linkDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(keyValue.ValueData)) .ToUniversalTime(); break; case BinaryType: binType = int.Parse(keyValue.ValueData); break; case LastModified: lm = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)).ToUniversalTime(); break; case Created: created = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)).ToUniversalTime(); break; case FullPath: fullPath = keyValue.ValueData; break; case IsLocal: isLocal = int.Parse(keyValue.ValueData); break; case GuessProgramID: gProgramID = int.Parse(keyValue.ValueData); break; case LastModifiedStore: lmStore = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)) .ToUniversalTime(); break; case ProgramID: progID = keyValue.ValueData; var program = ProgramsEntries.SingleOrDefault(t => t.ProgramID == progID); if (program != null) { hasLinkedProgram = true; } break; case SHA1: sha = keyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': 0x{keyVal:X}"); break; } } if (fullPath.Length == 0) { continue; } TotalFileEntries += 1; var fe = new FileEntryOld(prodName, progID, sha, fullPath, lmStore, registryKey.KeyName, registryKey.LastWriteTime.Value, subKey.KeyName, subKey.LastWriteTime.Value, isLocal, compName, langId, fileVerString, peHash, fileVerNum, fileDesc, binProdVersion, binFileVersion, linkerVersion, binType, switchBack, fileSize, linkDate, sizeOfImage, lm, created, peHeaderChecksum, gProgramID, subKey.KeyName); if (hasLinkedProgram) { var program = ProgramsEntries.SingleOrDefault(t => t.ProgramID == fe.ProgramID); fe.ProgramName = program.ProgramName_0; program.FileEntries.Add(fe); } else { fe.ProgramName = "Unassociated"; UnassociatedFileEntries.Add(fe); } } catch (Exception ex) { _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}"); } } } }
public void ShouldIncreaseSoftParsingError() { var usrclass = new RegistryHive(@"..\..\Hives\UsrClass-win7.dat"); usrclass.RecoverDeleted = true; Check.That(usrclass.SoftParsingErrors).IsEqualTo(0); usrclass.ParseHive(); Check.That(usrclass.SoftParsingErrors).IsGreaterThan(0); }
public void ShouldThrowExceptionNoRootKey() { Check.ThatCode(() => { var r = new RegistryHive(@"..\..\Hives\SECURITYNoRoot"); r.ParseHive(); }).Throws <KeyNotFoundException>(); }
public void ShouldCatchNKRecordThatsTooSmallFromSlackSpace() { var usrclass = new RegistryHive(@"..\..\Hives\ERZ_Win81_UsrClass.dat"); usrclass.RecoverDeleted = true; usrclass.ParseHive(); }
public void ShouldCatchVKRecordThatsTooSmallFromSlackSpace() { var usrclass = new RegistryHive(@"..\..\Hives\NTUSER slack.DAT"); usrclass.RecoverDeleted = true; usrclass.ParseHive(); }
public void InitializeObjects() { Debug.WriteLine("Initializing hives..."); SamOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM"); SamHasBigEndianOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM_hasBigEndianDWord"); SamDupeNameOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM_DUPENAME"); NtUser1OnDemand = new RegistryHiveOnDemand(@"..\..\Hives\NTUSER1.DAT"); UsrClassDeletedBagsOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\UsrClassDeletedBags.dat"); SoftwareOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SOFTWARE"); SystemOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SYSTEM"); Bcd = new RegistryHive(@"..\..\Hives\BCD"); Bcd.FlushRecordListsAfterParse = false; Bcd.RecoverDeleted = true; Bcd.ParseHive(); UsrclassDeleted = new RegistryHive(@"..\..\Hives\UsrClassDeletedBags.dat"); UsrclassDeleted.RecoverDeleted = true; UsrclassDeleted.FlushRecordListsAfterParse = false; UsrclassDeleted.ParseHive(); UsrclassAcronis = new RegistryHive(@"..\..\Hives\Acronis_0x52_Usrclass.dat"); UsrclassAcronis.RecoverDeleted = true; UsrclassAcronis.FlushRecordListsAfterParse = false; UsrclassAcronis.ParseHive(); UsrClass1 = new RegistryHive(@"..\..\Hives\UsrClass 1.dat"); UsrClass1.RecoverDeleted = true; UsrClass1.FlushRecordListsAfterParse = false; UsrClass1.ParseHive(); UsrClass1OnDemand = new RegistryHiveOnDemand(@"..\..\Hives\UsrClass 1.dat"); UsrClassBeef = new RegistryHive(@"..\..\Hives\UsrClass BEEF000E.dat"); UsrClassBeef.RecoverDeleted = true; UsrClassBeef.FlushRecordListsAfterParse = false; UsrClassBeef.ParseHive(); NtUserSlack = new RegistryHive(@"..\..\Hives\NTUSER slack.DAT"); NtUserSlack.FlushRecordListsAfterParse = false; NtUserSlack.ParseHive(); Sam = new RegistryHive(@"..\..\Hives\SAM"); Sam.FlushRecordListsAfterParse = false; Sam.ParseHive(); SamRootValue = new RegistryHive(@"..\..\Hives\SAM_RootValue"); SamRootValue.FlushRecordListsAfterParse = false; SamRootValue.ParseHive(); Security = new RegistryHiveOnDemand(@"..\..\Hives\SECURITY"); DriversOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\DRIVERS"); Drivers = new RegistryHive(@"..\..\Hives\DRIVERS"); Drivers.FlushRecordListsAfterParse = false; Drivers.RecoverDeleted = true; Drivers.ParseHive(); System = new RegistryHive(@"..\..\Hives\System"); System.FlushRecordListsAfterParse = false; System.ParseHive(); SanOther = new RegistryHiveOnDemand(@"..\..\Hives\SAN(OTHER)"); UsrClassFtp = new RegistryHiveOnDemand(@"..\..\Hives\UsrClass FTP.dat"); }
public AppCompatCache(string filename, int controlSet, bool noLogs) { byte[] rawBytes = null; Caches = new List <IAppCompatCache>(); var controlSetIds = new List <int>(); RegistryKey subKey = null; var isLiveRegistry = string.IsNullOrEmpty(filename); if (isLiveRegistry) { var keyCurrUser = Microsoft.Win32.Registry.LocalMachine; var subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache"); if (subKey2 == null) { subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility"); if (subKey2 == null) { Console.WriteLine( @"'CurrentControlSet\Control\Session Manager\AppCompatCache' key not found! Exiting"); return; } } rawBytes = (byte[])subKey2.GetValue("AppCompatCache", null); subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\Select"); ControlSet = (int)subKey2.GetValue("Current"); var is32Bit = Is32Bit(filename); var cache = Init(rawBytes, is32Bit, ControlSet); Caches.Add(cache); return; } ControlSet = controlSet; if (File.Exists(filename) == false) { throw new FileNotFoundException($"File not found ({filename})!"); } var hive = new RegistryHive(filename); if (hive.Header.PrimarySequenceNumber != hive.Header.SecondarySequenceNumber) { var hiveBase = Path.GetFileName(filename); var dirname = Path.GetDirectoryName(filename); if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); if (logFiles.Length == 0) { var log = LogManager.GetCurrentClassLogger(); if (noLogs == false) { log.Warn("Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception("Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } log.Warn("Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } else { hive.ProcessTransactionLogs(logFiles.ToList(), true); } } hive.ParseHive(); if (controlSet == -1) { for (var i = 0; i < 10; i++) { subKey = hive.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = hive.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatibility"); } if (subKey != null) { controlSetIds.Add(i); } } if (controlSetIds.Count > 1) { var log = LogManager.GetCurrentClassLogger(); log.Warn( $"***The following ControlSet00x keys will be exported: {string.Join(",", controlSetIds)}. Use -c to process keys individually\r\n"); } } else { //a control set was passed in subKey = hive.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = hive.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatibility"); } if (subKey == null) { throw new Exception($"Could not find ControlSet00{ControlSet}. Exiting"); } controlSetIds.Add(ControlSet); } var is32 = Is32Bit(filename); var log1 = LogManager.GetCurrentClassLogger(); log1.Debug($@"**** Found {controlSetIds.Count} ids to process"); foreach (var id in controlSetIds) { log1.Debug($@"**** Processing id {id}"); var hive2 = new RegistryHiveOnDemand(filename); subKey = hive2.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatCache"); if (subKey == null) { log1.Debug($@"**** Initial subkey null, getting appCompatability key"); subKey = hive2.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatibility"); } log1.Debug($@"**** Looking AppCompatcache value"); var val = subKey?.Values.SingleOrDefault(c => c.ValueName == "AppCompatCache"); if (val != null) { log1.Debug($@"**** Found AppCompatcache value"); rawBytes = val.ValueDataRaw; } if (rawBytes == null) { var log = LogManager.GetCurrentClassLogger(); log.Error($@"'AppCompatCache' value not found for 'ControlSet00{id}'! Exiting"); } var cache = Init(rawBytes, is32, id); Caches.Add(cache); } }
public void ShouldFindRegQWordValues() { var ntUser1OnDemand = new RegistryHiveOnDemand(@".\Hives\NTUSER1.DAT"); var key = ntUser1OnDemand.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\Software\Microsoft\Windows\Windows Error Reporting"); Check.That(key).IsNotNull(); var val = key.Values.Single(t => t.ValueName == "LastWatsonCabUploaded"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegQword); Check.That(val.VkRecord.ValueData).IsEqualTo((ulong)130557640214774914); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(4); key = ntUser1OnDemand.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\Software\Microsoft\Windows\CurrentVersion\Store\RefreshBannedAppList"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "BannedAppsLastModified"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegQword); Check.That(val.VkRecord.ValueData).IsEqualTo((ulong)0); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(4); var usrclassAcronis = new RegistryHive(@".\Hives\Acronis_0x52_Usrclass.dat"); usrclassAcronis.RecoverDeleted = true; usrclassAcronis.FlushRecordListsAfterParse = false; usrclassAcronis.ParseHive(); key = usrclassAcronis.GetKey( @"S-1-5-21-3851833874-1800822990-1357392098-1000_Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "LastAdvertisement"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegQword); Check.That(val.VkRecord.ValueData).IsEqualTo((ulong)130294002389413697); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(4); var usrclassDeleted = new RegistryHive(@".\Hives\UsrClassDeletedBags.dat"); usrclassDeleted.RecoverDeleted = true; usrclassDeleted.FlushRecordListsAfterParse = false; usrclassDeleted.ParseHive(); key = usrclassDeleted.GetKey( @"S-1-5-21-146151751-63468248-1215037915-1000_Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "LastAdvertisement"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegQword); Check.That(val.VkRecord.ValueData).IsEqualTo((ulong)130672934390152518); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(4); var ntUserSlack = new RegistryHive(@".\Hives\NTUSER slack.DAT"); ntUserSlack.FlushRecordListsAfterParse = false; ntUserSlack.ParseHive(); key = ntUserSlack.GetKey( @"$$$PROTO.HIV\Software\Microsoft\VisualStudio\7.0\External Tools"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "LastMerge"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegQword); Check.That(val.VkRecord.ValueData).IsEqualTo((ulong)127257359392030000); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(4); }
public void ShouldThrowExceptionNoRootKey() { Check.ThatCode(() =>{var r = new RegistryHive(@"..\..\Hives\SECURITYNoRoot");r.ParseHive();}).Throws<KeyNotFoundException>(); }
public void ShouldFindKeyValueAndCheckProperties() { var sam = new RegistryHive(@".\Hives\SAM"); sam.FlushRecordListsAfterParse = false; sam.ParseHive(); var key = sam.GetKey(0x418); Check.That(key).IsNotNull(); Check.That(key.ToString()).IsNotEmpty(); var val = key.Values[0]; //TODO Need to export to reg each kind too Check.That(val).IsNotNull(); Check.That(val.ValueName).IsNotEmpty(); Check.That(val.ValueData).IsEmpty(); Check.That(val.ValueSlack).IsEmpty(); Check.That(val.ValueSlackRaw).IsEmpty(); Check.That(val.ToString()).IsNotEmpty(); Check.That(val.ValueName).IsEqualTo("(default)"); Check.That(val.ValueType).IsEqualTo("RegNone"); Check.That(val.ValueData).IsEqualTo(""); Check.That(val.ValueSlack).IsEqualTo(""); Check.That(val.VkRecord.Size).IsEqualTo(-24); Check.That(val.VkRecord.RelativeOffset).IsEqualTo(0x270); Check.That(val.VkRecord.AbsoluteOffset).IsEqualTo(0x1270); Check.That(val.VkRecord.Signature).IsEqualTo("vk"); Check.That(val.VkRecord.IsFree).IsFalse(); Check.That(val.VkRecord.DataLength).IsEqualTo(0x80000000); Check.That(val.VkRecord.OffsetToData).IsEqualTo(0); Check.That(val.VkRecord.NameLength).IsEqualTo(0); Check.That(val.VkRecord.NamePresentFlag).IsEqualTo(0); //This key has slack key = sam.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\SAM\Domains\Account\Users\000001F4"); Check.That(key).IsNotNull(); val = key.Values[0]; Check.That(val).IsNotNull(); Check.That(val.ValueName).IsNotEmpty(); Check.That(val.ValueData).IsNotEmpty(); Check.That(val.ValueSlack).IsNotEmpty(); Check.That(val.ValueSlackRaw.Length).IsStrictlyGreaterThan(0); Check.That(val.ToString()).IsNotEmpty(); Check.That(val.ValueName).IsEqualTo("F"); Check.That(val.ValueData).IsNotEmpty(); Check.That(val.ValueData.Length).IsEqualTo(239); Check.That(val.ValueSlack).IsNotEmpty(); Check.That(val.ValueSlack.Length).IsEqualTo(11); Check.That(val.ValueSlackRaw.Length).IsEqualTo(4); Check.That(val.ToString()).IsNotEmpty(); Check.That(val.ValueType).IsEqualTo("RegBinary"); Check.That(val.ValueData) .IsEqualTo( "02-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-FF-FF-FF-FF-FF-FF-FF-7F-00-00-00-00-00-00-00-00-F4-01-00-00-01-02-00-00-10-02-00-00-00-00-00-00-00-00-00-00-01-00-00-00-00-00-00-00-73-00-00-00"); Check.That(val.ValueSlack).IsEqualTo("1F-00-0F-00"); Check.That(val.VkRecord.Size).IsEqualTo(-32); Check.That(val.VkRecord.RelativeOffset).IsEqualTo(0x39B8); Check.That(val.VkRecord.AbsoluteOffset).IsEqualTo(0x49B8); Check.That(val.VkRecord.Signature).IsEqualTo("vk"); Check.That(val.VkRecord.IsFree).IsFalse(); Check.That(val.VkRecord.DataLength).IsEqualTo(0x50); Check.That(val.VkRecord.OffsetToData).IsEqualTo(0x39D8); Check.That(val.VkRecord.NameLength).IsEqualTo(0x1); Check.That(val.VkRecord.NamePresentFlag).IsEqualTo(1); Check.That(val.VkRecord.Padding.Length).IsEqualTo(7); }
public void ShouldFindRegMultiSzValues() { var ntUser1OnDemand = new RegistryHiveOnDemand(@".\Hives\NTUSER1.DAT"); var key = ntUser1OnDemand.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\Control Panel\International\User Profile"); Check.That(key).IsNotNull(); var val = key.Values.Single(t => t.ValueName == "Languages"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegMultiSz); Check.That(val.VkRecord.ValueData).IsEqualTo("en-US"); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(0); var usrclassAcronis = new RegistryHive(@".\Hives\Acronis_0x52_Usrclass.dat"); usrclassAcronis.RecoverDeleted = true; usrclassAcronis.FlushRecordListsAfterParse = false; usrclassAcronis.ParseHive(); key = usrclassAcronis.GetKey( @"S-1-5-21-3851833874-1800822990-1357392098-1000_Classes\Local Settings\MuiCache\12\52C64B7E"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "LanguageList"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegMultiSz); Check.That(val.VkRecord.ValueData).IsEqualTo("en-US en"); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(0); var bcd = new RegistryHive(@".\Hives\BCD"); bcd.FlushRecordListsAfterParse = false; bcd.RecoverDeleted = true; bcd.ParseHive(); key = bcd.GetKey( @"System\Objects\{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}\Elements\14000006"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "Element"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegMultiSz); Check.That(val.VkRecord.ValueData) .IsEqualTo("{4636856e-540f-4170-a130-a84776f4c654} {0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}"); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(6); key = bcd.GetKey( @"System\Objects\{9dea862c-5cdd-4e70-acc1-f32b344d4795}\Elements\14000006"); Check.That(key).IsNotNull(); val = key.Values.Single(t => t.ValueName == "Element"); Check.That(val).IsNotNull(); Check.That(val.VkRecord.DataType).IsEqualTo(VkCellRecord.DataTypeEnum.RegMultiSz); Check.That(val.VkRecord.ValueData).IsEqualTo("{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}"); Check.That(val.VkRecord.ValueDataSlack.Length).IsEqualTo(84); }
private static void Main(string[] args) { if (!CheckForDotnet46()) { Console.Error.WriteLine("Please install .NET Framework 4.6."); return; } string inDir = "", outDir = ""; string outFileBase = $"regruns_output.csv"; // option handling string[] cmds = Environment.GetCommandLineArgs(); if (args.Length == 3 || args.Length == 4) // -o output input [--noheader] { if (args[0] == "-o" || args[0] == "--output") { outDir = args[1]; inDir = args[2]; } else { Help(); } } // TODO: implement standard output // else if (args.Length == 1) // only input // inDir = args[0]; else { Help(); } if (Directory.Exists(outDir) == false) { Directory.CreateDirectory(outDir); } var systemHives = new List <string>(); var softwareHives = new List <string>(); var ntuserHives = new List <string>(); // Search SYSTEM/SOFTWARE/NTUSER.DAT Hive foreach (string fileName in Directory.GetFiles(inDir, "*", SearchOption.AllDirectories)) { Stream st = File.OpenRead(fileName); if (st.Length < 4) { continue; } BinaryReader br = new BinaryReader(st); if (br.ReadInt32() != 1718052210) // means not "regf" { continue; } if (Path.GetFileName(fileName).ToUpper().Contains("SYSTEM")) { systemHives.Add(fileName); } else if (Path.GetFileName(fileName).ToUpper().Contains("SOFTWARE")) { softwareHives.Add(fileName); } else if (Path.GetFileName(fileName).ToUpper().Contains("NTUSER.DAT")) { ntuserHives.Add(fileName); } } var outFileName = Path.Combine(outDir, outFileBase); var sw = new StreamWriter(outFileName, true, System.Text.Encoding.UTF8); sw.AutoFlush = true; if (args.Length == 4) { if (args[3] == "--noheader") { // no header } else { sw.WriteLine("ComputerName\tHiveName\tKey\tName\tValue\tLastModified\tTimeZone"); } } else { sw.WriteLine("ComputerName\tHiveName\tKey\tName\tValue\tLastModified\tTimeZone"); } // SYSTEM foreach (var systemHive in systemHives) { var reg = new RegistryHive(systemHive); try { reg.ParseHive(); } catch { Console.Error.WriteLine($"Error: {systemHive}"); continue; } var subKey = reg.GetKey("Select"); if (subKey == null) { continue; } var currentCtlSet = int.Parse(subKey.Values.Single(c => c.ValueName == "Current").ValueData); StreamReader cReader = new StreamReader(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"\system.txt", System.Text.Encoding.Default); // read key per line while (cReader.Peek() >= 0) { string keyName = cReader.ReadLine(); var key = reg.GetKey($@"ControlSet00{currentCtlSet}\{keyName}"); if (key == null) { continue; } WriteSpecificKeyInfo(key, sw, systemHive); } Console.WriteLine($"Finished: '{systemHive}'"); cReader.Close(); } // SOFTWARE foreach (var softwareHive in softwareHives) { var reg = new RegistryHive(softwareHive); try { reg.ParseHive(); } catch { Console.Error.WriteLine($"Error: {softwareHive}"); continue; } StreamReader cReader = new StreamReader(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"\software.txt", System.Text.Encoding.Default); // read key per line while (cReader.Peek() >= 0) { string keyName = cReader.ReadLine(); var key = reg.GetKey(keyName); if (key == null) { continue; } WriteSpecificKeyInfo(key, sw, softwareHive); } Console.WriteLine($"Finished: '{softwareHive}'"); cReader.Close(); } // NTUSER.dat foreach (var ntuserHive in ntuserHives) { var reg = new RegistryHive(ntuserHive); try { reg.ParseHive(); } catch { Console.Error.WriteLine($"Error: {ntuserHive}"); continue; } StreamReader cReader = new StreamReader(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"\ntuser.txt", System.Text.Encoding.Default); // read key by line while (cReader.Peek() >= 0) { string keyName = cReader.ReadLine(); var key = reg.GetKey(keyName); if (key == null) { continue; } WriteSpecificKeyInfo(key, sw, ntuserHive); } Console.WriteLine($"Finished: '{ntuserHive}'"); cReader.Close(); } Console.WriteLine($"Saved: '{outFileName}'"); sw.Close(); return; }
public void ExportToRegFormatSingleKey() { var samOnDemand = new RegistryHiveOnDemand(@"..\..\..\Hives\SAM"); var key = samOnDemand.GetKey(@"SAM\Domains\Account"); var exported = Helpers.ExportToReg(@"exportSamTest.reg", key, HiveTypeEnum.Sam, false); Check.That(exported).IsTrue(); var ntUser1OnDemand = new RegistryHiveOnDemand(@"..\..\..\Hives\NTUSER1.DAT"); key = ntUser1OnDemand.GetKey(@"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\Console"); exported = Helpers.ExportToReg(@"exportntuser1Test.reg", key, HiveTypeEnum.NtUser, false); Check.That(exported).IsTrue(); var security = new RegistryHiveOnDemand(@"..\..\..\Hives\SECURITY"); key = security.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\Policy\Accounts\S-1-5-9"); exported = Helpers.ExportToReg(@"exportsecTest.reg", key, HiveTypeEnum.Security, false); Check.That(exported).IsTrue(); var systemOnDemand = new RegistryHiveOnDemand(@"..\..\..\Hives\SYSTEM"); key = systemOnDemand.GetKey( @"CsiTool-CreateHive-{00000000-0000-0000-0000-000000000000}\ControlSet001\Enum\ACPI\PNP0C02\1"); exported = Helpers.ExportToReg(@"exportsysTest.reg", key, HiveTypeEnum.System, false); Check.That(exported).IsTrue(); var usrClassFtp = new RegistryHiveOnDemand(@"..\..\..\Hives\UsrClass FTP.dat"); key = usrClassFtp.GetKey(@"S-1-5-21-2417227394-2575385136-2411922467-1105_Classes\.3g2"); exported = Helpers.ExportToReg(@"exportusrTest.reg", key, HiveTypeEnum.UsrClass, false); Check.That(exported).IsTrue(); var samDupeNameOnDemand = new RegistryHiveOnDemand(@"..\..\..\Hives\SAM_DUPENAME"); key = samDupeNameOnDemand.GetKey(@"SAM\SAM\Domains\Account\Aliases\000003E9"); exported = Helpers.ExportToReg(@"exportotherTest.reg", key, HiveTypeEnum.Other, false); Check.That(exported).IsTrue(); var usrclassDeleted = new RegistryHive(@"..\..\..\Hives\UsrClassDeletedBags.dat"); usrclassDeleted.RecoverDeleted = true; usrclassDeleted.FlushRecordListsAfterParse = false; usrclassDeleted.ParseHive(); key = usrclassDeleted.GetKey( @"S-1-5-21-146151751-63468248-1215037915-1000_Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU\1"); exported = Helpers.ExportToReg(@"exportDeletedTest.reg", key, HiveTypeEnum.UsrClass, false); Check.That(exported).IsTrue(); }
public void ShouldThrowExceptionWithBadHbinHeader() { Check.ThatCode(() => { var r = new RegistryHive(@"..\..\Hives\SAMBadHBinHeader"); r.ParseHive(); }).Throws <Exception>(); }
public void InitializeObjects() { Debug.WriteLine("Initializing hives..."); SamOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM"); SamHasBigEndianOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM_hasBigEndianDWord"); SamDupeNameOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SAM_DUPENAME"); NtUser1OnDemand = new RegistryHiveOnDemand(@"..\..\Hives\NTUSER1.DAT"); UsrClassDeletedBagsOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\UsrClassDeletedBags.dat"); SoftwareOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SOFTWARE"); SystemOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\SYSTEM"); Bcd = new RegistryHive(@"..\..\Hives\BCD"); Bcd.FlushRecordListsAfterParse = false; Bcd.RecoverDeleted = true; Bcd.ParseHive(); UsrclassDeleted = new RegistryHive(@"..\..\Hives\UsrClassDeletedBags.dat"); UsrclassDeleted.RecoverDeleted = true; UsrclassDeleted.FlushRecordListsAfterParse = false; UsrclassDeleted.ParseHive(); UsrclassAcronis = new RegistryHive(@"..\..\Hives\Acronis_0x52_Usrclass.dat"); UsrclassAcronis.RecoverDeleted = true; UsrclassAcronis.FlushRecordListsAfterParse = false; UsrclassAcronis.ParseHive(); UsrClass1 = new RegistryHive(@"..\..\Hives\UsrClass 1.dat"); UsrClass1.RecoverDeleted = true; UsrClass1.FlushRecordListsAfterParse = false; UsrClass1.ParseHive(); UsrClass1OnDemand = new RegistryHiveOnDemand(@"..\..\Hives\UsrClass 1.dat"); UsrClassBeef = new RegistryHive(@"..\..\Hives\UsrClass BEEF000E.dat"); UsrClassBeef.RecoverDeleted = true; UsrClassBeef.FlushRecordListsAfterParse = false; UsrClassBeef.ParseHive(); NtUserSlack = new RegistryHive(@"..\..\Hives\NTUSER slack.DAT"); NtUserSlack.FlushRecordListsAfterParse = false; NtUserSlack.ParseHive(); Sam = new RegistryHive(@"..\..\Hives\SAM"); Sam.FlushRecordListsAfterParse = false; Sam.ParseHive(); SamRootValue = new RegistryHive(@"..\..\Hives\SAM_RootValue"); SamRootValue.FlushRecordListsAfterParse = false; SamRootValue.ParseHive(); Security = new RegistryHiveOnDemand(@"..\..\Hives\SECURITY"); DriversOnDemand = new RegistryHiveOnDemand(@"..\..\Hives\DRIVERS"); Drivers = new RegistryHive(@"..\..\Hives\DRIVERS"); Drivers.FlushRecordListsAfterParse = false; Drivers.RecoverDeleted = true; Drivers.ParseHive(); System = new RegistryHive(@"..\..\Hives\System"); System.FlushRecordListsAfterParse = false; System.ParseHive(); SanOther = new RegistryHiveOnDemand(@"..\..\Hives\SAN(OTHER)"); UsrClassFtp = new RegistryHiveOnDemand(@"..\..\Hives\UsrClass FTP.dat"); }
public void ShouldThrowExceptionWithBadHbinHeader() { Check.ThatCode(() =>{var r = new RegistryHive(@"..\..\Hives\SAMBadHBinHeader");r.ParseHive();}).Throws<Exception>(); }
public AmcacheOld(string hive, bool recoverDeleted) { _logger = LogManager.GetCurrentClassLogger(); var reg = new RegistryHive(hive) { RecoverDeleted = recoverDeleted }; reg.ParseHive(); var fileKey = reg.GetKey(@"Root\File"); var programsKey = reg.GetKey(@"Root\Programs"); UnassociatedFileEntries = new List <FileEntryOld>(); ProgramsEntries = new List <ProgramsEntryOld>(); if (fileKey == null || programsKey == null) { _logger.Error($"Hive does not contain a File and/or Programs key. Processing cannot continue"); return; } //First, we get data for all the Program entries under Programs key foreach (var registryKey in programsKey.SubKeys) { var ProgramName0 = ""; var ProgramVersion1 = ""; var Guid10 = ""; var UninstallGuid11 = ""; var Guid12 = ""; var Dword13 = 0; var Dword14 = 0; var Dword15 = 0; var UnknownBytes = new byte[0]; long Qword17 = 0; var Dword18 = 0; var VenderName2 = ""; var LocaleID3 = ""; var Dword5 = 0; var InstallSource6 = ""; var UninstallKey7 = ""; DateTimeOffset?EpochA = null; DateTimeOffset?EpochB = null; var PathListd = ""; var Guidf = ""; var RawFiles = ""; try { foreach (var value in registryKey.Values) { switch (value.ValueName) { case "0": ProgramName0 = value.ValueData; break; case "1": ProgramVersion1 = value.ValueData; break; case "2": VenderName2 = value.ValueData; break; case "3": LocaleID3 = value.ValueData; break; case "5": Dword5 = int.Parse(value.ValueData); break; case "6": InstallSource6 = value.ValueData; break; case "7": UninstallKey7 = value.ValueData; break; case "a": try { var seca = long.Parse(value.ValueData); if (seca > 0) { EpochA = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); } } catch (Exception) { //sometimes the number is way too big } break; case "b": var seconds = long.Parse(value.ValueData); if (seconds > 0) { EpochB = DateTimeOffset.FromUnixTimeSeconds(seconds).ToUniversalTime(); } break; case "d": PathListd = value.ValueData; break; case "f": Guidf = value.ValueData; break; case "10": Guid10 = value.ValueData; break; case "11": UninstallGuid11 = value.ValueData; break; case "12": Guid12 = value.ValueData; break; case "13": Dword13 = int.Parse(value.ValueData); break; case "14": Dword13 = int.Parse(value.ValueData); break; case "15": Dword13 = int.Parse(value.ValueData); break; case "16": UnknownBytes = value.ValueDataRaw; break; case "17": Qword17 = long.Parse(value.ValueData); break; case "18": Dword18 = int.Parse(value.ValueData); break; case "Files": RawFiles = value.ValueData; break; default: _logger.Warn( $"Unknown value name in Program at path {registryKey.KeyPath}: {value.ValueName}"); break; } } var pe = new ProgramsEntryOld(ProgramName0, ProgramVersion1, VenderName2, LocaleID3, InstallSource6, UninstallKey7, Guid10, Guid12, UninstallGuid11, Dword5, Dword13, Dword14, Dword15, UnknownBytes, Qword17, Dword18, EpochA, EpochB, PathListd, Guidf, RawFiles, registryKey.KeyName, registryKey.LastWriteTime.Value); ProgramsEntries.Add(pe); } catch (Exception ex) { _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}"); } } //For each Programs entry, add the related Files entries from Files\Volume subkey, put the rest in unassociated foreach (var registryKey in fileKey.SubKeys) { //These are the guids for volumes foreach (var subKey in registryKey.SubKeys) { var prodName = ""; int?langId = null; var fileVerString = ""; var fileVerNum = ""; var fileDesc = ""; var compName = ""; var fullPath = ""; var switchBack = ""; var peHash = ""; var progID = ""; var sha = ""; long binProdVersion = 0; ulong binFileVersion = 0; var linkerVersion = 0; var binType = 0; var isLocal = 0; var gProgramID = 0; int? fileSize = null; int? sizeOfImage = null; int? peHeaderChecksum = null; DateTimeOffset?created = null; DateTimeOffset?lm = null; DateTimeOffset?lmStore = null; DateTimeOffset?linkDate = null; var hasLinkedProgram = false; try { //these are the files executed from the volume foreach (var keyValue in subKey.Values) { var keyVal = int.Parse(keyValue.ValueName, NumberStyles.HexNumber); switch (keyVal) { case ProductName: prodName = keyValue.ValueData; break; case CompanyName: compName = keyValue.ValueData; break; case FileVersionNumber: fileVerNum = keyValue.ValueData; break; case LanguageCode: langId = int.Parse(keyValue.ValueData); break; case SwitchBackContext: switchBack = keyValue.ValueData; break; case FileVersionString: fileVerString = keyValue.ValueData; break; case FileSize: fileSize = int.Parse(keyValue.ValueData); break; case SizeOfImage: sizeOfImage = int.Parse(keyValue.ValueData); break; case PEHeaderHash: peHash = keyValue.ValueData; break; case PEHeaderChecksum: peHeaderChecksum = int.Parse(keyValue.ValueData); break; case BinProductVersion: binProdVersion = long.Parse(keyValue.ValueData); break; case BinFileVersion: binFileVersion = ulong.Parse(keyValue.ValueData); break; case FileDescription: fileDesc = keyValue.ValueData; break; case LinkerVersion: linkerVersion = int.Parse(keyValue.ValueData); break; case LinkDate: linkDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(keyValue.ValueData)) .ToUniversalTime(); break; case BinaryType: binType = int.Parse(keyValue.ValueData); break; case LastModified: lm = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)).ToUniversalTime(); break; case Created: created = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)).ToUniversalTime(); break; case FullPath: fullPath = keyValue.ValueData; break; case IsLocal: isLocal = int.Parse(keyValue.ValueData); break; case GuessProgramID: gProgramID = int.Parse(keyValue.ValueData); break; case LastModifiedStore: lmStore = DateTimeOffset.FromFileTime(long.Parse(keyValue.ValueData)).ToUniversalTime(); break; case ProgramID: progID = keyValue.ValueData; var program = ProgramsEntries.SingleOrDefault(t => t.ProgramID == progID); if (program != null) { hasLinkedProgram = true; } break; case SHA1: sha = keyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': 0x{keyVal:X}"); break; } } if (fullPath.Length == 0) { continue; } TotalFileEntries += 1; var fe = new FileEntryOld(prodName, progID, sha, fullPath, lmStore, registryKey.KeyName, registryKey.LastWriteTime.Value, subKey.KeyName, subKey.LastWriteTime.Value, isLocal, compName, langId, fileVerString, peHash, fileVerNum, fileDesc, binProdVersion, binFileVersion, linkerVersion, binType, switchBack, fileSize, linkDate, sizeOfImage, lm, created, peHeaderChecksum, gProgramID, subKey.KeyName); if (hasLinkedProgram) { var program = ProgramsEntries.SingleOrDefault(t => t.ProgramID == fe.ProgramID); fe.ProgramName = program.ProgramName_0; program.FileEntries.Add(fe); } else { fe.ProgramName = "Unassociated"; UnassociatedFileEntries.Add(fe); } } catch (Exception ex) { _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}"); } } } }
public static bool IsNewFormat(string file, bool noLog) { RegistryKey fileKey = null; RegistryHive reg; var dirname = Path.GetDirectoryName(file); var hiveBase = Path.GetFileName(file); List <RawCopy.RawCopyReturn> rawFiles = null; try { try { reg = new RegistryHive(file) { RecoverDeleted = true }; } catch (IOException) { //file is in use if (RawCopy.Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } var files = new List <string>(); files.Add(file); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = RawCopy.Helper.GetFiles(files); var b = new byte[rawFiles.First().FileStream.Length]; rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length); reg = new RegistryHive(b, rawFiles.First().InputFilename); } LogManager.DisableLogging(); if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); if (logFiles.Length == 0) { var log = LogManager.GetCurrentClassLogger(); if (noLog == false) { log.Warn("Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception("Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } log.Warn("Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } else { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var b = new byte[rawCopyReturn.FileStream.Length]; rawCopyReturn.FileStream.Read(b, 0, (int)rawCopyReturn.FileStream.Length); var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, b); lt.Add(tt); } reg.ProcessTransactionLogs(lt, true); } else { reg.ProcessTransactionLogs(logFiles.ToList(), true); } } } reg.ParseHive(); fileKey = reg.GetKey(@"Root\InventoryApplicationFile"); LogManager.EnableLogging(); } catch (Exception ex) { LogManager.EnableLogging(); } return(fileKey != null); }
public AmcacheNew(string hive, bool recoverDeleted) { _logger = LogManager.GetCurrentClassLogger(); var reg = new RegistryHive(hive) { RecoverDeleted = recoverDeleted }; reg.ParseHive(); var fileKey = reg.GetKey(@"Root\InventoryApplicationFile"); var programsKey = reg.GetKey(@"Root\InventoryApplication"); UnassociatedFileEntries = new List <FileEntryNew>(); ProgramsEntries = new List <ProgramsEntryNew>(); DeviceContainers = new List <DeviceContainer>(); DevicePnps = new List <DevicePnp>(); DriveBinaries = new List <DriverBinary>(); DriverPackages = new List <DriverPackage>(); ShortCuts = new List <Shortcut>(); if (fileKey == null || programsKey == null) { _logger.Error( "Hive does not contain a InventoryApplicationFile and/or InventoryApplication key. Processing cannot continue"); return; } foreach (var registryKey in programsKey.SubKeys) { var bundleManifestPath = string.Empty; var hiddenArp = false; var inboxModernApp = false; DateTimeOffset?installDate = null; var language = 0; var manifestPath = string.Empty; var msiPackageCode = string.Empty; var msiProductCode = string.Empty; var name = string.Empty; var osVersionAtInstallTime = string.Empty; var packageFullName = string.Empty; var programId = string.Empty; var programInstanceId = string.Empty; var publisher = string.Empty; var registryKeyPath = string.Empty; var rootDirPath = string.Empty; var source = string.Empty; var storeAppType = string.Empty; var type = string.Empty; var uninstallString = string.Empty; var version = string.Empty; try { foreach (var registryKeyValue in registryKey.Values) { switch (registryKeyValue.ValueName) { case "BundleManifestPath": bundleManifestPath = registryKeyValue.ValueData; break; case "HiddenArp": hiddenArp = registryKeyValue.ValueData == "1"; break; case "InboxModernApp": inboxModernApp = registryKeyValue.ValueData == "1"; break; case "InstallDate": if (registryKeyValue.ValueData.Length > 0) { var d = new DateTimeOffset(DateTime.Parse(registryKeyValue.ValueData).Ticks, TimeSpan.Zero); installDate = d; } break; case "Language": language = int.Parse(registryKeyValue.ValueData); break; case "ManifestPath": manifestPath = registryKeyValue.ValueData; break; case "MsiPackageCode": msiPackageCode = registryKeyValue.ValueData; break; case "MsiProductCode": msiProductCode = registryKeyValue.ValueData; break; case "Name": name = registryKeyValue.ValueData; break; case "OSVersionAtInstallTime": osVersionAtInstallTime = registryKeyValue.ValueData; break; case "PackageFullName": packageFullName = registryKeyValue.ValueData; break; case "ProgramId": programId = registryKeyValue.ValueData; break; case "ProgramInstanceId": programInstanceId = registryKeyValue.ValueData; break; case "Publisher": publisher = registryKeyValue.ValueData; break; case "RegistryKeyPath": registryKeyPath = registryKeyValue.ValueData; break; case "RootDirPath": rootDirPath = registryKeyValue.ValueData; break; case "Source": source = registryKeyValue.ValueData; break; case "StoreAppType": storeAppType = registryKeyValue.ValueData; break; case "Type": type = registryKeyValue.ValueData; break; case "UninstallString": uninstallString = registryKeyValue.ValueData; break; case "Version": version = registryKeyValue.ValueData; break; default: _logger.Warn( $"Unknown value name in InventoryApplication at path {registryKey.KeyPath}: {registryKeyValue.ValueName}"); break; } } var pe = new ProgramsEntryNew(bundleManifestPath, hiddenArp, inboxModernApp, installDate, language, manifestPath, msiPackageCode, msiProductCode, name, osVersionAtInstallTime, packageFullName, programId, programInstanceId, publisher, registryKeyPath, rootDirPath, source, storeAppType, type, uninstallString, version, registryKey.LastWriteTime.Value); ProgramsEntries.Add(pe); } catch (Exception ex) { _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}"); } } foreach (var subKey in fileKey.SubKeys) { var binaryType = string.Empty; var binFileVersion = string.Empty; var binProductVersion = string.Empty; var fileId = string.Empty; var isOsComponent = false; var isPeFile = false; var language = 0; DateTimeOffset?linkDate = null; var longPathHash = string.Empty; var lowerCaseLongPath = string.Empty; var name = string.Empty; var productName = string.Empty; var productVersion = string.Empty; var programId = string.Empty; var publisher = string.Empty; var size = 0; var version = string.Empty; var hasLinkedProgram = false; try { foreach (var subKeyValue in subKey.Values) { switch (subKeyValue.ValueName) { case "BinaryType": binaryType = subKeyValue.ValueData; break; case "BinFileVersion": binFileVersion = subKeyValue.ValueData; break; case "BinProductVersion": binProductVersion = subKeyValue.ValueData; break; case "FileId": fileId = subKeyValue.ValueData; break; case "IsOsComponent": isOsComponent = subKeyValue.ValueData == "1"; break; case "IsPeFile": isPeFile = subKeyValue.ValueData == "1"; break; case "Language": language = int.Parse(subKeyValue.ValueData); break; case "LinkDate": if (subKeyValue.ValueData.Length > 0) { var d = new DateTimeOffset(DateTime.Parse(subKeyValue.ValueData).Ticks, TimeSpan.Zero); linkDate = d; } break; case "LongPathHash": longPathHash = subKeyValue.ValueData; break; case "LowerCaseLongPath": lowerCaseLongPath = subKeyValue.ValueData; break; case "Name": name = subKeyValue.ValueData; break; case "ProductName": productName = subKeyValue.ValueData; break; case "ProductVersion": productVersion = subKeyValue.ValueData; break; case "ProgramId": programId = subKeyValue.ValueData; var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == programId); if (program != null) { hasLinkedProgram = true; } break; case "Publisher": publisher = subKeyValue.ValueData; break; case "Size": size = int.Parse(subKeyValue.ValueData); break; case "Version": version = subKeyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': {subKeyValue.ValueName}"); break; } } } catch (Exception ex) { _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}"); } TotalFileEntries += 1; Debug.WriteLine(name); var fe = new FileEntryNew(binaryType, binFileVersion, productVersion, fileId, isOsComponent, isPeFile, language, linkDate, longPathHash, lowerCaseLongPath, name, productName, productVersion, programId, publisher, size, version, subKey.LastWriteTime.Value, binProductVersion); if (hasLinkedProgram) { var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == fe.ProgramId); fe.ApplicationName = program.Name; program.FileEntries.Add(fe); } else { fe.ApplicationName = "Unassociated"; UnassociatedFileEntries.Add(fe); } } var shortCutkey = reg.GetKey(@"Root\InventoryApplicationShortcut"); if (shortCutkey != null) { foreach (var shortCutkeySubKey in shortCutkey.SubKeys) { ShortCuts.Add(new Shortcut(shortCutkeySubKey.KeyName, shortCutkeySubKey.Values.First().ValueData, shortCutkeySubKey.LastWriteTime.Value)); } } var deviceKey = reg.GetKey(@"Root\InventoryDeviceContainer"); if (deviceKey != null) { foreach (var deviceSubKey in deviceKey.SubKeys) { var categories = string.Empty; var discoveryMethod = string.Empty; var friendlyName = string.Empty; var icon = string.Empty; var isActive = false; var isConnected = false; var isMachineContainer = false; var isNetworked = false; var isPaired = false; var manufacturer = string.Empty; var modelId = string.Empty; var modelName = string.Empty; var modelNumber = string.Empty; var primaryCategory = string.Empty; var state = string.Empty; try { foreach (var keyValue in deviceSubKey.Values) { switch (keyValue.ValueName) { case "Categories": categories = keyValue.ValueData; break; case "DiscoveryMethod": discoveryMethod = keyValue.ValueData; break; case "FriendlyName": friendlyName = keyValue.ValueData; break; case "Icon": icon = keyValue.ValueData; break; case "IsActive": isActive = keyValue.ValueData == "1"; break; case "IsConnected": isConnected = keyValue.ValueData == "1"; break; case "IsMachineContainer": isMachineContainer = keyValue.ValueData == "1"; break; case "IsNetworked": isNetworked = keyValue.ValueData == "1"; break; case "IsPaired": isPaired = keyValue.ValueData == "1"; break; case "Manufacturer": manufacturer = keyValue.ValueData; break; case "ModelId": modelId = keyValue.ValueData; break; case "ModelName": modelName = keyValue.ValueData; break; case "ModelNumber": modelNumber = keyValue.ValueData; break; case "PrimaryCategory": primaryCategory = keyValue.ValueData; break; case "State": state = keyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing DeviceContainer at path '{deviceSubKey.KeyPath}': {keyValue.ValueName}"); break; } } var dc = new DeviceContainer(deviceSubKey.KeyName, deviceSubKey.LastWriteTime.Value, categories, discoveryMethod, friendlyName, icon, isActive, isConnected, isMachineContainer, isNetworked, isPaired, manufacturer, modelId, modelName, modelNumber, primaryCategory, state); DeviceContainers.Add(dc); } catch (Exception ex) { _logger.Error($"Error parsing DeviceContainer at {deviceSubKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {deviceSubKey}"); } } } var pnpKey = reg.GetKey(@"Root\InventoryDevicePnp"); if (pnpKey != null) { foreach (var pnpsKey in pnpKey.SubKeys) { var busReportedDescription = string.Empty; var Class = string.Empty; var classGuid = string.Empty; var compid = string.Empty; var containerId = string.Empty; var description = string.Empty; var deviceState = string.Empty; var driverId = string.Empty; var driverName = string.Empty; var driverPackageStrongName = string.Empty; var driverVerDate = string.Empty; var driverVerVersion = string.Empty; var enumerator = string.Empty; var hwid = string.Empty; var inf = string.Empty; var installState = string.Empty; var manufacturer = string.Empty; var matchingId = string.Empty; var model = string.Empty; var parentId = string.Empty; var problemCode = string.Empty; var provider = string.Empty; var service = string.Empty; var stackid = string.Empty; try { foreach (var keyValue in pnpsKey.Values) { switch (keyValue.ValueName) { case "BusReportedDescription": busReportedDescription = keyValue.ValueData; break; case "Class": Class = keyValue.ValueData; break; case "ClassGuid": classGuid = keyValue.ValueData; break; case "COMPID": compid = keyValue.ValueData; break; case "ContainerId": containerId = keyValue.ValueData; break; case "Description": description = keyValue.ValueData; break; case "DeviceState": deviceState = keyValue.ValueData; break; case "DriverId": driverId = keyValue.ValueData; break; case "DriverName": driverName = keyValue.ValueData; break; case "DriverPackageStrongName": driverPackageStrongName = keyValue.ValueData; break; case "DriverVerDate": driverVerDate = keyValue.ValueData; break; case "DriverVerVersion": driverVerVersion = keyValue.ValueData; break; case "Enumerator": enumerator = keyValue.ValueData; break; case "HWID": hwid = keyValue.ValueData; break; case "Inf": inf = keyValue.ValueData; break; case "InstallState": installState = keyValue.ValueData; break; case "LowerClassFilters": case "LowerFilters": break; case "Manufacturer": manufacturer = keyValue.ValueData; break; case "MatchingID": matchingId = keyValue.ValueData; break; case "Model": model = keyValue.ValueData; break; case "ParentId": parentId = keyValue.ValueData; break; case "ProblemCode": problemCode = keyValue.ValueData; break; case "Provider": provider = keyValue.ValueData; break; case "Service": service = keyValue.ValueData; break; case "STACKID": stackid = keyValue.ValueData; break; case "UpperClassFilters": case "UpperFilters": break; default: _logger.Warn( $"Unknown value name when processing DevicePnp at path '{pnpsKey.KeyPath}': {keyValue.ValueName}"); break; } } var dp = new DevicePnp(pnpsKey.KeyName, pnpKey.LastWriteTime.Value, busReportedDescription, Class, classGuid, compid, containerId, description, deviceState, driverId, driverName, driverPackageStrongName, driverVerDate, driverVerVersion, enumerator, hwid, inf, installState, manufacturer, matchingId, model, parentId, problemCode, provider, service, stackid); DevicePnps.Add(dp); } catch (Exception ex) { _logger.Error($"Error parsing DevicePnp at {pnpKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {pnpKey}"); } } } var binaryKey = reg.GetKey(@"Root\InventoryDriverBinary"); if (binaryKey != null) { foreach (var binKey in binaryKey.SubKeys) { var driverCheckSum = 0; var driverCompany = string.Empty; var driverId = string.Empty; var driverInBox = false; var driverIsKernelMode = false; DateTimeOffset?driverLastWriteTime = null; var driverName = string.Empty; var driverPackageStrongName = string.Empty; var driverSigned = false; DateTimeOffset?driverTimeStamp = null; var driverType = string.Empty; var driverVersion = string.Empty; var imageSize = 0; var inf = string.Empty; var product = string.Empty; var productVersion = string.Empty; var service = string.Empty; var wdfVersion = string.Empty; try { foreach (var keyValue in binKey.Values) { switch (keyValue.ValueName) { case "DriverCheckSum": driverCheckSum = int.Parse(keyValue.ValueData); break; case "DriverCompany": driverCompany = keyValue.ValueData; break; case "DriverId": driverId = keyValue.ValueData; break; case "DriverInBox": driverInBox = keyValue.ValueData == "1"; break; case "DriverIsKernelMode": driverIsKernelMode = keyValue.ValueData == "1"; break; case "DriverLastWriteTime": if (keyValue.ValueData.Length > 0) { var d = new DateTimeOffset(DateTime.Parse(keyValue.ValueData).Ticks, TimeSpan.Zero); driverLastWriteTime = d; } break; case "DriverName": driverName = keyValue.ValueData; break; case "DriverPackageStrongName": driverPackageStrongName = keyValue.ValueData; break; case "DriverSigned": driverSigned = keyValue.ValueData == "1"; break; case "DriverTimeStamp": //DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); var seca = long.Parse(keyValue.ValueData); if (seca > 0) { driverTimeStamp = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); } break; case "DriverType": driverType = keyValue.ValueData; break; case "DriverVersion": driverVersion = keyValue.ValueData; break; case "ImageSize": imageSize = int.Parse(keyValue.ValueData); break; case "Inf": inf = keyValue.ValueData; break; case "Product": product = keyValue.ValueData; break; case "ProductVersion": productVersion = keyValue.ValueData; break; case "Service": service = keyValue.ValueData; break; case "WdfVersion": wdfVersion = keyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing DriverBinary at path '{binKey.KeyPath}': {keyValue.ValueName}"); break; } } var db = new DriverBinary(binKey.KeyName, binaryKey.LastWriteTime.Value, driverCheckSum, driverCompany, driverId, driverInBox, driverIsKernelMode, driverLastWriteTime, driverName, driverPackageStrongName, driverSigned, driverTimeStamp, driverType, driverVersion, imageSize, inf, product, productVersion, service, wdfVersion); DriveBinaries.Add(db); } catch (Exception ex) { _logger.Error($"Error parsing DriverBinary at {binaryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {binaryKey}"); } } } var packaheKey = reg.GetKey(@"Root\InventoryDriverPackage"); if (packaheKey != null) { foreach (var packKey in packaheKey.SubKeys) { var Class = string.Empty; var ClassGuid = string.Empty; DateTimeOffset?Date = null; var Directory = string.Empty; var DriverInBox = false; var Hwids = string.Empty; var Inf = string.Empty; var Provider = string.Empty; var SubmissionId = string.Empty; var SYSFILE = string.Empty; var Version = string.Empty; try { foreach (var keyValue in packKey.Values) { switch (keyValue.ValueName) { case "Class": Class = keyValue.ValueData; break; case "ClassGuid": ClassGuid = keyValue.ValueData; break; case "Date": if (keyValue.ValueData.Length > 0) { var d = new DateTimeOffset(DateTime.Parse(keyValue.ValueData).Ticks, TimeSpan.Zero); Date = d; } break; case "Directory": Directory = keyValue.ValueData; break; case "DriverInBox": DriverInBox = keyValue.ValueData == "1"; break; case "Hwids": Hwids = keyValue.ValueData; break; case "Inf": Inf = keyValue.ValueData; break; case "Provider": Provider = keyValue.ValueData; break; case "SubmissionId": SubmissionId = keyValue.ValueData; break; case "SYSFILE": SYSFILE = keyValue.ValueData; break; case "Version": Version = keyValue.ValueData; break; default: _logger.Warn( $"Unknown value name when processing DriverPackage at path '{packKey.KeyPath}': {keyValue.ValueName}"); break; } } var dp = new DriverPackage(packKey.KeyName, packaheKey.LastWriteTime.Value, Class, ClassGuid, Date, Directory, DriverInBox, Hwids, Inf, Provider, SubmissionId, SYSFILE, Version); DriverPackages.Add(dp); } catch (Exception ex) { _logger.Error($"Error parsing DriverPackage at {packaheKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {packaheKey}"); } } } }
public void Adobe() { /*var f = new List<string>(); * f.Add("D:20200618035802+05'30'"); * f.Add("D:20200618035756+05'30'"); * f.Add("D:20200618035751+05'30'"); * f.Add("D:20200618035744+05'30'"); * f.Add("D:20200618035737+05'30'"); * f.Add("D:20200617182700-04'00'"); * f.Add("D:20200617182636-04'00'"); * f.Add("D:20200617223217Z"); * f.Add("D:20200617182628-04'00'"); * f.Add("D:20200617181449-04'00'"); * f.Add("D:20200617181442-04'00'"); * f.Add("D:20200617181427-04'00'"); * f.Add("D:20200617221353Z"); * f.Add("D:20200617221332Z"); * f.Add("D:20200617221318Z"); * f.Add("D:20200617230951+01'00'"); * f.Add("D:20200617230941+01'00'"); * f.Add("D:20200617230930+01'00'"); * f.Add("D:20200617230922+01'00'"); * f.Add("D:20200617230912+01'00'"); * f.Add("D:20200617230902+01'00'"); * f.Add("D:20200617230854+01'00'"); * f.Add("D:20200617223156Z"); * f.Add("D:20200617230846+01'00'"); * f.Add("D:20200617230730+01'00'"); * f.Add("D:20200617230724+01'00'"); * f.Add("D:20200617230718+01'00'"); * f.Add("D:20200617223147Z"); * f.Add("D:20200617230712+01'00'"); * f.Add("D:20200617230702+01'00'"); * f.Add("D:20200617230655+01'00'"); * f.Add("D:20200617230647+01'00'"); * f.Add("D:20200617230640+01'00'"); * f.Add("D:20200617230217+01'00'"); * f.Add("D:20200617230020+01'00'"); * f.Add("D:20200617230016+01'00'"); * f.Add("D:20200617223137Z"); * f.Add("D:20200617223126Z"); * f.Add("D:20200617223024Z"); * f.Add("D:20200617223003Z"); * * foreach (var f1 in f) * { * var start = f1.Substring(2); * Console.WriteLine(start); * * var year = start.Substring(0, 4); * var month = start.Substring(4, 2); * var day = start.Substring(6, 2); * var hours = start.Substring(8, 2); * var mins = start.Substring(10, 2); * var sec = start.Substring(12, 2); * var tzi = start.Substring(14); * tzi = tzi.Replace("'", ":").TrimEnd(':'); * * var dateString = $"{month}/{day}/{year}"; * var timeString = $"{hours}:{mins}:{sec}"; * * Console.WriteLine($"{dateString} {timeString} {tzi}"); * * if (tzi.EndsWith("Z")) * { * tzi = "+0:00"; * } * * var aaa = DateTimeOffset.ParseExact($"{dateString} {timeString} {tzi}","MM/dd/yyyy HH:mm:ss zzz",CultureInfo.InvariantCulture); * * var dto = new DateTimeOffset(int.Parse(year),int.Parse(month),int.Parse(day),int.Parse(hours),int.Parse(mins),int.Parse(sec),TimeSpan.Zero); * * Console.WriteLine($"dto: {dto:yyyy-MM-dd HH:mm:ss}"); * Console.WriteLine($"As UTC: {aaa.ToUniversalTime():yyyy-MM-dd HH:mm:ss}"); * }*/ var r = new Adobe(); var reg = new RegistryHive(@"D:\Temp\Adobe_cRecentFiles_NTUSER.DAT"); reg.ParseHive(); var key = reg.GetKey(@"Software\Adobe"); Check.That(r.Values.Count).IsEqualTo(0); r.ProcessValues(key); Check.That(r.Values.Count).IsEqualTo(114); Check.That(r.Errors.Count).IsEqualTo(0); }
public void TerminalServers() { var r = new TerminalServerClient(); var reg = new RegistryHive(@"D:\SynologyDrive\Registry\ALL\NTUSER.DAT"); reg.ParseHive(); var key = reg.GetKey(@"Software\Microsoft\Terminal Server Client"); Check.That(r.Values.Count).IsEqualTo(0); r.ProcessValues(key); Check.That(r.Values.Count).IsEqualTo(6); Check.That(r.Errors.Count).IsEqualTo(0); var ff = (RegistryPlugin.TerminalServerClient.ValuesOut)r.Values[0]; Check.That(ff.MRUPosition).IsEqualTo(1); Check.That(ff.HostName).Contains("GOON"); r = new TerminalServerClient(); reg = new RegistryHive(@"D:\SynologyDrive\Registry\ALL\NTUSER3.DAT"); reg.ParseHive(); key = reg.GetKey(@"Software\Microsoft\Terminal Server Client"); Check.That(r.Values.Count).IsEqualTo(0); r.ProcessValues(key); Check.That(r.Values.Count).IsEqualTo(7); Check.That(r.Errors.Count).IsEqualTo(0); ff = (RegistryPlugin.TerminalServerClient.ValuesOut)r.Values[0]; Check.That(ff.MRUPosition).IsEqualTo(-1); Check.That(ff.HostName).Contains("GOON"); Check.That(ff.LastModified.Month).IsEqualTo(5); Check.That(ff.LastModified.Minute).IsEqualTo(32); Check.That(ff.LastModified.Second).IsEqualTo(8); Check.That(ff.LastModified.Day).IsEqualTo(28); ff = (RegistryPlugin.TerminalServerClient.ValuesOut)r.Values[3]; Check.That(ff.MRUPosition).IsEqualTo(-1); Check.That(ff.HostName).Contains("SVR01"); r = new TerminalServerClient(); reg = new RegistryHive(@"D:\SynologyDrive\Registry\NTUSER_dblake.DAT"); reg.ParseHive(); key = reg.GetKey(@"Software\Microsoft\Terminal Server Client"); Check.That(r.Values.Count).IsEqualTo(0); r.ProcessValues(key); Check.That(r.Values.Count).IsEqualTo(0); Check.That(r.Errors.Count).IsEqualTo(0); }
private static void Main(string[] args) { var testFiles = new List <string>(); var result = Parser.Default.ParseArguments <Options>(args); if (!result.Errors.Any()) { if (result.Value.HiveName == null && result.Value.DirectoryName == null) { Console.WriteLine(result.Value.GetUsage()); Environment.Exit(1); } if (!string.IsNullOrEmpty(result.Value.HiveName)) { if (!string.IsNullOrEmpty(result.Value.DirectoryName)) { Console.WriteLine("Must specify either -d or -f, but not both"); Environment.Exit(1); } } if (!string.IsNullOrEmpty(result.Value.DirectoryName)) { if (!string.IsNullOrEmpty(result.Value.HiveName)) { Console.WriteLine("Must specify either -d or -f, but not both"); Environment.Exit(1); } } if (!string.IsNullOrEmpty(result.Value.HiveName)) { testFiles.Add(result.Value.HiveName); } else { if (Directory.Exists(result.Value.DirectoryName)) { foreach (var file in Directory.GetFiles(result.Value.DirectoryName)) { testFiles.Add(file); } } else { Console.WriteLine("Directory '{0}' does not exist!", result.Value.DirectoryName); Environment.Exit(1); } } } else { Console.WriteLine(result.Value.GetUsage()); Environment.Exit(1); } var verboseLevel = result.Value.VerboseLevel; if (verboseLevel < 0) { verboseLevel = 0; } if (verboseLevel > 2) { verboseLevel = 2; } var config = GetNlogConfig(verboseLevel, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); LogManager.Configuration = config; var logger = LogManager.GetCurrentClassLogger(); foreach (var testFile in testFiles) { if (File.Exists(testFile) == false) { logger.Error("'{0}' does not exist!", testFile); continue; } logger.Info("Processing '{0}'", testFile); Console.Title = $"Processing '{testFile}'"; var sw = new Stopwatch(); try { var registryHive = new RegistryHive(testFile); if (registryHive.Header.ValidateCheckSum() == false) { logger.Warn("CheckSum mismatch!"); } if (registryHive.Header.Sequence1 != registryHive.Header.Sequence2) { logger.Warn("Sequence mismatch!"); } sw.Start(); registryHive.RecoverDeleted = result.Value.RecoverDeleted; registryHive.FlushRecordListsAfterParse = !result.Value.DontFlushLists; registryHive.ParseHive(); logger.Info("Finished processing '{0}'", testFile); Console.Title = $"Finished processing '{testFile}'"; sw.Stop(); var freeCells = registryHive.CellRecords.Where(t => t.Value.IsFree); var referencedCells = registryHive.CellRecords.Where(t => t.Value.IsReferenced); var nkFree = freeCells.Count(t => t.Value is NKCellRecord); var vkFree = freeCells.Count(t => t.Value is VKCellRecord); var skFree = freeCells.Count(t => t.Value is SKCellRecord); var lkFree = freeCells.Count(t => t.Value is LKCellRecord); var freeLists = registryHive.ListRecords.Where(t => t.Value.IsFree); var referencedList = registryHive.ListRecords.Where(t => t.Value.IsReferenced); var goofyCellsShouldBeUsed = registryHive.CellRecords.Where(t => t.Value.IsFree == false && t.Value.IsReferenced == false); var goofyListsShouldBeUsed = registryHive.ListRecords.Where(t => t.Value.IsFree == false && t.Value.IsReferenced == false); var sb = new StringBuilder(); sb.AppendLine("Results:"); sb.AppendLine(); sb.AppendLine( $"Found {registryHive.HBinRecordCount:N0} hbin records. Total size of seen hbin records: 0x{registryHive.HBinRecordTotalSize:X}, Header hive size: 0x{registryHive.Header.Length:X}"); if (registryHive.FlushRecordListsAfterParse == false) { sb.AppendLine( $"Found {registryHive.CellRecords.Count:N0} Cell records (nk: {registryHive.CellRecords.Count(w => w.Value is NKCellRecord):N0}, vk: {registryHive.CellRecords.Count(w => w.Value is VKCellRecord):N0}, sk: {registryHive.CellRecords.Count(w => w.Value is SKCellRecord):N0}, lk: {registryHive.CellRecords.Count(w => w.Value is LKCellRecord):N0})"); sb.AppendLine($"Found {registryHive.ListRecords.Count:N0} List records"); sb.AppendLine(); sb.AppendLine(string.Format($"Header CheckSums match: {registryHive.Header.ValidateCheckSum()}")); sb.AppendLine( string.Format( $"Header sequence 1: {registryHive.Header.Sequence1}, Header sequence 2: {registryHive.Header.Sequence2}")); sb.AppendLine(); sb.AppendLine( $"There are {referencedCells.Count():N0} cell records marked as being referenced ({referencedCells.Count()/(double) registryHive.CellRecords.Count:P})"); sb.AppendLine( $"There are {referencedList.Count():N0} list records marked as being referenced ({referencedList.Count()/(double) registryHive.ListRecords.Count:P})"); if (result.Value.RecoverDeleted) { sb.AppendLine(); sb.AppendLine("Free record info"); sb.AppendLine( $"{freeCells.Count():N0} free Cell records (nk: {nkFree:N0}, vk: {vkFree:N0}, sk: {skFree:N0}, lk: {lkFree:N0})"); sb.AppendLine($"{freeLists.Count():N0} free List records"); } sb.AppendLine(); sb.AppendLine( $"Cells: Free + referenced + marked as in use but not referenced == Total? {registryHive.CellRecords.Count == freeCells.Count() + referencedCells.Count() + goofyCellsShouldBeUsed.Count()}"); sb.AppendLine( $"Lists: Free + referenced + marked as in use but not referenced == Total? {registryHive.ListRecords.Count == freeLists.Count() + referencedList.Count() + goofyListsShouldBeUsed.Count()}"); } sb.AppendLine(); sb.AppendLine( $"There were {registryHive.HardParsingErrors:N0} hard parsing errors (a record marked 'in use' that didn't parse correctly.)"); sb.AppendLine( $"There were {registryHive.SoftParsingErrors:N0} soft parsing errors (a record marked 'free' that didn't parse correctly.)"); logger.Info(sb.ToString()); // foreach (var cellTemplate in fName1Test.ListRecords) // { // Console.WriteLine(cellTemplate.ToString()); // } if (result.Value.ExportHiveData) { Console.WriteLine(); var baseDir = Path.Combine(Path.GetDirectoryName(testFile), "out"); if (Directory.Exists(baseDir) == false) { Directory.CreateDirectory(baseDir); } var baseFname = Path.GetFileName(testFile); var myName = string.Empty; var deletedOnly = result.Value.ExportDeletedOnly; if (deletedOnly) { myName = "_EricZ_recovered.txt"; } else { myName = "_EricZ_all.txt"; } var outfile = Path.Combine(baseDir, $"{baseFname}{myName}"); logger.Info("Exporting hive data to '{0}'", outfile); registryHive.ExportDataToCommonFormat(outfile, deletedOnly); } } catch (Exception ex) { Console.WriteLine("There was an error: {0}", ex.Message); } logger.Info("Processing took {0:N4} seconds\r\n", sw.Elapsed.TotalSeconds); Console.WriteLine(); Console.WriteLine(); if (result.Value.PauseAfterEachFile) { Console.WriteLine("Press any key to continue to next file"); Console.ReadKey(); Console.WriteLine(); Console.WriteLine(); } } }
public void ShouldCatchSlackRecordTooSmallToGetSignatureFrom() { var usrclass = new RegistryHive(@"..\..\Hives\UsrClassJVM.dat"); usrclass.RecoverDeleted = true; usrclass.ParseHive(); }
public AppCompatCache(string filename, int controlSet, bool noLogs) { byte[] rawBytes = null; Caches = new List <IAppCompatCache>(); var controlSetIds = new List <int>(); RegistryKey subKey = null; var isLiveRegistry = string.IsNullOrEmpty(filename); if (isLiveRegistry) { var keyCurrUser = Microsoft.Win32.Registry.LocalMachine; var subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache"); if (subKey2 == null) { subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility"); if (subKey2 == null) { Console.WriteLine( @"'CurrentControlSet\Control\Session Manager\AppCompatCache' key not found! Exiting"); return; } } rawBytes = (byte[])subKey2.GetValue("AppCompatCache", null); subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\Select"); ControlSet = (int)subKey2.GetValue("Current"); var is32Bit = Is32Bit(filename, null); var cache = Init(rawBytes, is32Bit, ControlSet); Caches.Add(cache); return; } RegistryHive reg; Privilege[] privileges = { Privilege.EnableDelegation, Privilege.Impersonate, Privilege.Tcb }; using (new PrivilegeEnabler(Privilege.Backup, privileges)) { ControlSet = controlSet; if (File.Exists(filename) == false && Helper.RawFileExists(filename) == false) { throw new FileNotFoundException($"File not found ({filename})!"); } var dirname = Path.GetDirectoryName(Path.GetFullPath(filename)); var hiveBase = Path.GetFileName(filename); List <RawCopyReturn> rawFiles = null; try { reg = new RegistryHive(filename) { RecoverDeleted = true }; } catch (IOException) { //file is in use if (Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } _logger.Warn($"'{filename}' is in use. Rerouting...\r\n"); var files = new List <string>(); files.Add(filename); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList(); var log1 = $"{dirname}\\{hiveBase}.LOG1"; var log2 = $"{dirname}\\{hiveBase}.LOG2"; if (logFiles.Count == 0) { if (Helper.RawFileExists(log1)) { logFiles.Add(log1); } if (Helper.RawFileExists(log2)) { logFiles.Add(log2); } } foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = Helper.GetFiles(files); reg = new RegistryHive(rawFiles.First().FileBytes, rawFiles.First().InputFilename); } if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList(); var log1 = $"{dirname}\\{hiveBase}.LOG1"; var log2 = $"{dirname}\\{hiveBase}.LOG2"; if (logFiles.Count == 0) { if (File.Exists(log1)) { logFiles.Add(log1); } if (File.Exists(log2)) { logFiles.Add(log2); } } if (logFiles.Count == 0) { if (Helper.IsAdministrator()) { if (Helper.RawFileExists(log1)) { logFiles.Add(log1); } if (Helper.RawFileExists(log2)) { logFiles.Add(log2); } } else { _logger.Fatal($"Log files not found and no administrator access to look for them!"); Console.WriteLine(); } } if (logFiles.Count == 0) { if (noLogs == false) { _logger.Warn( "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception( "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } _logger.Warn( "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } else { if (noLogs == false) { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, rawCopyReturn.FileBytes); lt.Add(tt); } reg.ProcessTransactionLogs(lt, true); } else { reg.ProcessTransactionLogs(logFiles.ToList(), true); } } else { _logger.Warn( "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways..."); } } } reg.ParseHive(); } if (controlSet == -1) { for (var i = 0; i < 10; i++) { subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatibility"); } if (subKey != null) { controlSetIds.Add(i); } } if (controlSetIds.Count > 1) { _logger.Warn( $"***The following ControlSet00x keys will be exported: {string.Join(",", controlSetIds)}. Use -c to process keys individually\r\n"); } } else { //a control set was passed in subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatibility"); } if (subKey == null) { throw new Exception($"Could not find ControlSet00{ControlSet}. Exiting"); } controlSetIds.Add(ControlSet); } var is32 = Is32Bit(filename, reg); _logger.Debug($@"**** Found {controlSetIds.Count} ids to process"); foreach (var id in controlSetIds) { _logger.Debug($@"**** Processing id {id}"); // var hive2 = new RegistryHiveOnDemand(filename); subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatCache"); if (subKey == null) { _logger.Debug(@"**** Initial subkey null, getting appCompatability key"); subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatibility"); } _logger.Debug(@"**** Looking AppCompatcache value"); var val = subKey?.Values.SingleOrDefault(c => c.ValueName == "AppCompatCache"); if (val != null) { _logger.Debug(@"**** Found AppCompatcache value"); rawBytes = val.ValueDataRaw; } if (rawBytes == null) { _logger.Error($@"'AppCompatCache' value not found for 'ControlSet00{id}'! Exiting"); } var cache = Init(rawBytes, is32, id); Caches.Add(cache); } }
public void ShouldFindADBRecordWhileParsing() { var usrclass = new RegistryHive(@"..\..\Hives\SYSTEM"); usrclass.ParseHive(); }
public void ShouldFindAdbRecordWhileParsing() { var usrclass = new RegistryHive(@"..\..\..\Hives\SYSTEM"); usrclass.ParseHive(); }
public void ExportUsrClassToCommonFormatWithDeleted() { var UsrclassDeleted = new RegistryHive(@"..\..\Hives\UsrClassDeletedBags.dat"); UsrclassDeleted.RecoverDeleted = true; UsrclassDeleted.FlushRecordListsAfterParse = false; UsrclassDeleted.ParseHive(); UsrclassDeleted.ExportDataToCommonFormat("UsrClassDeletedExport.txt", true); UsrclassDeleted = new RegistryHive(@"..\..\Hives\UsrClassDeletedBags.dat"); UsrclassDeleted.FlushRecordListsAfterParse = true; UsrclassDeleted.ParseHive(); UsrclassDeleted.ExportDataToCommonFormat("UsrClassDeletedWithFlushExport.txt", true); }
public AmcacheNew(string hive, bool recoverDeleted, bool noLogs) { _logger = LogManager.GetCurrentClassLogger(); RegistryHive reg; var dirname = Path.GetDirectoryName(hive); var hiveBase = Path.GetFileName(hive); List <RawCopyReturn> rawFiles = null; try { reg = new RegistryHive(hive) { RecoverDeleted = true }; } catch (IOException) { //file is in use if (RawCopy.Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } _logger.Warn($"'{hive}' is in use. Rerouting...\r\n"); var files = new List <string>(); files.Add(hive); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = RawCopy.Helper.GetFiles(files); var b = new byte[rawFiles.First().FileStream.Length]; rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length); reg = new RegistryHive(b, rawFiles.First().InputFilename); } if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); var log = LogManager.GetCurrentClassLogger(); if (logFiles.Length == 0) { if (noLogs == false) { log.Warn( "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception( "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } log.Warn( "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } else { if (noLogs == false) { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var b = new byte[rawCopyReturn.FileStream.Length]; rawCopyReturn.FileStream.Read(b, 0, (int)rawCopyReturn.FileStream.Length); var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, b); lt.Add(tt); } reg.ProcessTransactionLogs(lt, true); } else { reg.ProcessTransactionLogs(logFiles.ToList(), true); } } else { log.Warn( "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways..."); } } } reg.ParseHive(); var fileKey = reg.GetKey(@"Root\InventoryApplicationFile"); var programsKey = reg.GetKey(@"Root\InventoryApplication"); UnassociatedFileEntries = new List <FileEntryNew>(); ProgramsEntries = new List <ProgramsEntryNew>(); DeviceContainers = new List <DeviceContainer>(); DevicePnps = new List <DevicePnp>(); DriveBinaries = new List <DriverBinary>(); DriverPackages = new List <DriverPackage>(); ShortCuts = new List <Shortcut>(); _logger.Debug("Getting Programs data"); if (programsKey != null) { foreach (var registryKey in programsKey.SubKeys) { var bundleManifestPath = string.Empty; var hiddenArp = false; var inboxModernApp = false; DateTimeOffset?installDate = null; var language = 0; var manifestPath = string.Empty; var msiPackageCode = string.Empty; var msiProductCode = string.Empty; var name = string.Empty; var osVersionAtInstallTime = string.Empty; var packageFullName = string.Empty; var programId = string.Empty; var programInstanceId = string.Empty; var publisher = string.Empty; var registryKeyPath = string.Empty; var rootDirPath = string.Empty; var source = string.Empty; var storeAppType = string.Empty; var type = string.Empty; var uninstallString = string.Empty; var version = string.Empty; var installDateArpLastModified = string.Empty; DateTimeOffset?installDateMsi = null; var installDateFromLinkFile = string.Empty; var manufacturer = string.Empty; var driverVerVersion = string.Empty; try { foreach (var registryKeyValue in registryKey.Values) { switch (registryKeyValue.ValueName) { case "BundleManifestPath": bundleManifestPath = registryKeyValue.ValueData; break; case "HiddenArp": hiddenArp = registryKeyValue.ValueData == "1"; break; case "InboxModernApp": inboxModernApp = registryKeyValue.ValueData == "1"; break; case "InstallDate": if (registryKeyValue.ValueData.Length > 0) { // _logger.Warn($"registryKeyValue.ValueData for InstallDate as InvariantCulture: {registryKeyValue.ValueData.ToString(CultureInfo.InvariantCulture)}"); var d = new DateTimeOffset( DateTime.Parse(registryKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo) .Ticks, TimeSpan.Zero); installDate = d; } break; case "Language": if (registryKeyValue.ValueData.Length == 0) { language = 0; } else { language = int.Parse(registryKeyValue.ValueData); } break; case "ManifestPath": manifestPath = registryKeyValue.ValueData; break; case "MsiPackageCode": msiPackageCode = registryKeyValue.ValueData; break; case "MsiProductCode": msiProductCode = registryKeyValue.ValueData; break; case "Name": name = registryKeyValue.ValueData; break; case "OSVersionAtInstallTime": osVersionAtInstallTime = registryKeyValue.ValueData; break; case "PackageFullName": packageFullName = registryKeyValue.ValueData; break; case "ProgramId": programId = registryKeyValue.ValueData; break; case "ProgramInstanceId": programInstanceId = registryKeyValue.ValueData; break; case "Publisher": publisher = registryKeyValue.ValueData; break; case "RegistryKeyPath": registryKeyPath = registryKeyValue.ValueData; break; case "RootDirPath": rootDirPath = registryKeyValue.ValueData; break; case "Source": source = registryKeyValue.ValueData; break; case "StoreAppType": storeAppType = registryKeyValue.ValueData; break; case "Type": type = registryKeyValue.ValueData; break; case "UninstallString": uninstallString = registryKeyValue.ValueData; break; case "Version": version = registryKeyValue.ValueData; break; case "InstallDateArpLastModified": if (registryKeyValue.ValueData.Length > 0) { installDateArpLastModified = registryKeyValue.ValueData; } break; case "InstallDateMsi": if (registryKeyValue.ValueData.Length > 0) { // _logger.Warn($"registryKeyValue.ValueData for InstallDate as InvariantCulture: {registryKeyValue.ValueData.ToString(CultureInfo.InvariantCulture)}"); var d = new DateTimeOffset( DateTime.Parse(registryKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo) .Ticks, TimeSpan.Zero); installDateMsi = d; } break; case "InstallDateFromLinkFile": if (registryKeyValue.ValueData.Length > 0) { installDateFromLinkFile = registryKeyValue.ValueData; } break; case "DriverVerVersion": case "BusReportedDescription": case "HWID": case "COMPID": case "STACKID": case "UpperClassFilters": case "UpperFilters": case "LowerFilters": case "BinFileVersion": case "(default)": break; case "Manufacturer": if (registryKeyValue.ValueData.Length > 0) { manufacturer = registryKeyValue.ValueData; } break; default: _logger.Warn( $"Unknown value name in InventoryApplication at path {registryKey.KeyPath}: {registryKeyValue.ValueName}"); break; } } var pe = new ProgramsEntryNew(bundleManifestPath, hiddenArp, inboxModernApp, installDate, language, manifestPath, msiPackageCode, msiProductCode, name, osVersionAtInstallTime, packageFullName, programId, programInstanceId, publisher, registryKeyPath, rootDirPath, source, storeAppType, type, uninstallString, version, registryKey.LastWriteTime.Value, installDateArpLastModified, installDateMsi, installDateFromLinkFile, manufacturer); ProgramsEntries.Add(pe); } catch (Exception ex) { if (registryKey.NkRecord.IsFree == false) { _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}"); } } } } else { _logger.Warn("Hive does not contain a Root\\InventoryApplication key."); } _logger.Debug("Getting Files data"); if (fileKey != null) { foreach (var subKey in fileKey.SubKeys) { var binaryType = string.Empty; var binFileVersion = string.Empty; var binProductVersion = string.Empty; var fileId = string.Empty; var isOsComponent = false; var isPeFile = false; var language = 0; DateTimeOffset?linkDate = null; var longPathHash = string.Empty; var lowerCaseLongPath = string.Empty; var name = string.Empty; var productName = string.Empty; var productVersion = string.Empty; var programId = string.Empty; var publisher = string.Empty; long size = 0; ulong usn = 0; var version = string.Empty; var description = string.Empty; var hasLinkedProgram = false; try { foreach (var subKeyValue in subKey.Values) { switch (subKeyValue.ValueName) { case "BinaryType": binaryType = subKeyValue.ValueData; break; case "BinFileVersion": binFileVersion = subKeyValue.ValueData; break; case "BinProductVersion": binProductVersion = subKeyValue.ValueData; break; case "FileId": fileId = subKeyValue.ValueData; break; case "IsOsComponent": isOsComponent = subKeyValue.ValueData == "1"; break; case "IsPeFile": isPeFile = subKeyValue.ValueData == "1"; break; case "Language": language = int.Parse(subKeyValue.ValueData); break; case "LinkDate": if (subKeyValue.ValueData.Length > 0) { var d = new DateTimeOffset( DateTime.Parse(subKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo) .Ticks, TimeSpan.Zero); linkDate = d; } break; case "LongPathHash": longPathHash = subKeyValue.ValueData; break; case "LowerCaseLongPath": lowerCaseLongPath = subKeyValue.ValueData; break; case "Name": name = subKeyValue.ValueData; break; case "ProductName": productName = subKeyValue.ValueData; break; case "ProductVersion": productVersion = subKeyValue.ValueData; break; case "ProgramId": programId = subKeyValue.ValueData; var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == programId); if (program != null) { hasLinkedProgram = true; } break; case "Publisher": publisher = subKeyValue.ValueData; break; case "Size": try { if (subKeyValue.ValueData.StartsWith("0x")) { size = long.Parse(subKeyValue.ValueData.Replace("0x", ""), NumberStyles.HexNumber); } else { size = long.Parse(subKeyValue.ValueData); } } catch (Exception e) { } break; case "BusReportedDescription": case "FileSize": case "Model": case "Manufacturer": case "ParentId": case "MatchingID": case "ClassGuid": case "DriverName": case "Enumerator": case "Service": case "DeviceState": case "InstallState": case "DriverVerVersion": case "DriverPackageStrongName": case "DriverVerDate": case "ContainerId": case "HiddenArp": case "Inf": case "ProblemCode": case "Provider": case "Class": break; case "Description": description = subKeyValue.ValueData; break; case "Version": version = subKeyValue.ValueData; break; case "Usn": usn = ulong.Parse(subKeyValue.ValueData); break; default: if (subKeyValue.VkRecord.IsFree == false) { _logger.Warn( $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': {subKeyValue.ValueName}"); } break; } } } catch (Exception ex) { if (subKey.NkRecord.IsFree == false) { _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}"); } } TotalFileEntries += 1; var fe = new FileEntryNew(binaryType, binFileVersion, productVersion, fileId, isOsComponent, isPeFile, language, linkDate, longPathHash, lowerCaseLongPath, name, productName, productVersion, programId, publisher, size, version, subKey.LastWriteTime.Value, binProductVersion, usn, description); if (hasLinkedProgram) { var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == fe.ProgramId); if (program != null) { fe.ApplicationName = program.Name; program.FileEntries.Add(fe); } } else { fe.ApplicationName = "Unassociated"; UnassociatedFileEntries.Add(fe); } } } else { _logger.Warn("Hive does not contain a Root\\InventoryApplicationFile key."); } _logger.Debug("Getting Shortcut data"); var shortCutkey = reg.GetKey(@"Root\InventoryApplicationShortcut"); if (shortCutkey != null) { foreach (var shortCutkeySubKey in shortCutkey.SubKeys) { var lnkName = ""; if (shortCutkeySubKey.Values.Count > 0) { lnkName = shortCutkeySubKey.Values.First().ValueData; } ShortCuts.Add(new Shortcut(shortCutkeySubKey.KeyName, lnkName, shortCutkeySubKey.LastWriteTime.Value)); } } _logger.Debug("Getting InventoryDeviceContainer data"); var deviceKey = reg.GetKey(@"Root\InventoryDeviceContainer"); if (deviceKey != null) { foreach (var deviceSubKey in deviceKey.SubKeys) { var categories = string.Empty; var discoveryMethod = string.Empty; var friendlyName = string.Empty; var icon = string.Empty; var isActive = false; var isConnected = false; var isMachineContainer = false; var isNetworked = false; var isPaired = false; var manufacturer = string.Empty; var modelId = string.Empty; var modelName = string.Empty; var modelNumber = string.Empty; var primaryCategory = string.Empty; var state = string.Empty; try { foreach (var keyValue in deviceSubKey.Values) { switch (keyValue.ValueName) { case "Categories": categories = keyValue.ValueData; break; case "DiscoveryMethod": discoveryMethod = keyValue.ValueData; break; case "FriendlyName": friendlyName = keyValue.ValueData; break; case "Icon": icon = keyValue.ValueData; break; case "IsActive": isActive = keyValue.ValueData == "1"; break; case "IsConnected": isConnected = keyValue.ValueData == "1"; break; case "IsMachineContainer": isMachineContainer = keyValue.ValueData == "1"; break; case "IsNetworked": isNetworked = keyValue.ValueData == "1"; break; case "IsPaired": isPaired = keyValue.ValueData == "1"; break; case "Manufacturer": manufacturer = keyValue.ValueData; break; case "ModelId": modelId = keyValue.ValueData; break; case "ModelName": modelName = keyValue.ValueData; break; case "ModelNumber": modelNumber = keyValue.ValueData; break; case "PrimaryCategory": primaryCategory = keyValue.ValueData; break; case "State": state = keyValue.ValueData; break; case "(default)": case "Model": case "BusReportedDescription": case "Version": case "LowerClassFilters": case "ManifestPath": case "UpperClassFilters": break; default: _logger.Warn( $"Unknown value name when processing DeviceContainer at path '{deviceSubKey.KeyPath}': {keyValue.ValueName}"); break; } } var dc = new DeviceContainer(deviceSubKey.KeyName, deviceSubKey.LastWriteTime.Value, categories, discoveryMethod, friendlyName, icon, isActive, isConnected, isMachineContainer, isNetworked, isPaired, manufacturer, modelId, modelName, modelNumber, primaryCategory, state); DeviceContainers.Add(dc); } catch (Exception ex) { if (deviceSubKey.NkRecord.IsFree == false) { _logger.Error( $"Error parsing DeviceContainer at {deviceSubKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {deviceSubKey}"); } } } } _logger.Debug("Getting InventoryDevicePnp data"); var pnpKey = reg.GetKey(@"Root\InventoryDevicePnp"); if (pnpKey != null) { foreach (var pnpsKey in pnpKey.SubKeys) { var busReportedDescription = string.Empty; var Class = string.Empty; var classGuid = string.Empty; var compid = string.Empty; var containerId = string.Empty; var description = string.Empty; var deviceState = string.Empty; var driverId = string.Empty; var driverName = string.Empty; var driverPackageStrongName = string.Empty; var driverVerDate = string.Empty; var driverVerVersion = string.Empty; var enumerator = string.Empty; var hwid = string.Empty; var inf = string.Empty; var installState = string.Empty; var manufacturer = string.Empty; var matchingId = string.Empty; var model = string.Empty; var parentId = string.Empty; var problemCode = string.Empty; var provider = string.Empty; var service = string.Empty; var stackid = string.Empty; try { foreach (var keyValue in pnpsKey.Values) { switch (keyValue.ValueName) { case "BusReportedDescription": busReportedDescription = keyValue.ValueData; break; case "Class": Class = keyValue.ValueData; break; case "ClassGuid": classGuid = keyValue.ValueData; break; case "COMPID": compid = keyValue.ValueData; break; case "ContainerId": containerId = keyValue.ValueData; break; case "Description": description = keyValue.ValueData; break; case "DeviceState": deviceState = keyValue.ValueData; break; case "DriverId": driverId = keyValue.ValueData; break; case "DriverName": driverName = keyValue.ValueData; break; case "DriverPackageStrongName": driverPackageStrongName = keyValue.ValueData; break; case "DriverVerDate": driverVerDate = keyValue.ValueData; break; case "DriverVerVersion": driverVerVersion = keyValue.ValueData; break; case "Enumerator": enumerator = keyValue.ValueData; break; case "HWID": hwid = keyValue.ValueData; break; case "Inf": inf = keyValue.ValueData; break; case "InstallState": installState = keyValue.ValueData; break; case "LowerClassFilters": case "LowerFilters": break; case "Manufacturer": manufacturer = keyValue.ValueData; break; case "MatchingID": matchingId = keyValue.ValueData; break; case "Model": model = keyValue.ValueData; break; case "ParentId": parentId = keyValue.ValueData; break; case "ProblemCode": problemCode = keyValue.ValueData; break; case "Provider": provider = keyValue.ValueData; break; case "Service": service = keyValue.ValueData; break; case "STACKID": stackid = keyValue.ValueData; break; case "UpperClassFilters": case "UpperFilters": case "ExtendedInfs": case "DeviceInterfaceClasses": case "(default)": case "DeviceExtDriversFlightIds": case "InstallDate": case "FirstInstallDate": case "DeviceDriverFlightId": _logger.Debug($"Value: '{keyValue.ValueName}' --> {keyValue.ValueData}"); break; default: _logger.Warn( $"Unknown value name when processing DevicePnp at path '{pnpsKey.KeyPath}': {keyValue.ValueName}"); break; } } var dp = new DevicePnp(pnpsKey.KeyName, pnpsKey.LastWriteTime.Value, busReportedDescription, Class, classGuid, compid, containerId, description, deviceState, driverId, driverName, driverPackageStrongName, driverVerDate, driverVerVersion, enumerator, hwid, inf, installState, manufacturer, matchingId, model, parentId, problemCode, provider, service, stackid); DevicePnps.Add(dp); } catch (Exception ex) { if (pnpKey.NkRecord.IsFree == false) { _logger.Error($"Error parsing DevicePnp at {pnpKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {pnpKey}"); } } } } _logger.Debug("Getting InventoryDriverBinary data"); var binaryKey = reg.GetKey(@"Root\InventoryDriverBinary"); if (binaryKey != null) { foreach (var binKey in binaryKey.SubKeys) { var driverCheckSum = 0; var driverCompany = string.Empty; var driverId = string.Empty; var driverInBox = false; var driverIsKernelMode = false; DateTimeOffset?driverLastWriteTime = null; var driverName = string.Empty; var driverPackageStrongName = string.Empty; var driverSigned = false; DateTimeOffset?driverTimeStamp = null; var driverType = string.Empty; var driverVersion = string.Empty; var imageSize = 0; var inf = string.Empty; var product = string.Empty; var productVersion = string.Empty; var service = string.Empty; var wdfVersion = string.Empty; try { foreach (var keyValue in binKey.Values) { switch (keyValue.ValueName) { case "DriverCheckSum": driverCheckSum = int.Parse(keyValue.ValueData); break; case "DriverCompany": driverCompany = keyValue.ValueData; break; case "DriverId": driverId = keyValue.ValueData; break; case "DriverInBox": driverInBox = keyValue.ValueData == "1"; break; case "DriverIsKernelMode": driverIsKernelMode = keyValue.ValueData == "1"; break; case "DriverLastWriteTime": if (keyValue.ValueData.Length > 0) { var d = new DateTimeOffset( DateTime.Parse(keyValue.ValueData, DateTimeFormatInfo.InvariantInfo).Ticks, TimeSpan.Zero); driverLastWriteTime = d; } break; case "DriverName": driverName = keyValue.ValueData; break; case "DriverPackageStrongName": driverPackageStrongName = keyValue.ValueData; break; case "DriverSigned": driverSigned = keyValue.ValueData == "1"; break; case "DriverTimeStamp": //DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); var seca = long.Parse(keyValue.ValueData); if (seca > 0) { driverTimeStamp = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime(); } break; case "DriverType": driverType = keyValue.ValueData; break; case "DriverVersion": driverVersion = keyValue.ValueData; break; case "ImageSize": imageSize = int.Parse(keyValue.ValueData); break; case "Inf": inf = keyValue.ValueData; break; case "Product": product = keyValue.ValueData; break; case "ProductVersion": productVersion = keyValue.ValueData; break; case "Service": service = keyValue.ValueData; break; case "WdfVersion": wdfVersion = keyValue.ValueData; break; case "(default)": case "COMPID": case "HWID": break; default: _logger.Warn( $"Unknown value name when processing DriverBinary at path '{binKey.KeyPath}': {keyValue.ValueName}"); break; } } var db = new DriverBinary(binKey.KeyName, binKey.LastWriteTime.Value, driverCheckSum, driverCompany, driverId, driverInBox, driverIsKernelMode, driverLastWriteTime, driverName, driverPackageStrongName, driverSigned, driverTimeStamp, driverType, driverVersion, imageSize, inf, product, productVersion, service, wdfVersion); DriveBinaries.Add(db); } catch (Exception ex) { if (binaryKey.NkRecord.IsFree == false) { _logger.Error($"Error parsing DriverBinary at {binaryKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {binaryKey}"); } } } } _logger.Debug("Getting InventoryDriverPackage data"); var packaheKey = reg.GetKey(@"Root\InventoryDriverPackage"); if (packaheKey != null) { foreach (var packKey in packaheKey.SubKeys) { var Class = string.Empty; var ClassGuid = string.Empty; DateTimeOffset?Date = null; var Directory = string.Empty; var DriverInBox = false; var Hwids = string.Empty; var Inf = string.Empty; var Provider = string.Empty; var SubmissionId = string.Empty; var SYSFILE = string.Empty; var Version = string.Empty; try { foreach (var keyValue in packKey.Values) { switch (keyValue.ValueName) { case "Class": Class = keyValue.ValueData; break; case "ClassGuid": ClassGuid = keyValue.ValueData; break; case "Date": if (keyValue.ValueData.Length > 0) { var d = new DateTimeOffset( DateTime.Parse(keyValue.ValueData, DateTimeFormatInfo.InvariantInfo).Ticks, TimeSpan.Zero); Date = d; } break; case "Directory": Directory = keyValue.ValueData; break; case "DriverInBox": DriverInBox = keyValue.ValueData == "1"; break; case "Hwids": Hwids = keyValue.ValueData; break; case "Inf": Inf = keyValue.ValueData; break; case "Provider": Provider = keyValue.ValueData; break; case "SubmissionId": SubmissionId = keyValue.ValueData; break; case "SYSFILE": SYSFILE = keyValue.ValueData; break; case "Version": Version = keyValue.ValueData; break; case "IsActive": break; default: _logger.Warn( $"Unknown value name when processing DriverPackage at path '{packKey.KeyPath}': {keyValue.ValueName}"); break; } } var dp = new DriverPackage(packKey.KeyName, packKey.LastWriteTime.Value, Class, ClassGuid, Date, Directory, DriverInBox, Hwids, Inf, Provider, SubmissionId, SYSFILE, Version); DriverPackages.Add(dp); } catch (Exception ex) { if (packaheKey.NkRecord.IsFree == false) { _logger.Error($"Error parsing DriverPackage at {packaheKey.KeyPath}. Error: {ex.Message}"); _logger.Error( $"Please send the following text to [email protected]. \r\n\r\nKey data: {packaheKey}"); } } } } }