コード例 #1
0
        /// <summary>
        /// Main program entry point
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            //string testFile; //OLD SINGLE MODE
            var testFiles = new List <string>();

            // Fetch command line arguments
            var result = Parser.Default.ParseArguments <Options>(args);

            // If no argument parsing error, fetch the hive file name
            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);
            }

            // Checks passed, assign the supplied hive file
            //testFile = result.Value.HiveName; JUST REMOVED

            // Set verbosity level
            //var verboseLevel = result.Value.VerboseLevel;
            var verboseLevel = result.Value.VerboseLevel;

            if (verboseLevel < 0)
            {
                verboseLevel = 0;
            }
            if (verboseLevel > 2)
            {
                verboseLevel = 2;
            }

            foreach (var testFile in testFiles)
            {
                // Configure logging
                var config = GetNlogConfig(verboseLevel, Path.GetFullPath(testFile), testFile);
                LogManager.Configuration = config;
                var logger = LogManager.GetCurrentClassLogger();

                if (File.Exists(testFile) == false)
                {
                    logger.Error("'{0}' does not exist!", testFile);
                    continue;
                }

                //Console.WriteLine(">>> Processing: '{0}'", testFile);
                logger.Info("Processing '{0}'", testFile);

                if (result.Value.PerformCheck)
                {
                    try
                    {
                        var tregistryHive = new RegistryHive(testFile);
                        System.Environment.Exit(0);
                    }
                    catch (Exception)
                    {
                        System.Environment.Exit(1);
                    }
                }

                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();

                    // This is where Registry hive file processing is done
                    registryHive.RecoverDeleted = result.Value.RecoverDeleted;
                    logger.Info("Recover boolean: '{0}'", registryHive.RecoverDeleted);
                    registryHive.FlushRecordListsAfterParse = false;
                    registryHive.ParseHive();
                    logger.Info("Finished processing '{0}'", testFile);
                    //Console.WriteLine("  > Finished processing...");

                    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());

                    string outfile;
                    if (result.Value.OutputFile)
                    {
                        var baseDir   = Path.GetDirectoryName(testFile);
                        var baseFname = Path.GetFileName(testFile);
                        var myName    = string.Empty;
                        myName  = ".xml";
                        outfile = Path.Combine(baseDir, $"{baseFname}{myName}");
                    }
                    else
                    {
                        outfile = "console";
                    }

                    logger.Info("Exporting hive data to '{0}'", outfile);
                    registryHive.ExportDataToXMLFormat(outfile);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("There was an error: {0}", ex.Message);
                }
                sw.Stop();
                logger.Info(">>> Processing time: {0:N4} seconds\r\n", sw.Elapsed.TotalSeconds);
                //Console.WriteLine(">>> Processing time: {0:N4} seconds\r\n", sw.Elapsed.TotalSeconds);
            }
        }