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();
                }
            }
        }
    }
Example #3
0
        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}");
            }
        }
Example #6
0
        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;
        }
Example #7
0
        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}");
            }
        }
Example #8
0
        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;
        }
Example #9
0
        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
        }