public void OneOff() { var foo = File.ReadAllBytes(@"C:\Users\eric\Desktop\SYSTEM"); var a = new AppCompatCache.AppCompatCache(foo, 1, true); }
private static void DoWork(string f, string csv, string csvf, int c, bool t, string dt, bool nl, bool debug, bool trace) { var levelSwitch = new LoggingLevelSwitch(); var template = "{Message:lj}{NewLine}{Exception}"; if (debug) { levelSwitch.MinimumLevel = LogEventLevel.Debug; template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}"; } if (trace) { levelSwitch.MinimumLevel = LogEventLevel.Verbose; template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}"; } var conf = new LoggerConfiguration() .WriteTo.Console(outputTemplate: template) .MinimumLevel.ControlledBy(levelSwitch); Log.Logger = conf.CreateLogger(); var hiveToProcess = "Live Registry"; if (f?.Length > 0) { hiveToProcess = f; if (!File.Exists(f)) { Log.Warning("'{F}' not found. Exiting", f); return; } } else { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Log.Fatal("Live Registry support is not available on non-Windows systems"); Environment.Exit(0); //throw new NotSupportedException("Live Registry support is not available on non-Windows systems"); } } Log.Information("{Header}", Header); Console.WriteLine(); Log.Information("Command line: {Args}", string.Join(" ", _args)); Console.WriteLine(); if (IsAdministrator() == false) { Log.Fatal($"Warning: Administrator privileges not found!"); Console.WriteLine(); } Log.Information("Processing hive '{HiveToProcess}'", hiveToProcess); Console.WriteLine(); try { var appCompat = new AppCompatCache.AppCompatCache(f, c, nl); string outFileBase; var ts1 = DateTime.Now.ToString("yyyyMMddHHmmss"); if (f?.Length > 0) { if (c >= 0) { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(f)}_ControlSet00{c}_AppCompatCache.csv"; } else { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(f)}_AppCompatCache.csv"; } } else { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Environment.MachineName}_AppCompatCache.csv"; } if (csvf.IsNullOrEmpty() == false) { outFileBase = Path.GetFileName(csvf); } if (Directory.Exists(csv) == false) { Directory.CreateDirectory(csv !); } var outFilename = Path.Combine(csv, outFileBase); var sw = new StreamWriter(outFilename); var csvWriter = new CsvWriter(sw, CultureInfo.InvariantCulture); var foo = csvWriter.Context.AutoMap <CacheEntry>(); var o = new TypeConverterOptions { DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal }; csvWriter.Context.TypeConverterOptionsCache.AddOptions <CacheEntry>(o); foo.Map(entry => entry.LastModifiedTimeUTC).Convert(entry => entry.Value.LastModifiedTimeUTC.HasValue ? entry.Value.LastModifiedTimeUTC.Value.ToString(dt): ""); foo.Map(entry => entry.CacheEntrySize).Ignore(); foo.Map(entry => entry.Data).Ignore(); foo.Map(entry => entry.InsertFlags).Ignore(); foo.Map(entry => entry.DataSize).Ignore(); foo.Map(entry => entry.LastModifiedFILETIMEUTC).Ignore(); foo.Map(entry => entry.PathSize).Ignore(); foo.Map(entry => entry.Signature).Ignore(); foo.Map(entry => entry.ControlSet).Index(0); foo.Map(entry => entry.CacheEntryPosition).Index(1); foo.Map(entry => entry.Path).Index(2); foo.Map(entry => entry.LastModifiedTimeUTC).Index(3); foo.Map(entry => entry.Executed).Index(4); foo.Map(entry => entry.Duplicate).Index(5); foo.Map(entry => entry.SourceFile).Index(6); csvWriter.WriteHeader <CacheEntry>(); csvWriter.NextRecord(); Log.Debug("**** Found {Count} caches", appCompat.Caches.Count); var cacheKeys = new HashSet <string>(); if (appCompat.Caches.Any()) { foreach (var appCompatCach in appCompat.Caches) { Log.Verbose("Dumping cache details: {@Details}", appCompat); try { Log.Information( "Found {Count:N0} cache entries for {OperatingSystem} in {ControlSet}", appCompatCach.Entries.Count, appCompat.OperatingSystem, $"ControlSet00{appCompatCach.ControlSet}"); if (t) { foreach (var cacheEntry in appCompatCach.Entries) { cacheEntry.SourceFile = hiveToProcess; cacheEntry.Duplicate = cacheKeys.Contains(cacheEntry.GetKey()); cacheKeys.Add(cacheEntry.GetKey()); csvWriter.WriteRecord(cacheEntry); csvWriter.NextRecord(); } } else { foreach (var cacheEntry in appCompatCach.Entries) { cacheEntry.SourceFile = hiveToProcess; cacheEntry.Duplicate = cacheKeys.Contains(cacheEntry.GetKey()); cacheKeys.Add(cacheEntry.GetKey()); csvWriter.WriteRecord(cacheEntry); csvWriter.NextRecord(); } } } catch (Exception ex) { Log.Error(ex, "There was an error: Error message: {Message}", ex.Message); try { appCompatCach.PrintDump(); } catch (Exception ex1) { Log.Error(ex1, "Couldn't PrintDump: {Message}", ex1.Message); } } } sw.Flush(); sw.Close(); Console.WriteLine(); Log.Warning("Results saved to '{OutFilename}'", outFilename); Console.WriteLine(); } else { Console.WriteLine(); Log.Warning("No caches were found!"); Console.WriteLine(); } } catch (Exception ex) { if (ex.Message.Contains("Sequence numbers do not match and transaction logs were not found in the same direct") == false) { if (ex.Message.Contains("Administrator privileges not found")) { Log.Fatal("Could not access '{F}'. Does it exist?", f); Console.WriteLine(); Log.Fatal("Rerun the program with Administrator privileges to try again"); Console.WriteLine(); } else if (ex.Message.Contains("Invalid diskName:")) { Log.Fatal("Could not access '{F}'. Invalid disk!", f); Console.WriteLine(); } else { Log.Error(ex, "There was an error: {Message}", ex.Message); Console.WriteLine(); } } } }
private static void Main(string[] args) { ExceptionlessClient.Default.Startup("7iL4b0Me7W8PbFflftqWgfQCIdf55flrT2O11zIP"); SetupNLog(); var logger = LogManager.GetCurrentClassLogger(); _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>(); _fluentCommandLineParser.Setup(arg => arg.CsvDirectory) .As("csv") .WithDescription("Directory to save CSV formatted results to. Required") .Required(); _fluentCommandLineParser.Setup(arg => arg.CsvName) .As("csvf") .WithDescription("File name to save CSV formatted results to. When present, overrides default name\r\n"); _fluentCommandLineParser.Setup(arg => arg.HiveFile) .As('f') .WithDescription( "Full path to SYSTEM hive to process. If this option is not specified, the live Registry will be used") .SetDefault(string.Empty); _fluentCommandLineParser.Setup(arg => arg.SortTimestamps) .As('t') .WithDescription("Sorts last modified timestamps in descending order\r\n") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.ControlSet) .As('c') .WithDescription("The ControlSet to parse. Default is to extract all control sets.") .SetDefault(-1); _fluentCommandLineParser.Setup(arg => arg.Debug) .As("debug") .WithDescription("Debug mode") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.DateTimeFormat) .As("dt") .WithDescription( "The custom date/time format to use when displaying timestamps. See https://goo.gl/CNVq0k for options. Default is: yyyy-MM-dd HH:mm:ss") .SetDefault("yyyy-MM-dd HH:mm:ss"); _fluentCommandLineParser.Setup(arg => arg.NoTransLogs) .As("nl") .WithDescription( "When true, ignore transaction log files for dirty hives. Default is FALSE").SetDefault(false); var header = $"AppCompatCache Parser version {Assembly.GetExecutingAssembly().GetName().Version}" + $"\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + $"\r\nhttps://github.com/EricZimmerman/AppCompatCacheParser"; var footer = @"Examples: AppCompatCacheParser.exe --csv c:\temp -t -c 2" + "\r\n\t " + @" AppCompatCacheParser.exe --csv c:\temp --csvf results.csv" + "\r\n\t " + "\r\n\t" + " Short options (single letter) are prefixed with a single dash. Long commands are prefixed with two dashes\r\n"; _fluentCommandLineParser.SetupHelp("?", "help").WithHeader(header).Callback(text => logger.Info(text + "\r\n" + footer)); var result = _fluentCommandLineParser.Parse(args); if (result.HelpCalled) { return; } if (result.HasErrors) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } var hiveToProcess = "Live Registry"; if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { hiveToProcess = _fluentCommandLineParser.Object.HiveFile; } logger.Info(header); logger.Info(""); logger.Info($"Command line: {string.Join(" ", Environment.GetCommandLineArgs().Skip(1))}\r\n"); if (IsAdministrator() == false) { logger.Fatal($"Warning: Administrator privileges not found!\r\n"); } logger.Info($"Processing hive '{hiveToProcess}'"); logger.Info(""); if (_fluentCommandLineParser.Object.Debug) { LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Debug); } try { var appCompat = new AppCompatCache.AppCompatCache(_fluentCommandLineParser.Object.HiveFile, _fluentCommandLineParser.Object.ControlSet, _fluentCommandLineParser.Object.NoTransLogs); var outFileBase = string.Empty; var ts1 = DateTime.Now.ToString("yyyyMMddHHmmss"); if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { if (_fluentCommandLineParser.Object.ControlSet >= 0) { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.HiveFile)}_ControlSet00{_fluentCommandLineParser.Object.ControlSet}_AppCompatCache.csv"; } else { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.HiveFile)}_AppCompatCache.csv"; } } else { outFileBase = $"{ts1}_{appCompat.OperatingSystem}_{Environment.MachineName}_AppCompatCache.csv"; } if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false) { outFileBase = Path.GetFileName(_fluentCommandLineParser.Object.CsvName); } if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false) { Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory); } var outFilename = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outFileBase); var sw = new StreamWriter(outFilename); var csv = new CsvWriter(sw, CultureInfo.InvariantCulture); var foo = csv.Context.AutoMap <CacheEntry>(); var o = new TypeConverterOptions { DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal }; csv.Context.TypeConverterOptionsCache.AddOptions <CacheEntry>(o); foo.Map(t => t.LastModifiedTimeUTC).Convert(t => t.Value.LastModifiedTimeUTC.HasValue ? t.Value.LastModifiedTimeUTC.Value.ToString(_fluentCommandLineParser.Object.DateTimeFormat): ""); foo.Map(t => t.CacheEntrySize).Ignore(); foo.Map(t => t.Data).Ignore(); foo.Map(t => t.InsertFlags).Ignore(); foo.Map(t => t.DataSize).Ignore(); foo.Map(t => t.LastModifiedFILETIMEUTC).Ignore(); foo.Map(t => t.PathSize).Ignore(); foo.Map(t => t.Signature).Ignore(); foo.Map(t => t.ControlSet).Index(0); foo.Map(t => t.CacheEntryPosition).Index(1); foo.Map(t => t.Path).Index(2); foo.Map(t => t.LastModifiedTimeUTC).Index(3); foo.Map(t => t.Executed).Index(4); foo.Map(t => t.Duplicate).Index(5); foo.Map(t => t.SourceFile).Index(6); csv.WriteHeader <CacheEntry>(); csv.NextRecord(); logger.Debug($"**** Found {appCompat.Caches.Count} caches"); var cacheKeys = new HashSet <string>(); if (appCompat.Caches.Any()) { foreach (var appCompatCach in appCompat.Caches) { if (_fluentCommandLineParser.Object.Debug) { appCompatCach.PrintDump(); } try { logger.Info( $"Found {appCompatCach.Entries.Count:N0} cache entries for {appCompat.OperatingSystem} in ControlSet00{appCompatCach.ControlSet}"); if (_fluentCommandLineParser.Object.SortTimestamps) { // csv.WriteRecords(appCompatCach.Entries.OrderByDescending(t => t.LastModifiedTimeUTC)); foreach (var cacheEntry in appCompatCach.Entries) { cacheEntry.SourceFile = hiveToProcess; cacheEntry.Duplicate = cacheKeys.Contains(cacheEntry.GetKey()); cacheKeys.Add(cacheEntry.GetKey()); csv.WriteRecord(cacheEntry); csv.NextRecord(); } } else { foreach (var cacheEntry in appCompatCach.Entries) { cacheEntry.SourceFile = hiveToProcess; cacheEntry.Duplicate = cacheKeys.Contains(cacheEntry.GetKey()); cacheKeys.Add(cacheEntry.GetKey()); csv.WriteRecord(cacheEntry); csv.NextRecord(); } //csv.WriteRecords(appCompatCach.Entries); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message} Stack: {ex.StackTrace}"); try { appCompatCach.PrintDump(); } catch (Exception ex1) { logger.Error($"Couldn't PrintDump {ex1.Message} Stack: {ex1.StackTrace}"); } } } sw.Flush(); sw.Close(); logger.Warn($"\r\nResults saved to '{outFilename}'\r\n"); } else { logger.Warn($"\r\nNo caches were found!\r\n"); } } catch (Exception ex) { if (ex.Message.Contains("Sequence numbers do not match and transaction logs were not found in the same direct") == false) { if (ex.Message.Contains("Administrator privileges not found")) { logger.Fatal($"Could not access '{_fluentCommandLineParser.Object.HiveFile}'. Does it exist?"); logger.Error(""); logger.Fatal("Rerun the program with Administrator privileges to try again\r\n"); } else if (ex.Message.Contains("Invalid diskName:")) { logger.Fatal($"Could not access '{_fluentCommandLineParser.Object.HiveFile}'. Invalid disk!"); logger.Error(""); } else { logger.Error($"There was an error: {ex.Message}"); logger.Error($"Stacktrace: {ex.StackTrace}"); logger.Info(""); } } } }
public Windows8x(byte[] rawBytes, AppCompatCache.OperatingSystemVersion os, string computerName) { Entries = new List<CacheEntry>(); var index = 128; var signature = "00ts"; if (os == AppCompatCache.OperatingSystemVersion.Windows81_Windows2012R2) { signature = "10ts"; } var position = 0; while (index <= rawBytes.Length) { try { var ce = new CacheEntry { Signature = Encoding.ASCII.GetString(rawBytes, index, 4) }; if (ce.Signature != signature) { break; } ce.ComputerName = computerName; index += 4; // skip 4 unknown index += 4; var ceDataSize = BitConverter.ToUInt32(rawBytes, index); index += 4; ce.PathSize = BitConverter.ToUInt16(rawBytes, index); index += 2; ce.Path = Encoding.Unicode.GetString(rawBytes, index, ce.PathSize); index += ce.PathSize; // skip 4 unknown (insertion flags?) var Flag = BitConverter.ToInt32(rawBytes, index); Flag = Flag & 2; if (Flag == 2) ce.Flag = "Executed"; index += 4; // skip 4 unknown (shim flags?) index += 4; // skip 2 unknown index += 2; ce.LastModifiedTimeLocal = DateTimeOffset.FromFileTime(BitConverter.ToInt64(rawBytes, index)); ce.LastModifiedTimeUTC = DateTimeOffset.FromFileTime(BitConverter.ToInt64(rawBytes, index)).ToUniversalTime(); index += 8; ce.DataSize = BitConverter.ToInt32(rawBytes, index); index += 4; ce.Data = rawBytes.Skip(index).Take(ce.DataSize).ToArray(); index += ce.DataSize; ce.CacheEntryPosition = position; Entries.Add(ce); position += 1; } catch (Exception ex) { //TODO report this //take what we can get break; } } }
private static void Main(string[] args) { ExceptionlessClient.Default.Startup("7iL4b0Me7W8PbFflftqWgfQCIdf55flrT2O11zIP"); SetupNLog(); var logger = LogManager.GetCurrentClassLogger(); if (!CheckForDotnet46()) { logger.Warn(".net 4.6 not detected. Please install .net 4.6 and try again."); return; } _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>(); _fluentCommandLineParser.Setup(arg => arg.SaveTo) .As("csv") .WithDescription("Directory to save results. Required") .Required(); _fluentCommandLineParser.Setup(arg => arg.HiveFile) .As('f') .WithDescription( "Full path to SYSTEM hive to process. If this option is not specified, the live Registry will be used") .SetDefault(string.Empty); _fluentCommandLineParser.Setup(arg => arg.SortTimestamps) .As('t') .WithDescription("Sorts last modified timestamps in descending order\r\n") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.ControlSet) .As('c') .WithDescription("The ControlSet to parse. Default is to extract all control sets.") .SetDefault(-1); _fluentCommandLineParser.Setup(arg => arg.Debug) .As('d') .WithDescription("Debug mode") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.DateTimeFormat) .As("dt") .WithDescription( "The custom date/time format to use when displaying timestamps. See https://goo.gl/CNVq0k for options. Default is: yyyy-MM-dd HH:mm:ss") .SetDefault("yyyy-MM-dd HH:mm:ss"); var header = $"AppCompatCache Parser version {Assembly.GetExecutingAssembly().GetName().Version}" + $"\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + $"\r\nhttps://github.com/EricZimmerman/AppCompatCacheParser"; var footer = @"Examples: AppCompatCacheParser.exe --csv c:\temp -t -c 2" + "\r\n\t " + "\r\n\t" + " Short options (single letter) are prefixed with a single dash. Long commands are prefixed with two dashes\r\n"; _fluentCommandLineParser.SetupHelp("?", "help").WithHeader(header).Callback(text => logger.Info(text + "\r\n" + footer)); var result = _fluentCommandLineParser.Parse(args); if (result.HelpCalled) { return; } if (result.HasErrors) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } var hiveToProcess = "Live Registry"; if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { hiveToProcess = _fluentCommandLineParser.Object.HiveFile; } logger.Info(header); logger.Info(""); logger.Info($"Processing hive '{hiveToProcess}'"); logger.Info(""); if (_fluentCommandLineParser.Object.Debug) { LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Debug); } try { var appCompat = new AppCompatCache.AppCompatCache(_fluentCommandLineParser.Object.HiveFile, _fluentCommandLineParser.Object.ControlSet); var outFileBase = string.Empty; if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { if (_fluentCommandLineParser.Object.ControlSet >= 0) { outFileBase = $"{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.HiveFile)}_ControlSet00{_fluentCommandLineParser.Object.ControlSet}_AppCompatCache.tsv"; } else { outFileBase = $"{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.HiveFile)}_AppCompatCache.tsv"; } } else { outFileBase = $"{appCompat.OperatingSystem}_{Environment.MachineName}_AppCompatCache.tsv"; } if (Directory.Exists(_fluentCommandLineParser.Object.SaveTo) == false) { Directory.CreateDirectory(_fluentCommandLineParser.Object.SaveTo); } var outFilename = Path.Combine(_fluentCommandLineParser.Object.SaveTo, outFileBase); var sw = new StreamWriter(outFilename); var csv = new CsvWriter(sw); csv.Configuration.HasHeaderRecord = true; csv.Configuration.Delimiter = "\t"; var foo = csv.Configuration.AutoMap <CacheEntry>(); var o = new TypeConverterOptions { DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal }; csv.Configuration.TypeConverterOptionsCache.AddOptions <CacheEntry>(o); foo.Map(t => t.LastModifiedTimeUTC).ConvertUsing(t => t.LastModifiedTimeUTC.ToString(_fluentCommandLineParser.Object.DateTimeFormat)); foo.Map(t => t.CacheEntrySize).Ignore(); foo.Map(t => t.Data).Ignore(); foo.Map(t => t.InsertFlags).Ignore(); foo.Map(t => t.DataSize).Ignore(); foo.Map(t => t.LastModifiedFILETIMEUTC).Ignore(); foo.Map(t => t.PathSize).Ignore(); foo.Map(t => t.Signature).Ignore(); foo.Map(t => t.ControlSet).Index(0); foo.Map(t => t.CacheEntryPosition).Index(1); foo.Map(t => t.Path).Index(2); foo.Map(t => t.LastModifiedTimeUTC).Index(3); foo.Map(t => t.Executed).Index(4); csv.WriteHeader <CacheEntry>(); csv.NextRecord(); logger.Debug($"**** Found {appCompat.Caches.Count} caches"); if (appCompat.Caches.Any()) { foreach (var appCompatCach in appCompat.Caches) { if (_fluentCommandLineParser.Object.Debug) { appCompatCach.PrintDump(); } try { logger.Info( $"Found {appCompatCach.Entries.Count:N0} cache entries for {appCompat.OperatingSystem} in ControlSet00{appCompatCach.ControlSet}"); if (_fluentCommandLineParser.Object.SortTimestamps) { csv.WriteRecords(appCompatCach.Entries.OrderByDescending(t => t.LastModifiedTimeUTC)); } else { csv.WriteRecords(appCompatCach.Entries); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message} Stack: {ex.StackTrace}"); try { appCompatCach.PrintDump(); } catch (Exception ex1) { logger.Error($"Couldn't PrintDump {ex1.Message} Stack: {ex1.StackTrace}"); } } } sw.Flush(); sw.Close(); logger.Warn($"\r\nResults saved to '{outFilename}'\r\n"); } else { logger.Warn($"\r\nNo caches were found!\r\n"); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message} Stack: {ex.StackTrace}"); } }
private static void Main(string[] args) { if (!CheckForDotnet46()) { Console.Error.WriteLine("Please install .NET Framework 4.6."); return; } string inDir = "", outDir = ""; string outFileBase = $"shimcache_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(); } var outFilename = Path.Combine(outDir, outFileBase); var sw = new StreamWriter(outFilename, true, System.Text.Encoding.UTF8); sw.AutoFlush = true; var csv = new CsvWriter(sw); csv.Configuration.RegisterClassMap <CacheOutputMap>(); csv.Configuration.Delimiter = "\t"; csv.Configuration.Encoding = System.Text.Encoding.UTF8; if (args.Length == 4) { if (args[3] == "--noheader") { csv.Configuration.HasHeaderRecord = false; } else { csv.WriteHeader <CacheEntry>(); } } else { csv.WriteHeader <CacheEntry>(); } if (Directory.Exists(outDir) == false) { Directory.CreateDirectory(outDir); } 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; } br.BaseStream.Seek(48, SeekOrigin.Begin); if (br.ReadUInt16() != 'S') // means not SYSTEM hive { continue; } br.Close(); st.Close(); try { var appCompat = new AppCompatCache.AppCompatCache(fileName); if ((appCompat.Cache != null)) { Console.WriteLine($"Found: {appCompat.Cache.Entries.Count:N0} entries, '{fileName}'"); csv.WriteRecords(appCompat.Cache.Entries); } } catch (Exception ex) { Console.Error.WriteLine($"Skip: {ex.Message}"); } } Console.WriteLine($"Saved: '{outFilename}'"); sw.Close(); return; }
private static void Main(string[] args) { SetupNLog(); var logger = LogManager.GetCurrentClassLogger(); if (!CheckForDotnet46()) { logger.Warn(".net 4.6 not detected. Please install .net 4.6 and try again."); return; } _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>(); _fluentCommandLineParser.Setup(arg => arg.SaveTo) .As('s') .WithDescription("(REQUIRED) Directory to save results") .Required(); _fluentCommandLineParser.Setup(arg => arg.HiveFile) .As('h') .WithDescription( "Full path to SYSTEM hive file to process. If this option is not specified, the live Registry will be used") .SetDefault(string.Empty); _fluentCommandLineParser.Setup(arg => arg.SortTimestamps) .As('t') .WithDescription("Sorts timestamps in descending order") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.ControlSet) .As('c') .WithDescription("The ControlSet to parse. Default is to detect the current control set.") .SetDefault(-1); _fluentCommandLineParser.Setup(arg => arg.Debug) .As('d') .WithDescription("Debug mode") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.DateTimeFormat) .As("dt") .WithDescription( "The custom date/time format to use when displaying time stamps. Default is: yyyy-MM-dd HH:mm:ss K") .SetDefault("yyyy-MM-dd HH:mm:ss K"); var header = $"AppCompatCache Parser version {Assembly.GetExecutingAssembly().GetName().Version}" + $"\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + $"\r\nhttps://github.com/EricZimmerman/AppCompatCacheParser"; _fluentCommandLineParser.SetupHelp("?", "help").WithHeader(header).Callback(text => logger.Info(text)); var result = _fluentCommandLineParser.Parse(args); if (result.HelpCalled) { return; } if (result.HasErrors) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); logger.Info( @"Example: AppCompatCacheParser.exe -s c:\temp -t -c 2"); return; } var hiveToProcess = "Live Registry"; if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { hiveToProcess = _fluentCommandLineParser.Object.HiveFile; } logger.Info(header); logger.Info(""); logger.Info($"Processing hive '{hiveToProcess}'"); logger.Info(""); if (_fluentCommandLineParser.Object.Debug) { LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Debug); } try { var appCompat = new AppCompatCache.AppCompatCache(_fluentCommandLineParser.Object.HiveFile, _fluentCommandLineParser.Object.ControlSet); var outFileBase = string.Empty; if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { if (_fluentCommandLineParser.Object.ControlSet >= 0) { outFileBase = $"AppCompatCache.csv"; } else { outFileBase = $"AppCompatCache.csv"; } } else { outFileBase = $"AppCompatCache.csv"; } if (Directory.Exists(_fluentCommandLineParser.Object.SaveTo) == false) { Directory.CreateDirectory(_fluentCommandLineParser.Object.SaveTo); } var outFilename = Path.Combine(_fluentCommandLineParser.Object.SaveTo, outFileBase); logger.Info($"Results will be saved to '{outFilename}'\r\n"); var sw = new StreamWriter(outFilename) { AutoFlush = true }; var csv = new CsvWriter(sw); csv.Configuration.RegisterClassMap(new CacheOutputMap(_fluentCommandLineParser.Object.DateTimeFormat)); csv.Configuration.Delimiter = ","; csv.WriteHeader <CacheEntry>(); logger.Debug($"**** Found {appCompat.Caches.Count} caches"); if (appCompat.Caches.Any()) { foreach (var appCompatCach in appCompat.Caches) { if (_fluentCommandLineParser.Object.Debug) { appCompatCach.PrintDump(); } try { logger.Info( $"Found {appCompatCach.Entries.Count:N0} cache entries for {appCompat.OperatingSystem} in ControlSet00{appCompatCach.ControlSet}"); if (_fluentCommandLineParser.Object.SortTimestamps) { csv.WriteRecords(appCompatCach.Entries.OrderByDescending(t => t.LastModifiedTimeUTC)); } else { csv.WriteRecords(appCompatCach.Entries); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message} Stack: {ex.StackTrace}"); try { appCompatCach.PrintDump(); } catch (Exception ex1) { logger.Error($"Couldnt PrintDump {ex.Message} Stack: {ex.StackTrace}"); } } } sw.Close(); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message} Stack: {ex.StackTrace}"); } }
private static void Main(string[] args) { if (!CheckForDotnet46()) { Console.Error.WriteLine("Please install .NET Framework 4.6."); return; } string inDir = "", outDir = ""; string outFileBase = $"shimcache_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 outFilename = Path.Combine(outDir, outFileBase); var sw = new StreamWriter(outFilename, true, new System.Text.UTF8Encoding(false)); sw.AutoFlush = true; var csv = new CsvWriter(sw); csv.Configuration.RegisterClassMap <CacheOutputMap>(); csv.Configuration.Delimiter = "\t"; // csv.Configuration.IgnoreQuotes = false; csv.Configuration.Quote = '"'; csv.Configuration.QuoteAllFields = true; if (args.Length == 4) { if (args[3] == "--noheader") { csv.Configuration.HasHeaderRecord = false; } else { csv.Configuration.HasHeaderRecord = true; } } else { csv.Configuration.HasHeaderRecord = true; } bool entryFlag = false; foreach (string fileName in Directory.GetFiles(inDir, "*", SearchOption.AllDirectories)) { if (fileName.EndsWith(".LOG") || fileName.EndsWith(".LOG1") || fileName.EndsWith(".LOG2")) { continue; } DirectoryInfo parentFolder = Directory.GetParent(fileName); if (outDir.Contains(parentFolder.ToString())) { continue; } Stream st = File.OpenRead(fileName); if (st.Length < 4) { continue; } BinaryReader br = new BinaryReader(st); if (br.ReadInt32() != 1718052210) // means not "regf" { continue; } br.BaseStream.Seek(48, SeekOrigin.Begin); if (br.ReadUInt16() != 'S') // means not SYSTEM hive { continue; } br.Close(); st.Close(); var appCompat = new AppCompatCache.AppCompatCache(fileName, 0); // 0: current, -1: all control sets if (appCompat.Caches.Any()) { foreach (var appCompatCach in appCompat.Caches) { try { Console.WriteLine( $"Found {appCompatCach.Entries.Count:N0} entries for {appCompat.OperatingSystem} in ControlSet00{appCompatCach.ControlSet}"); csv.WriteRecords(appCompatCach.Entries); entryFlag = true; } catch (Exception ex) { Console.Error.WriteLine($"Skip: " + fileName); } } } } sw.Close(); if (entryFlag == true) { Console.WriteLine($"Saved: '{outFilename}'"); } else { Console.WriteLine($"Found 0 entries.."); } return; }
private static void Main(string[] args) { SetupNLog(); var logger = LogManager.GetCurrentClassLogger(); if (!CheckForDotnet46()) { logger.Warn(".net 4.6 not detected. Please install .net 4.6 and try again."); return; } var p = new FluentCommandLineParser <ApplicationArguments>(); p.Setup(arg => arg.SaveTo) .As('s') .WithDescription("(REQUIRED) Directory to save results") .Required(); p.Setup(arg => arg.HiveFile) .As('h') .WithDescription( "Full path to SYSTEM hive file to process. If this option is not specified, the live Registry will be used") .SetDefault(string.Empty); p.Setup(arg => arg.SortTimestamps) .As('t') .WithDescription("If true, sorts timestamps in descending order") .SetDefault(false); var header = $"AppCompatCache Parser version {Assembly.GetExecutingAssembly().GetName().Version}" + $"\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + $"\r\nhttps://github.com/EricZimmerman/AppCompatCacheParser"; p.SetupHelp("?", "help").WithHeader(header).Callback(text => logger.Info(text)); var result = p.Parse(args); if (result.HelpCalled) { return; } if (result.HasErrors) { p.HelpOption.ShowHelp(p.Options); logger.Info( @"Example: AppCompatCacheParser.exe -s c:\temp -t"); return; } var hiveToProcess = "Live Registry"; if (p.Object.HiveFile?.Length > 0) { hiveToProcess = p.Object.HiveFile; } logger.Info(header); logger.Info(""); logger.Info($"Processing hive '{hiveToProcess}'"); logger.Info(""); try { var appCompat = new AppCompatCache.AppCompatCache(p.Object.HiveFile); if (appCompat.Cache != null) { logger.Info( $"Found {appCompat.Cache.Entries.Count:N0} cache entries for {appCompat.OperatingSystem}"); var outFileBase = string.Empty; if (p.Object.HiveFile?.Length > 0) { outFileBase = $"{appCompat.OperatingSystem}_{Path.GetFileNameWithoutExtension(p.Object.HiveFile)}_AppCompatCache.tsv"; } else { outFileBase = $"{appCompat.OperatingSystem}_{Environment.MachineName}_AppCompatCache.tsv"; } if (Directory.Exists(p.Object.SaveTo) == false) { Directory.CreateDirectory(p.Object.SaveTo); } var outFilename = Path.Combine(p.Object.SaveTo, outFileBase); logger.Info($"\r\nSaving results to '{outFilename}'"); var sw = new StreamWriter(outFilename); sw.AutoFlush = true; var csv = new CsvWriter(sw); csv.Configuration.RegisterClassMap <CacheOutputMap>(); csv.Configuration.Delimiter = "\t"; //csv.Configuration.AllowComments = true; csv.WriteHeader <CacheEntry>(); if (p.Object.SortTimestamps) { csv.WriteRecords(appCompat.Cache.Entries.OrderByDescending(t => t.LastModifiedTimeUTC)); } else { csv.WriteRecords(appCompat.Cache.Entries); } sw.Close(); } } catch (Exception ex) { logger.Error($"There was an error: Error message: {ex.Message}"); } #if DEBUG logger.Info(""); logger.Info("Press a key to exit"); Console.ReadKey(); #endif }