Esempio n. 1
0
        private void GenerateCleanedESM(CleanedESM directive)
        {
            var filename = Path.GetFileName(directive.To);
            var gameFile = Path.Combine(GameFolder, "Data", filename);

            Info($"Generating cleaned ESM for {filename}");
            if (!File.Exists(gameFile))
            {
                throw new InvalidDataException($"Missing {filename} at {gameFile}");
            }
            Status($"Hashing game version of {filename}");
            var sha = gameFile.FileHash();

            if (sha != directive.SourceESMHash)
            {
                throw new InvalidDataException(
                          $"Cannot patch {filename} from the game folder because the hashes do not match. Have you already cleaned the file?");
            }

            var patchData = LoadBytesFromPath(directive.SourceDataID);
            var toFile    = Path.Combine(OutputFolder, directive.To);

            Status($"Patching {filename}");
            using (var output = File.Open(toFile, FileMode.Create))
                using (var input = File.OpenRead(gameFile))
                {
                    BSDiff.Apply(input, () => new MemoryStream(patchData), output);
                }
        }
Esempio n. 2
0
        private static void SaveJson(IPrefetch pf, bool pretty, string outDir)
        {
            try
            {
                if (Directory.Exists(outDir) == false)
                {
                    Directory.CreateDirectory(outDir);
                }

                var outName =
                    $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}_{Path.GetFileName(pf.SourceFilename)}.json";
                var outFile = Path.Combine(outDir, outName);


                if (pretty)
                {
                    File.WriteAllText(outFile, pf.Dump());
                }
                else
                {
                    File.WriteAllText(outFile, pf.ToJson());
                }
            }
            catch (Exception ex)
            {
                _logger.Error($"Error exporting json. Error: {ex.Message}");
            }
        }
Esempio n. 3
0
        // 解析测试视频
        private List <TestVideo> ParseTestVideo(string videoPath)
        {
            if (Directory.Exists(videoPath))
            {
                List <TestVideo> testVideos = new List <TestVideo>();
                var videos = Utility.Director(videoPath).Where(f =>
                {
                    string ex = Path.GetExtension(f);
                    return(ex == ".ts" || ex == ".mp4" || ex == ".flv" || ex == ".avi");
                }).ToList();

                foreach (var item in videos)
                {
                    var _testVideoItem = new TestVideo {
                        VideoName = Path.GetFileName(item), VideoPath = Path.GetDirectoryName(item)
                    };
                    testVideos.Add(_testVideoItem);
                }

                return(testVideos);
            }
            else
            {
                MessageWindow.ShowDialog($"无法访问文件夹 [{videoPath}]", this);
            }

            return(null);
        }
Esempio n. 4
0
        private void CountData(string dir)
        {
            alarmImageList.Clear();
            foreach (var item in alarmImageListAll)
            {
                if (item.ImagePath.Contains(dir))
                {
                    alarmImageList.Add(item);
                }
            }

            if (alarmImageList.Count == 0)
            {
                MessageWindow.ShowDialog($"目录 [{dir}] 下无告警图片");
                return;
            }

            var view = CollectionViewSource.GetDefaultView(DataContext);

            view?.MoveCurrentToFirst();

            this.Title = $"[{1}/{alarmImageList.Count}] {Path.GetFileName(CurrentAlarmImage()?.ImagePath)}";
            SetSelectedSceneItem(CurrentAlarmImage()?.Scene);
            SetSelectedIncidentItem(CurrentAlarmImage()?.Incident);

            // 更新数据库
            SQLiteCommand cmd = new SQLiteCommand
            {
                Connection  = dbConnection, // 连接数据库
                CommandText = string.Format($"INSERT OR REPLACE INTO DataPathTab(Item, Path) VALUES ('LastImagePath', '{dir}')")
            };

            cmd.ExecuteNonQuery();
        }
Esempio n. 5
0
 public static string FileHash(this string file, bool nullOnIOError = false)
 {
     try
     {
         var hash = new xxHashConfig();
         hash.HashSizeInBits = 64;
         hash.Seed           = 0x42;
         using (var fs = File.OpenRead(file))
         {
             var config = new xxHashConfig();
             config.HashSizeInBits = 64;
             using (var f = new StatusFileStream(fs, $"Hashing {Path.GetFileName(file)}"))
             {
                 var value = xxHashFactory.Instance.Create(config).ComputeHash(f);
                 return(value.AsBase64String());
             }
         }
     }
     catch (IOException ex)
     {
         if (nullOnIOError)
         {
             return(null);
         }
         throw ex;
     }
 }
Esempio n. 6
0
        public void Path_GetFileName()
        {
            Console.WriteLine("Path.GetFileName()");

            var pathCnt    = 0;
            var errorCnt   = 0;
            var skipAssert = false;

            UnitTestConstants.StopWatcher(true);
            foreach (var path in UnitTestConstants.InputPaths)
            {
                string expected = null;
                string actual   = null;

                Console.WriteLine("\n#{0:000}\tInput Path: [{1}]", ++pathCnt, path);

                // System.IO
                try
                {
                    expected = System.IO.Path.GetFileName(path);
                }
                catch (Exception ex)
                {
                    skipAssert = ex is ArgumentException;

                    Console.WriteLine("\tCaught [System.IO] {0}: [{1}]", ex.GetType().FullName, ex.Message.Replace(Environment.NewLine, "  "));
                }
                Console.WriteLine("\t   System.IO : [{0}]", expected ?? "null");


                // AlphaFS
                try
                {
                    actual = Path.GetFileName(path);

                    if (!skipAssert)
                    {
                        Assert.AreEqual(expected, actual);
                    }
                }
                catch (Exception ex)
                {
                    errorCnt++;

                    Console.WriteLine("\tCaught [AlphaFS] {0}: [{1}]", ex.GetType().FullName, ex.Message.Replace(Environment.NewLine, "  "));
                }
                Console.WriteLine("\t   AlphaFS   : [{0}]", actual ?? "null");
            }
            Console.WriteLine("\n{0}", UnitTestConstants.Reporter(true));

            Assert.AreEqual(0, errorCnt, "Encountered paths where AlphaFS != System.IO");
        }
Esempio n. 7
0
        private void UpdateArchive(VirtualFile f)
        {
            if (!f.IsStaged)
            {
                throw new InvalidDataException("Can't analyze an unstaged file");
            }

            var tmp_dir = Path.Combine(_stagedRoot, Guid.NewGuid().ToString());

            Utils.Status($"Extracting Archive {Path.GetFileName(f.StagedPath)}");

            FileExtractor.ExtractAll(f.StagedPath, tmp_dir);


            Utils.Status($"Updating Archive {Path.GetFileName(f.StagedPath)}");

            var entries = Directory.EnumerateFiles(tmp_dir, "*", SearchOption.AllDirectories)
                          .Select(path => path.RelativeTo(tmp_dir));

            var new_files = entries.Select(e => {
                var new_path = new string[f.Paths.Length + 1];
                f.Paths.CopyTo(new_path, 0);
                new_path[f.Paths.Length] = e;
                var nf = new VirtualFile()
                {
                    Paths = new_path,
                };
                nf._stagedPath = Path.Combine(tmp_dir, e);
                Add(nf);
                return(nf);
            }).ToList();

            // Analyze them
            new_files.PMap(file =>
            {
                Utils.Status($"Analyzing {Path.GetFileName(file.StagedPath)}");
                file.Analyze();
            });
            // Recurse into any archives in this archive
            new_files.Where(file => file.IsArchive).Do(file => UpdateArchive(file));

            f.FinishedIndexing = true;

            if (!_isSyncing)
            {
                SyncToDisk();
            }

            Utils.Status("Cleaning Directory");
            DeleteDirectory(tmp_dir);
        }
Esempio n. 8
0
        public static IErrorResponse CheckValidInstallPath(string path)
        {
            var ret = Utils.IsDirectoryPathValid(path);

            if (!ret.Succeeded)
            {
                return(ret);
            }

            if (!Directory.Exists(path))
            {
                return(ErrorResponse.Success);
            }

            // Check folder does not have a wabbajack modlist
            foreach (var file in Directory.EnumerateFiles(path, DirectoryEnumerationOptions.Recursive))
            {
                if (!File.Exists(file))
                {
                    continue;
                }
                if (System.IO.Path.GetExtension(file).Equals(ExtensionManager.Extension))
                {
                    return(ErrorResponse.Fail($"Cannot install into a folder with a wabbajack modlist inside of it."));
                }
            }

            // Check folder is either empty, or a likely valid previous install
            if (!Directory.IsEmpty(path))
            {
                // Some probably naive check, but should be a good starting point to improve later
                if (!Directory.EnumerateFiles(path).Any(file =>
                {
                    var fileName = Path.GetFileName(file);
                    if (fileName.Equals("ModOrganizer.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                    if (fileName.Equals("ModOrganizer.ini", StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                    return(false);
                }))
                {
                    return(ErrorResponse.Fail($"Cannot install into a non-empty folder that does not look like a previous WJ installation."));
                }
            }

            return(ErrorResponse.Success);
        }
Esempio n. 9
0
 private void ValidateGameESMs()
 {
     foreach (var esm in ModList.Directives.OfType <CleanedESM>().ToList())
     {
         var filename = Path.GetFileName(esm.To);
         var gameFile = Path.Combine(GameFolder, "Data", filename);
         Utils.Log($"Validating {filename}");
         var hash = gameFile.FileHash();
         if (hash != esm.SourceESMHash)
         {
             Utils.ErrorThrow(new InvalidGameESMError(esm, hash, gameFile));
         }
     }
 }
Esempio n. 10
0
        /// <summary>
        ///     MurMur3 hashes the file pointed to by this string
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string FileSHA256(this string file)
        {
            var sha = new SHA256Managed();

            using (var o = new CryptoStream(Stream.Null, sha, CryptoStreamMode.Write))
            {
                using (var i = File.OpenRead(file))
                {
                    i.CopyToWithStatus(new FileInfo(file).Length, o, $"Hashing {Path.GetFileName(file)}");
                }
            }

            return(sha.Hash.ToBase64());
        }
Esempio n. 11
0
            public override async ValueTask <Directive> Run(RawSourceFile source)
            {
                if (!_mergesIndexed.TryGetValue(source.AbsolutePath, out var merge))
                {
                    return(null);
                }
                var result = source.EvolveTo <MergedPatch>();

                result.Sources = merge.plugins.Select(f =>
                {
                    var orig_path = Path.Combine(f.dataFolder, f.filename);
                    var paths     = new[]
                    {
                        orig_path,
                        orig_path + ".mohidden",
                        Path.Combine(Path.GetDirectoryName(orig_path), "optional", Path.GetFileName(orig_path))
                    };

                    var abs_path = paths.FirstOrDefault(p => File.Exists(p));

                    if (abs_path == null)
                    {
                        throw new InvalidDataException(
                            $"File {abs_path} is required to build {merge.filename} but it doesn't exist searched in: \n" + String.Join("\n", paths));
                    }

                    return(new SourcePatch
                    {
                        RelativePath = abs_path.RelativeTo(_mo2Compiler.MO2Folder),
                        Hash = _compiler.VFS.Index.ByFullPath[abs_path].Hash
                    });
                }).ToList();

                var src_data = result.Sources.Select(f => File.ReadAllBytes(Path.Combine(_mo2Compiler.MO2Folder, f.RelativePath)))
                               .ConcatArrays();

                var dst_data = File.ReadAllBytes(source.AbsolutePath);

                await using (var ms = new MemoryStream())
                {
                    await Utils.CreatePatch(src_data, dst_data, ms);

                    result.PatchID = _compiler.IncludeFile(ms.ToArray());
                }

                return(result);
            }
Esempio n. 12
0
        private static bool SetBrowserEmulationVersion(BrowserEmulationVersion browserEmulationVersion)
        {
            bool result;

            result = false;

            try
            {
                RegistryKey key;

                key = Registry.CurrentUser.OpenSubKey(BrowserEmulationKey, true);

                if (key != null)
                {
                    string programName;

                    programName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);

                    if (browserEmulationVersion != BrowserEmulationVersion.Default)
                    {
                        // if it's a valid value, update or create the value
                        key.SetValue(programName, (int)browserEmulationVersion, RegistryValueKind.DWord);
                        logger.Warn("SETTING REGISTRY:{0}-{1}-{2}-{3}", key.Name, programName, (int)browserEmulationVersion, RegistryValueKind.DWord.ToString());
                    }
                    else
                    {
                        // otherwise, remove the existing value
                        key.DeleteValue(programName, false);
                        logger.Warn("DELETING REGISTRY KEY:{0}-{1}", key.Name, programName);
                    }

                    result = true;
                }
            }
            catch (SecurityException se)
            {
                // The user does not have the permissions required to read from the registry key.
                logger.Error(se);
            }
            catch (UnauthorizedAccessException uae)
            {
                // The user does not have the necessary registry rights.
                logger.Error(uae);
            }

            return(result);
        }
Esempio n. 13
0
        // 上一张图片
        private void PreImageClick(object sender, RoutedEventArgs e)
        {
            var view = CollectionViewSource.GetDefaultView(DataContext);

            if (view.CurrentPosition > 0)
            {
                view.MoveCurrentToPrevious();
                this.Title = $"[{view.CurrentPosition + 1}/{alarmImageList.Count}] {Path.GetFileName(CurrentAlarmImage()?.ImagePath)}";
            }
            else
            {
                MessageWindow.ShowDialog("No More Image", this);
            }
            SetSelectedSceneItem(CurrentAlarmImage().Scene);
            SetSelectedIncidentItem(CurrentAlarmImage().Incident);
            var msg = Validation(CurrentAlarmImage());

            if (msg != null)
            {
                MessageWindow.ShowDialog(msg, this);
            }
        }
Esempio n. 14
0
        private static BrowserEmulationVersion GetBrowserEmulationVersion()
        {
            BrowserEmulationVersion result;

            result = BrowserEmulationVersion.Default;

            try
            {
                RegistryKey key;

                key = Registry.CurrentUser.OpenSubKey(BrowserEmulationKey, true);
                if (key != null)
                {
                    string programName;
                    object value;

                    programName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
                    value       = key.GetValue(programName, null);

                    if (value != null)
                    {
                        result = (BrowserEmulationVersion)Convert.ToInt32(value);
                    }
                }
            }
            catch (SecurityException se)
            {
                // The user does not have the permissions required to read from the registry key.
                logger.Error(se);
            }
            catch (UnauthorizedAccessException uae)
            {
                // The user does not have the necessary registry rights.
                logger.Error(uae);
            }

            return(result);
        }
Esempio n. 15
0
        private static void Main(string[] args)
        {
            ExceptionlessClient.Default.Startup("tYeWS6A5K5uItgpB44dnNy2qSb2xJxiQWRRGWebq");

            SetupNLog();

            _logger = LogManager.GetLogger("EvtxECmd");

            _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>
            {
                IsCaseSensitive = false
            };

            _fluentCommandLineParser.Setup(arg => arg.File)
            .As('f')
            .WithDescription("File to process. This or -d is required\r\n");
            _fluentCommandLineParser.Setup(arg => arg.Directory)
            .As('d')
            .WithDescription("Directory to process that contains evtx files. This or -f is required");

            _fluentCommandLineParser.Setup(arg => arg.CsvDirectory)
            .As("csv")
            .WithDescription(
                "Directory to save CSV formatted results to.");     // This, --json, or --xml required

            _fluentCommandLineParser.Setup(arg => arg.CsvName)
            .As("csvf")
            .WithDescription(
                "File name to save CSV formatted results to. When present, overrides default name");

            _fluentCommandLineParser.Setup(arg => arg.JsonDirectory)
            .As("json")
            .WithDescription(
                "Directory to save JSON formatted results to.");     // This, --csv, or --xml required
            _fluentCommandLineParser.Setup(arg => arg.JsonName)
            .As("jsonf")
            .WithDescription(
                "File name to save JSON formatted results to. When present, overrides default name");

            _fluentCommandLineParser.Setup(arg => arg.XmlDirectory)
            .As("xml")
            .WithDescription(
                "Directory to save XML formatted results to.");     // This, --csv, or --json required

            _fluentCommandLineParser.Setup(arg => arg.XmlName)
            .As("xmlf")
            .WithDescription(
                "File name to save XML formatted results to. When present, overrides default name\r\n");

            _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.fffffff")
            .SetDefault("yyyy-MM-dd HH:mm:ss.fffffff");

            _fluentCommandLineParser.Setup(arg => arg.IncludeIds)
            .As("inc")
            .WithDescription(
                "List of Event IDs to process. All others are ignored. Overrides --exc Format is 4624,4625,5410")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.ExcludeIds)
            .As("exc")
            .WithDescription(
                "List of Event IDs to IGNORE. All others are included. Format is 4624,4625,5410")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.StartDate)
            .As("sd")
            .WithDescription(
                "Start date for including events (UTC). Anything OLDER than this is dropped. Format should match --dt")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.EndDate)
            .As("ed")
            .WithDescription(
                "End date for including events (UTC). Anything NEWER than this is dropped. Format should match --dt")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.FullJson)
            .As("fj")
            .WithDescription(
                "When true, export all available data when using --json. Default is FALSE.")
            .SetDefault(false);
            // _fluentCommandLineParser.Setup(arg => arg.PayloadAsJson)
            //     .As("pj")
            //     .WithDescription(
            //         "When true, include event *payload* as json. Default is TRUE.")
            //     .SetDefault(true);

            _fluentCommandLineParser.Setup(arg => arg.TimeDiscrepancyThreshold)
            .As("tdt")
            .WithDescription(
                "The number of seconds to use for time discrepancy detection. Default is 1 second")
            .SetDefault(1);

            _fluentCommandLineParser.Setup(arg => arg.Metrics)
            .As("met")
            .WithDescription(
                "When true, show metrics about processed event log. Default is TRUE.\r\n")
            .SetDefault(true);

            _fluentCommandLineParser.Setup(arg => arg.MapsDirectory)
            .As("maps")
            .WithDescription(
                "The path where event maps are located. Defaults to 'Maps' folder where program was executed\r\n  ")
            .SetDefault(Path.Combine(BaseDirectory, "Maps"));

            _fluentCommandLineParser.Setup(arg => arg.Vss)
            .As("vss")
            .WithDescription(
                "Process all Volume Shadow Copies that exist on drive specified by -f or -d . Default is FALSE")
            .SetDefault(false);
            _fluentCommandLineParser.Setup(arg => arg.Dedupe)
            .As("dedupe")
            .WithDescription(
                "Deduplicate -f or -d & VSCs based on SHA-1. First file found wins. Default is TRUE\r\n")
            .SetDefault(true);

            _fluentCommandLineParser.Setup(arg => arg.Sync)
            .As("sync")
            .WithDescription(
                "If true, the latest maps from https://github.com/EricZimmerman/evtx/tree/master/evtx/Maps are downloaded and local maps updated. Default is FALSE\r\n")
            .SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.Debug)
            .As("debug")
            .WithDescription("Show debug information during processing").SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.Trace)
            .As("trace")
            .WithDescription("Show trace information during processing\r\n").SetDefault(false);

            var header =
                $"EvtxECmd version {Assembly.GetExecutingAssembly().GetName().Version}" +
                "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" +
                "\r\nhttps://github.com/EricZimmerman/evtx";

            var footer =
                @"Examples: EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --csv ""c:\temp\out"" --csvf MyOutputFile.csv" +
                "\r\n\t " +
                @" EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --csv ""c:\temp\out""" + "\r\n\t " +
                @" EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --json ""c:\temp\jsonout""" + "\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)
            {
                _logger.Error("");
                _logger.Error(result.ErrorText);

                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                return;
            }

            if (_fluentCommandLineParser.Object.Sync)
            {
                try
                {
                    _logger.Info(header);
                    UpdateFromRepo();
                }
                catch (Exception e)
                {
                    _logger.Error(e, $"There was an error checking for updates: {e.Message}");
                }

                Environment.Exit(0);
            }

            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() &&
                _fluentCommandLineParser.Object.Directory.IsNullOrEmpty())
            {
                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                _logger.Warn("-f or -d is required. Exiting");
                return;
            }

            _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");
            }

            if (_fluentCommandLineParser.Object.Debug)
            {
                LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Debug);
            }

            if (_fluentCommandLineParser.Object.Trace)
            {
                LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Trace);
            }

            LogManager.ReconfigExistingLoggers();

            if (_fluentCommandLineParser.Object.Vss & (IsAdministrator() == false))
            {
                _logger.Error("--vss is present, but administrator rights not found. Exiting\r\n");
                return;
            }

            var sw = new Stopwatch();

            sw.Start();

            var ts = DateTimeOffset.UtcNow;

            _errorFiles = new Dictionary <string, int>();

            if (_fluentCommandLineParser.Object.JsonDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.JsonDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.JsonDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.JsonDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.JsonDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.json";

                if (_fluentCommandLineParser.Object.JsonName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.JsonName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.JsonDirectory, outName);

                _logger.Warn($"json output will be saved to '{outFile}'\r\n");

                try
                {
                    _swJson = new StreamWriter(outFile, false, Encoding.UTF8);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }

                JsConfig.DateHandler = DateHandler.ISO8601;
            }

            if (_fluentCommandLineParser.Object.XmlDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.XmlDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.XmlDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.XmlDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.XmlDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.xml";

                if (_fluentCommandLineParser.Object.XmlName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.XmlName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.XmlDirectory, outName);

                _logger.Warn($"XML output will be saved to '{outFile}'\r\n");

                try
                {
                    _swXml = new StreamWriter(outFile, false, Encoding.UTF8);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }
            }

            if (_fluentCommandLineParser.Object.StartDate.IsNullOrEmpty() == false)
            {
                if (DateTimeOffset.TryParse(_fluentCommandLineParser.Object.StartDate, null, DateTimeStyles.AssumeUniversal, out var dt))
                {
                    _startDate = dt;
                    _logger.Info($"Setting Start date to '{_startDate.Value.ToUniversalTime().ToString(_fluentCommandLineParser.Object.DateTimeFormat)}'");
                }
                else
                {
                    _logger.Warn($"Could not parse '{_fluentCommandLineParser.Object.StartDate}' to a valud datetime! Events will not be filtered by Start date!");
                }
            }
            if (_fluentCommandLineParser.Object.EndDate.IsNullOrEmpty() == false)
            {
                if (DateTimeOffset.TryParse(_fluentCommandLineParser.Object.EndDate, null, DateTimeStyles.AssumeUniversal, out var dt))
                {
                    _endDate = dt;
                    _logger.Info($"Setting End date to '{_endDate.Value.ToUniversalTime().ToString(_fluentCommandLineParser.Object.DateTimeFormat)}'");
                }
                else
                {
                    _logger.Warn($"Could not parse '{_fluentCommandLineParser.Object.EndDate}' to a valud datetime! Events will not be filtered by End date!");
                }
            }

            if (_startDate.HasValue || _endDate.HasValue)
            {
                _logger.Info("");
            }


            if (_fluentCommandLineParser.Object.CsvDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.CsvDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.CsvDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.csv";

                if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.CsvName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName);

                _logger.Warn($"CSV output will be saved to '{outFile}'\r\n");

                try
                {
                    _swCsv = new StreamWriter(outFile, false, Encoding.UTF8);

                    var opt = new CsvConfiguration(CultureInfo.InvariantCulture)
                    {
                        ShouldUseConstructorParameters = _ => false
                    };

                    _csvWriter = new CsvWriter(_swCsv, opt);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }



                var foo = _csvWriter.Context.AutoMap <EventRecord>();

                // if (_fluentCommandLineParser.Object.PayloadAsJson == false)
                // {
                //     foo.Map(t => t.Payload).Ignore();
                // }
                // else
                // {
                //
                // }

                foo.Map(t => t.RecordPosition).Ignore();
                foo.Map(t => t.Size).Ignore();
                foo.Map(t => t.Timestamp).Ignore();

                foo.Map(t => t.RecordNumber).Index(0);
                foo.Map(t => t.EventRecordId).Index(1);
                foo.Map(t => t.TimeCreated).Index(2);
                foo.Map(t => t.TimeCreated).Convert(t =>
                                                    $"{t.Value.TimeCreated.ToString(_fluentCommandLineParser.Object.DateTimeFormat)}");
                foo.Map(t => t.EventId).Index(3);
                foo.Map(t => t.Level).Index(4);
                foo.Map(t => t.Provider).Index(5);
                foo.Map(t => t.Channel).Index(6);
                foo.Map(t => t.ProcessId).Index(7);
                foo.Map(t => t.ThreadId).Index(8);
                foo.Map(t => t.Computer).Index(9);
                foo.Map(t => t.UserId).Index(10);
                foo.Map(t => t.MapDescription).Index(11);
                foo.Map(t => t.UserName).Index(12);
                foo.Map(t => t.RemoteHost).Index(13);
                foo.Map(t => t.PayloadData1).Index(14);
                foo.Map(t => t.PayloadData2).Index(15);
                foo.Map(t => t.PayloadData3).Index(16);
                foo.Map(t => t.PayloadData4).Index(17);
                foo.Map(t => t.PayloadData5).Index(18);
                foo.Map(t => t.PayloadData6).Index(19);
                foo.Map(t => t.ExecutableInfo).Index(20);
                foo.Map(t => t.HiddenRecord).Index(21);
                foo.Map(t => t.SourceFile).Index(22);
                foo.Map(t => t.Keywords).Index(23);
                foo.Map(t => t.Payload).Index(24);

                _csvWriter.Context.RegisterClassMap(foo);
                _csvWriter.WriteHeader <EventRecord>();
                _csvWriter.NextRecord();
            }

            if (Directory.Exists(_fluentCommandLineParser.Object.MapsDirectory) == false)
            {
                _logger.Warn(
                    $"Maps directory '{_fluentCommandLineParser.Object.MapsDirectory}' does not exist! Event ID maps will not be loaded!!");
            }
            else
            {
                _logger.Debug($"Loading maps from '{Path.GetFullPath(_fluentCommandLineParser.Object.MapsDirectory)}'");
                var errors = EventLog.LoadMaps(Path.GetFullPath(_fluentCommandLineParser.Object.MapsDirectory));

                if (errors)
                {
                    return;
                }

                _logger.Info($"Maps loaded: {EventLog.EventLogMaps.Count:N0}");
            }

            _includeIds = new HashSet <int>();
            _excludeIds = new HashSet <int>();

            if (_fluentCommandLineParser.Object.ExcludeIds.IsNullOrEmpty() == false)
            {
                var excSegs = _fluentCommandLineParser.Object.ExcludeIds.Split(',');

                foreach (var incSeg in excSegs)
                {
                    if (int.TryParse(incSeg, out var goodId))
                    {
                        _excludeIds.Add(goodId);
                    }
                }
            }

            if (_fluentCommandLineParser.Object.IncludeIds.IsNullOrEmpty() == false)
            {
                _excludeIds.Clear();
                var incSegs = _fluentCommandLineParser.Object.IncludeIds.Split(',');

                foreach (var incSeg in incSegs)
                {
                    if (int.TryParse(incSeg, out var goodId))
                    {
                        _includeIds.Add(goodId);
                    }
                }
            }

            if (_fluentCommandLineParser.Object.Vss)
            {
                string driveLetter;
                if (_fluentCommandLineParser.Object.File.IsEmpty() == false)
                {
                    driveLetter = Path.GetPathRoot(Path.GetFullPath(_fluentCommandLineParser.Object.File))
                                  .Substring(0, 1);
                }
                else
                {
                    driveLetter = Path.GetPathRoot(Path.GetFullPath(_fluentCommandLineParser.Object.Directory))
                                  .Substring(0, 1);
                }


                Helper.MountVss(driveLetter, VssDir);
                Console.WriteLine();
            }

            EventLog.TimeDiscrepancyThreshold = _fluentCommandLineParser.Object.TimeDiscrepancyThreshold;

            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() == false)
            {
                if (File.Exists(_fluentCommandLineParser.Object.File) == false)
                {
                    _logger.Warn($"'{_fluentCommandLineParser.Object.File}' does not exist! Exiting");
                    return;
                }

                if (_swXml == null && _swJson == null && _swCsv == null)
                {
                    //no need for maps
                    _logger.Debug("Clearing map collection since no output specified");
                    EventLog.EventLogMaps.Clear();
                }

                _fluentCommandLineParser.Object.Dedupe = false;

                ProcessFile(Path.GetFullPath(_fluentCommandLineParser.Object.File));

                if (_fluentCommandLineParser.Object.Vss)
                {
                    var vssDirs = Directory.GetDirectories(VssDir);

                    var root = Path.GetPathRoot(Path.GetFullPath(_fluentCommandLineParser.Object.File));
                    var stem = Path.GetFullPath(_fluentCommandLineParser.Object.File).Replace(root, "");

                    foreach (var vssDir in vssDirs)
                    {
                        var newPath = Path.Combine(vssDir, stem);
                        if (File.Exists(newPath))
                        {
                            ProcessFile(newPath);
                        }
                    }
                }
            }
            else
            {
                _logger.Info($"Looking for event log files in '{_fluentCommandLineParser.Object.Directory}'");
                _logger.Info("");

                var f = new DirectoryEnumerationFilters
                {
                    InclusionFilter = fsei => fsei.Extension.ToUpperInvariant() == ".EVTX",
                    RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink,
                    ErrorFilter     = (errorCode, errorMessage, pathProcessed) => true
                };

                var dirEnumOptions =
                    DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive |
                    DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                    DirectoryEnumerationOptions.BasicSearch;

                var files2 =
                    Directory.EnumerateFileSystemEntries(Path.GetFullPath(_fluentCommandLineParser.Object.Directory), dirEnumOptions, f);

                if (_swXml == null && _swJson == null && _swCsv == null)
                {
                    //no need for maps
                    _logger.Debug("Clearing map collection since no output specified");
                    EventLog.EventLogMaps.Clear();
                }

                foreach (var file in files2)
                {
                    ProcessFile(file);
                }

                if (_fluentCommandLineParser.Object.Vss)
                {
                    var vssDirs = Directory.GetDirectories(VssDir);

                    Console.WriteLine();

                    foreach (var vssDir in vssDirs)
                    {
                        var root = Path.GetPathRoot(Path.GetFullPath(_fluentCommandLineParser.Object.Directory));
                        var stem = Path.GetFullPath(_fluentCommandLineParser.Object.Directory).Replace(root, "");

                        var target = Path.Combine(vssDir, stem);

                        _logger.Fatal($"\r\nSearching 'VSS{target.Replace($"{VssDir}\\","")}' for event logs...");

                        var vssFiles = Helper.GetFilesFromPath(target, true, "*.evtx");

                        foreach (var file in vssFiles)
                        {
                            ProcessFile(file);
                        }
                    }
                }
            }

            try
            {
                _swCsv?.Flush();
                _swCsv?.Close();

                _swJson?.Flush();
                _swJson?.Close();

                _swXml?.Flush();
                _swXml?.Close();
            }
            catch (Exception e)
            {
                _logger.Error($"Error when flushing output files to disk! Error message: {e.Message}");
            }


            sw.Stop();
            _logger.Info("");

            var suff = string.Empty;

            if (_fileCount != 1)
            {
                suff = "s";
            }

            _logger.Error(
                $"Processed {_fileCount:N0} file{suff} in {sw.Elapsed.TotalSeconds:N4} seconds\r\n");

            if (_errorFiles.Count > 0)
            {
                _logger.Info("");
                _logger.Error("Files with errors");
                foreach (var errorFile in _errorFiles)
                {
                    _logger.Info($"'{errorFile.Key}' error count: {errorFile.Value:N0}");
                }

                _logger.Info("");
            }

            if (_fluentCommandLineParser.Object.Vss)
            {
                if (Directory.Exists(VssDir))
                {
                    foreach (var directory in Directory.GetDirectories(VssDir))
                    {
                        Directory.Delete(directory);
                    }
                    Directory.Delete(VssDir, true, true);
                }
            }
        }
Esempio n. 16
0
        // 合并数据
        private void MergeData(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new OpenFileDialog()
            {
                Filter = "Data Base file (.db)|*.db|All files (*.*)|*.*"
            };
            string fileName = null;

            if (openFileDialog.ShowDialog() == true)
            {
                fileName = openFileDialog.FileName;
            }
            if (string.IsNullOrEmpty(fileName))
            {
                return;
            }

            string        _dbPath = $"Data Source = {fileName}";
            SQLiteCommand cmd     = new SQLiteCommand
            {
                Connection  = new SQLiteConnection(_dbPath),
                CommandText = "SELECT * FROM AlarmImageTab WHERE state != 0"
            };

            cmd.Connection.Open();

            List <AlarmImage> _alarmImageList = new List <AlarmImage>();

            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    var _alarmDataItem = new AlarmImage
                    {
                        ID            = dataReader.GetInt32(0),
                        ImagePath     = dataReader.GetString(1),
                        Scene         = dataReader.GetString(2),
                        Incident      = dataReader.GetString(3),
                        Video         = dataReader.GetString(4),
                        Frame         = dataReader.GetInt32(5),
                        State         = (DetectType)(dataReader.GetInt32(6)),
                        IncidentCount = dataReader.GetInt32(7)
                    };

                    _alarmImageList.Add(_alarmDataItem);
                }
                cmd.Connection.Close();
            }

            // 合并数据
            if (dbConnection == null)
            {
                MessageWindow.ShowDialog("无法连接到数据库", this);
                return;
            }
            cmd = new SQLiteCommand {
                Connection = dbConnection
            };
            cmd.CommandText = "BEGIN";
            cmd.ExecuteNonQuery();
            foreach (var item in _alarmImageList)
            {
                if (item.State != DetectType.UnKnown)
                {
                    var imgs = alarmImageListAll.Where(f => Path.GetFileName(f.ImagePath) == Path.GetFileName(item.ImagePath)).ToList();
                    if (imgs.Count == 0)  // 新的告警图片
                    {
                        alarmImageListAll.Add(item);
                        // 更新数据库
                        cmd.CommandText = string.Format($"INSERT INTO AlarmImageTab(id, image, scene, incident, video, frame, state, count)" +
                                                        $" VALUES ('{item.ID}', '{item.ImagePath}','{item.Scene}','{item.Incident}', '{item.Video}', '{item.Frame}', '{(int)item.State}', '{item.IncidentCount}')");
                        cmd.ExecuteNonQuery();
                    }
                    else  // 已存在的告警图片
                    {
                        imgs[0].State         = item.State;
                        imgs[0].IncidentCount = item.IncidentCount;
                        // 更新数据库
                        cmd.CommandText = string.Format($"UPDATE AlarmImageTab SET state = '{(int)item.State}', count = '{item.IncidentCount}' WHERE image = '{ imgs[0].ImagePath}'");
                        cmd.ExecuteNonQuery();
                    }
                    dataWindow.UpdateAlarmImageItem(item);
                }
            }
            cmd.CommandText = "COMMIT";
            cmd.ExecuteNonQuery();

            // 更新数据窗口
            dataWindow.SetDetailData(GetDetailData());

            MessageWindow.ShowDialog("完成数据合并", this);
        }
Esempio n. 17
0
        public static IErrorResponse CheckValidInstallPath(string path, string downloadFolder)
        {
            var ret = Utils.IsDirectoryPathValid(path);

            if (!ret.Succeeded)
            {
                return(ret);
            }

            if (!Directory.Exists(path))
            {
                return(ErrorResponse.Success);
            }

            // Check folder does not have a Wabbajack ModList
            foreach (var file in Directory.EnumerateFiles(path))
            {
                if (!File.Exists(file))
                {
                    continue;
                }
                if (System.IO.Path.GetExtension(file).Equals(Consts.ModListExtension))
                {
                    return(ErrorResponse.Fail($"Cannot install into a folder with a Wabbajack ModList inside of it"));
                }
            }

            // Check folder is either empty, or a likely valid previous install
            if (!Directory.IsEmpty(path))
            {
                // If we have a MO2 install, assume good to go
                if (Directory.EnumerateFiles(path).Any(file =>
                {
                    var fileName = Path.GetFileName(file);
                    if (fileName.Equals("ModOrganizer.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                    if (fileName.Equals("ModOrganizer.ini", StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                    return(false);
                }))
                {
                    return(ErrorResponse.Success);
                }

                // If we don't have a MO2 install, and there's any file that's not in the downloads folder, mark failure
                if (Directory.EnumerateFiles(path).Any(file =>
                {
                    var fileName = Path.GetFileName(file);
                    if (string.IsNullOrWhiteSpace(downloadFolder))
                    {
                        return(true);
                    }
                    return(!Utils.IsUnderneathDirectory(file, downloadFolder));
                }))
                {
                    return(ErrorResponse.Fail($"Cannot install into a non-empty folder that does not look like a previous WJ installation.\n" +
                                              $"To override, delete all installed files from your target installation folder.  Any files in your download folder are okay to keep."));
                }
            }

            return(ErrorResponse.Success);
        }
Esempio n. 18
0
        // 恢复上次状态
        public void Resume()
        {
            if (!File.Exists("./data.db"))
            {
                CreateBlankTabs();
                return;
            }

            string DBPath = "Data Source = " + AppDomain.CurrentDomain.BaseDirectory + @"data.db";

            dbConnection = new SQLiteConnection(DBPath);
            if (dbConnection == null)
            {
                MessageWindow.ShowDialog("无法连接到数据库 data.db", this);
                return;
            }
            dbConnection.Open();

            SQLiteCommand cmd = new SQLiteCommand();

            cmd.Connection = dbConnection; // 连接数据库

            // 标注视频
            cmd.CommandText = "SELECT * FROM VideoInfoTab";
            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    // VideoDataTab(Scene, Video, Incident, Count)
                    string _scene    = dataReader.GetString(0);
                    string _video    = dataReader.GetString(1);
                    string _incident = dataReader.GetString(2);
                    int    _count    = dataReader.GetInt32(3);

                    var _videoInfoItem = new VideoInfo
                    {
                        Scene     = _scene,
                        VideoName = _video,
                        Incident  = _incident,
                        Count     = _count
                    };
                    videoInfoList.Add(_videoInfoItem);
                }
            }

            // 告警图片
            cmd.CommandText = "SELECT * FROM AlarmImageTab";
            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    // (id INTEGER, image VARCHAR(512) PRIMARY KEY, scene VARCHAR(64), incident VARCHAR(64), video VARCHAR(256), frame INTEGER, state INTEGER)
                    int    _id        = dataReader.GetInt32(0);
                    string _imgPath   = dataReader.GetString(1);
                    string _scene     = dataReader.GetString(2);
                    string _incident  = dataReader.GetString(3);
                    string _videoName = dataReader.GetString(4);
                    int    _frame     = dataReader.GetInt32(5);
                    int    _state     = dataReader.GetInt32(6);
                    int    _count     = dataReader.GetInt32(7);

                    var _alarmDataItem = new AlarmImage
                    {
                        ID            = _id,
                        ImagePath     = _imgPath,
                        Video         = _videoName,
                        Scene         = _scene,
                        Incident      = _incident,
                        Frame         = _frame,
                        State         = (DetectType)_state,
                        IncidentCount = _count
                    };

                    alarmImageListAll.Add(_alarmDataItem);
                    dataWindow.AddAlarmImageItem(_alarmDataItem);
                }
            }

            // 测试视频
            cmd.CommandText = "SELECT * FROM TestVideoTab";
            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    // (VideoName VARCHAR(256) PRIMARY KEY, Directory VARCHAR(256))
                    string _videoName     = dataReader.GetString(0);
                    string _videoPath     = dataReader.GetString(1);
                    var    _testVideoItem = new TestVideo {
                        VideoName = _videoName, VideoPath = _videoPath
                    };
                    testVideoList.Add(_testVideoItem);
                    dataWindow.AddTestVideoItem(_testVideoItem);
                }
            }

            // 告警图片路径
            cmd.CommandText = "SELECT * FROM DataPathTab WHERE Item = 'AlarmImagePath'";
            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                if (dataReader.Read())
                {
                    string _imagePath = dataReader.GetString(1);
                    if (Directory.Exists(_imagePath))
                    {
                        fileTree.Clear();
                        fileTree.Add(new FileRecord {
                            Info = new DirAndFileInfo {
                                FullName = _imagePath
                            }
                        });
                    }
                    else
                    {
                        MessageWindow.ShowDialog($"无法访问告警图片路径 [{_imagePath}]");
                    }
                }
            }

            // 上一次统计的告警图片路径
            cmd.CommandText = "SELECT * FROM DataPathTab WHERE Item = 'LastImagePath'";
            using (SQLiteDataReader dataReader = cmd.ExecuteReader())
            {
                if (dataReader.Read())
                {
                    string _dir = dataReader.GetString(1);
                    if (Directory.Exists(_dir))
                    {
                        foreach (var item in alarmImageListAll)
                        {
                            if (item.ImagePath.Contains(_dir))
                            {
                                alarmImageList.Add(item);
                            }
                        }
                    }
                    else
                    {
                        MessageWindow.ShowDialog($"无法访问告警图片路径 [{_dir}]");
                    }
                }
            }

            this.Title = $"[{1}/{alarmImageList.Count}] {Path.GetFileName(CurrentAlarmImage()?.ImagePath)}";
            SetSelectedSceneItem(CurrentAlarmImage()?.Scene);
            SetSelectedIncidentItem(CurrentAlarmImage()?.Incident);

            // 更细统计数据
            dataWindow.SetDetailData(GetDetailData());
        }
Esempio n. 19
0
        private static void ProcessFile(string fileName)
        {
            _logger.Debug($"Checking if '{fileName}' is a SQLite file");
            if (SQLiteFile.IsSQLiteFile(fileName) == false)
            {
                if (_fluentCommandLineParser.Object.Hunt == false)
                {
                    _logger.Error($"\t'{fileName}' is not a SQLite file! Skipping...");
                }
                else
                {
                    _logger.Debug($"\t'{fileName}' is not a SQLite file! Skipping...");
                }

                return;
            }

            _logger.Debug($"'{fileName}' is a SQLite file!");

            if (_fluentCommandLineParser.Object.Dedupe)
            {
                var sha = File.GetHash(fileName, HashType.SHA1);

                if (SeenHashes.Contains(sha))
                {
                    _logger.Error($"Skipping '{fileName}' as a file with SHA-1 '{sha}' has already been processed");
                    Console.WriteLine();
                    return;
                }

                _logger.Debug($"Adding '{fileName}' SHA-1 '{sha}' to seen hashes collection");
                SeenHashes.Add(sha);
            }

            _logger.Warn($"Processing '{fileName}'...");

            ProcessedFiles.Add(fileName);

            var maps = new List <MapFile>();

            if (_fluentCommandLineParser.Object.Hunt)
            {
                maps = SQLMap.MapFiles.Values.ToList();
            }
            else
            {
                //only find maps tht match the db filename
                maps = SQLMap.MapFiles.Values.Where(t => string.Equals(t.FileName, Path.GetFileName(fileName),
                                                                       StringComparison.InvariantCultureIgnoreCase)).ToList();
            }

            var foundMap = false;

            //need to run thru each map and see if we get any IdentityQuery matches
            //process each one that matches
            foreach (var map in maps)
            {
                _logger.Debug($"Processing map '{map.Description}' with Id '{map.Id}'");

                var dbFactory = new OrmLiteConnectionFactory($"{fileName}", SqliteDialect.Provider);

                var baseTime = DateTimeOffset.UtcNow;

                using (var db = dbFactory.Open())
                {
                    _logger.Debug($"\tVerifying database via '{map.IdentifyQuery}'");

                    var id = db.ExecuteScalar <string>(map.IdentifyQuery);

                    if (string.Equals(id, map.IdentifyValue, StringComparison.InvariantCultureIgnoreCase) == false)
                    {
                        _logger.Error($"\tFor map w/ description '{map.Description}', got value '{id}' from IdentityQuery, but expected '{map.IdentifyValue}'. Queries will not be processed!");
                        continue;
                    }

                    //if we find any matches, its not unmatched anymore
                    foundMap = true;

                    _logger.Error($"\tMap queries found: {map.Queries.Count:N0}. Processing queries...");
                    foreach (var queryInfo in map.Queries)
                    {
                        _logger.Debug($"Processing query '{queryInfo.Name}'");

                        try
                        {
                            var results = db.Query <dynamic>(queryInfo.Query).ToList();

                            var outName =
                                $"{baseTime:yyyyMMddHHmmssffffff}_{map.CSVPrefix}_{queryInfo.BaseFileName}_{map.Id}.csv";

                            var fullOutName = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName);

                            if (results.Any() == false)
                            {
                                _logger.Warn($"\t '{queryInfo.Name}' did not return any results. CSV will not be saved.");
                                continue;
                            }

                            _logger.Info($"\tDumping '{queryInfo.Name}' to '{fullOutName}'");

                            using (var writer = new StreamWriter(new FileStream(fullOutName, FileMode.CreateNew)))
                            {
                                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                                {
                                    //   csv.WriteRecords(results);

                                    foreach (var result in results)
                                    {
                                        result.SourceFile = fileName;
                                        csv.WriteRecord(result);
                                        csv.NextRecord();
                                    }

                                    // csv.WriteComment("");
                                    // csv.NextRecord();
                                    // csv.WriteComment($"SourceFile: {fileName}");
                                    // csv.NextRecord();
                                    csv.Flush();
                                    writer.Flush();
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            _logger.Fatal($"Error processing map '{map.Description}' with Id '{map.Id}' for query '{queryInfo.Name}':");
                            _logger.Error($"\t{e.Message.Replace("\r\n","\r\n\t")}");
                        }
                    }
                }
            }

            if (foundMap == false)
            {
                _logger.Info($"\tNo maps found for '{fileName}'. Adding to unmatched database list");
                UnmatchedDbs.Add(fileName);
            }

            Console.WriteLine();
        }
Esempio n. 20
0
        private static void Main(string[] args)
        {
            ExceptionlessClient.Default.Startup("x3MPpeQSBUUsXl3DjekRQ9kYjyN3cr5JuwdoOBpZ");

            SetupNLog();

            _keywords = new HashSet <string> {
                "temp", "tmp"
            };

            _logger = LogManager.GetCurrentClassLogger();



            _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>
            {
                IsCaseSensitive = false
            };

            _fluentCommandLineParser.Setup(arg => arg.File)
            .As('f')
            .WithDescription("File to process. Either this or -d is required");

            _fluentCommandLineParser.Setup(arg => arg.Directory)
            .As('d')
            .WithDescription("Directory to recursively process. Either this or -f is required");

            _fluentCommandLineParser.Setup(arg => arg.Keywords)
            .As('k')
            .WithDescription(
                "Comma separated list of keywords to highlight in output. By default, 'temp' and 'tmp' are highlighted. Any additional keywords will be added to these.");

            _fluentCommandLineParser.Setup(arg => arg.OutFile)
            .As('o')
            .WithDescription(
                "When specified, save prefetch file bytes to the given path. Useful to look at decompressed Win10 files");

            _fluentCommandLineParser.Setup(arg => arg.Quiet)
            .As('q')
            .WithDescription(
                "Do not dump full details about each file processed. Speeds up processing when using --json or --csv. Default is FALSE\r\n")
            .SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.JsonDirectory)
            .As("json")
            .WithDescription(
                "Directory to save json representation to. Use --pretty for a more human readable layout");

            _fluentCommandLineParser.Setup(arg => arg.CsvDirectory)
            .As("csv")
            .WithDescription(
                "Directory to save CSV results to. Be sure to include the full path in double quotes");
            _fluentCommandLineParser.Setup(arg => arg.CsvName)
            .As("csvf")
            .WithDescription("File name to save CSV formatted results to. When present, overrides default name");


            _fluentCommandLineParser.Setup(arg => arg.xHtmlDirectory)
            .As("html")
            .WithDescription(
                "Directory to save xhtml formatted results to. Be sure to include the full path in double quotes");

            _fluentCommandLineParser.Setup(arg => arg.JsonPretty)
            .As("pretty")
            .WithDescription(
                "When exporting to json, use a more human readable layout. Default is FALSE\r\n").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.PreciseTimestamps)
            .As("mp")
            .WithDescription(
                "When true, display higher precision for timestamps. Default is FALSE").SetDefault(false);


            var header =
                $"PECmd version {Assembly.GetExecutingAssembly().GetName().Version}" +
                "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" +
                "\r\nhttps://github.com/EricZimmerman/PECmd";

            var footer = @"Examples: PECmd.exe -f ""C:\Temp\CALC.EXE-3FBEF7FD.pf""" + "\r\n\t " +
                         @" PECmd.exe -f ""C:\Temp\CALC.EXE-3FBEF7FD.pf"" --json ""D:\jsonOutput"" --jsonpretty" +
                         "\r\n\t " +
                         @" PECmd.exe -d ""C:\Temp"" -k ""system32, fonts""" + "\r\n\t " +
                         @" PECmd.exe -d ""C:\Temp"" --csv ""c:\temp"" --csvf foo.csv --json c:\temp\json" +
                         "\r\n\t " +
                         @" PECmd.exe -d ""C:\Windows\Prefetch""" + "\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)
            {
                _logger.Error("");
                _logger.Error(result.ErrorText);

                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                return;
            }

            if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.File) &&
                UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.Directory))
            {
                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                _logger.Warn("Either -f or -d is required. Exiting");
                return;
            }

            if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.File) == false &&
                !File.Exists(_fluentCommandLineParser.Object.File))
            {
                _logger.Warn($"File '{_fluentCommandLineParser.Object.File}' not found. Exiting");
                return;
            }

            if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.Directory) == false &&
                !Directory.Exists(_fluentCommandLineParser.Object.Directory))
            {
                _logger.Warn($"Directory '{_fluentCommandLineParser.Object.Directory}' not found. Exiting");
                return;
            }

            if (_fluentCommandLineParser.Object.Keywords?.Length > 0)
            {
                var kws = _fluentCommandLineParser.Object.Keywords.ToLowerInvariant().Split(new[] { ',' },
                                                                                            StringSplitOptions.RemoveEmptyEntries);

                foreach (var kw in kws)
                {
                    _keywords.Add(kw.Trim());
                }
            }


            _logger.Info(header);
            _logger.Info("");
            _logger.Info($"Command line: {string.Join(" ", Environment.GetCommandLineArgs().Skip(1))}");

            if (IsAdministrator() == false)
            {
                _logger.Fatal("\r\nWarning: Administrator privileges not found!");
            }

            _logger.Info("");
            _logger.Info($"Keywords: {string.Join(", ", _keywords)}");
            _logger.Info("");

            if (_fluentCommandLineParser.Object.PreciseTimestamps)
            {
                _fluentCommandLineParser.Object.DateTimeFormat = _preciseTimeFormat;
            }

            _processedFiles = new List <IPrefetch>();

            _failedFiles = new List <string>();

            if (_fluentCommandLineParser.Object.File?.Length > 0)
            {
                IPrefetch pf = null;

                try
                {
                    pf = LoadFile(_fluentCommandLineParser.Object.File);

                    if (pf != null)
                    {
                        if (_fluentCommandLineParser.Object.OutFile.IsNullOrEmpty() == false)
                        {
                            try
                            {
                                if (Directory.Exists(Path.GetDirectoryName(_fluentCommandLineParser.Object.OutFile)) ==
                                    false)
                                {
                                    Directory.CreateDirectory(
                                        Path.GetDirectoryName(_fluentCommandLineParser.Object.OutFile));
                                }

                                PrefetchFile.SavePrefetch(_fluentCommandLineParser.Object.OutFile, pf);
                                _logger.Info($"Saved prefetch bytes to '{_fluentCommandLineParser.Object.OutFile}'");
                            }
                            catch (Exception e)
                            {
                                _logger.Error($"Unable to save prefetch file. Error: {e.Message}");
                            }
                        }


                        _processedFiles.Add(pf);
                    }
                }
                catch (UnauthorizedAccessException ex)
                {
                    _logger.Error(
                        $"Unable to access '{_fluentCommandLineParser.Object.File}'. Are you running as an administrator? Error: {ex.Message}");
                }
                catch (Exception ex)
                {
                    _logger.Error(
                        $"Error getting prefetch files in '{_fluentCommandLineParser.Object.Directory}'. Error: {ex.Message}");
                }
            }
            else
            {
                _logger.Info($"Looking for prefetch files in '{_fluentCommandLineParser.Object.Directory}'");
                _logger.Info("");

                string[] pfFiles = null;


                var f = new DirectoryEnumerationFilters();
                f.InclusionFilter = fsei =>
                {
                    if (fsei.Extension.ToUpperInvariant() == ".PF")
                    {
                        return(true);
                    }

                    return(false);
                };

                f.RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink;

                f.ErrorFilter = (errorCode, errorMessage, pathProcessed) => true;

                var dirEnumOptions =
                    DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive |
                    DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                    DirectoryEnumerationOptions.BasicSearch;

                var files2 =
                    Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntries(_fluentCommandLineParser.Object.Directory, dirEnumOptions, f);



                try
                {
                    pfFiles = files2.ToArray(); //Directory.GetFiles(_fluentCommandLineParser.Object.Directory, "*.pf",                        SearchOption.AllDirectories);
                }
                catch (UnauthorizedAccessException ua)
                {
                    _logger.Error(
                        $"Unable to access '{_fluentCommandLineParser.Object.Directory}'. Are you running as an administrator? Error: {ua.Message}");
                    return;
                }
                catch (Exception ex)
                {
                    _logger.Error(
                        $"Error getting prefetch files in '{_fluentCommandLineParser.Object.Directory}'. Error: {ex.Message}");
                    return;
                }

                _logger.Info($"Found {pfFiles.Length:N0} Prefetch files");
                _logger.Info("");

                var sw = new Stopwatch();
                sw.Start();

                foreach (var file in pfFiles)
                {
                    var pf = LoadFile(file);

                    if (pf != null)
                    {
                        _processedFiles.Add(pf);
                    }
                }

                sw.Stop();

                if (_fluentCommandLineParser.Object.Quiet)
                {
                    _logger.Info("");
                }

                _logger.Info(
                    $"Processed {pfFiles.Length - _failedFiles.Count:N0} out of {pfFiles.Length:N0} files in {sw.Elapsed.TotalSeconds:N4} seconds");

                if (_failedFiles.Count > 0)
                {
                    _logger.Info("");
                    _logger.Warn("Failed files");
                    foreach (var failedFile in _failedFiles)
                    {
                        _logger.Info($"  {failedFile}");
                    }
                }
            }

            if (_processedFiles.Count > 0)
            {
                _logger.Info("");

                try
                {
                    CsvWriter    csv          = null;
                    StreamWriter streamWriter = null;

                    CsvWriter    csvTl          = null;
                    StreamWriter streamWriterTl = null;


                    if (_fluentCommandLineParser.Object.CsvDirectory?.Length > 0)
                    {
                        var outName = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_PECmd_Output.csv";

                        if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false)
                        {
                            outName = Path.GetFileName(_fluentCommandLineParser.Object.CsvName);
                        }

                        var outNameTl = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_PECmd_Output_Timeline.csv";
                        if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false)
                        {
                            outNameTl =
                                $"{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.CsvName)}_Timeline{Path.GetExtension(_fluentCommandLineParser.Object.CsvName)}";
                        }


                        var outFile   = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName);
                        var outFileTl = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outNameTl);


                        if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false)
                        {
                            _logger.Warn(
                                $"Path to '{_fluentCommandLineParser.Object.CsvDirectory}' does not exist. Creating...");
                            Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory);
                        }

                        _logger.Warn($"CSV output will be saved to '{outFile}'");
                        _logger.Warn($"CSV time line output will be saved to '{outFileTl}'");

                        try
                        {
                            streamWriter = new StreamWriter(outFile);
                            csv          = new CsvWriter(streamWriter);


                            csv.WriteHeader(typeof(CsvOut));
                            csv.NextRecord();

                            streamWriterTl = new StreamWriter(outFileTl);
                            csvTl          = new CsvWriter(streamWriterTl);

                            csvTl.WriteHeader(typeof(CsvOutTl));
                            csvTl.NextRecord();
                        }
                        catch (Exception ex)
                        {
                            _logger.Error(
                                $"Unable to open '{outFile}' for writing. CSV export canceled. Error: {ex.Message}");
                        }
                    }

                    if (_fluentCommandLineParser.Object.JsonDirectory?.Length > 0)
                    {
                        if (Directory.Exists(_fluentCommandLineParser.Object.JsonDirectory) == false)
                        {
                            _logger.Warn(
                                $"'{_fluentCommandLineParser.Object.JsonDirectory} does not exist. Creating...'");
                            Directory.CreateDirectory(_fluentCommandLineParser.Object.JsonDirectory);
                        }

                        _logger.Warn($"Saving json output to '{_fluentCommandLineParser.Object.JsonDirectory}'");
                    }

                    XmlTextWriter xml = null;

                    if (_fluentCommandLineParser.Object.xHtmlDirectory?.Length > 0)
                    {
                        if (Directory.Exists(_fluentCommandLineParser.Object.xHtmlDirectory) == false)
                        {
                            _logger.Warn(
                                $"'{_fluentCommandLineParser.Object.xHtmlDirectory} does not exist. Creating...'");
                            Directory.CreateDirectory(_fluentCommandLineParser.Object.xHtmlDirectory);
                        }

                        var outDir = Path.Combine(_fluentCommandLineParser.Object.xHtmlDirectory,
                                                  $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}_PECmd_Output_for_{_fluentCommandLineParser.Object.xHtmlDirectory.Replace(@":\", "_").Replace(@"\", "_")}");

                        if (Directory.Exists(outDir) == false)
                        {
                            Directory.CreateDirectory(outDir);
                        }

                        var styleDir = Path.Combine(outDir, "styles");
                        if (Directory.Exists(styleDir) == false)
                        {
                            Directory.CreateDirectory(styleDir);
                        }

                        File.WriteAllText(Path.Combine(styleDir, "normalize.css"), Resources.normalize);
                        File.WriteAllText(Path.Combine(styleDir, "style.css"), Resources.style);

                        Resources.directories.Save(Path.Combine(styleDir, "directories.png"));
                        Resources.filesloaded.Save(Path.Combine(styleDir, "filesloaded.png"));

                        var outFile = Path.Combine(_fluentCommandLineParser.Object.xHtmlDirectory, outDir,
                                                   "index.xhtml");

                        _logger.Warn($"Saving HTML output to '{outFile}'");

                        xml = new XmlTextWriter(outFile, Encoding.UTF8)
                        {
                            Formatting  = Formatting.Indented,
                            Indentation = 4
                        };

                        xml.WriteStartDocument();

                        xml.WriteProcessingInstruction("xml-stylesheet", "href=\"styles/normalize.css\"");
                        xml.WriteProcessingInstruction("xml-stylesheet", "href=\"styles/style.css\"");

                        xml.WriteStartElement("document");
                    }

                    if (_fluentCommandLineParser.Object.CsvDirectory.IsNullOrEmpty() == false ||
                        _fluentCommandLineParser.Object.JsonDirectory.IsNullOrEmpty() == false ||
                        _fluentCommandLineParser.Object.xHtmlDirectory.IsNullOrEmpty() == false)
                    {
                        foreach (var processedFile in _processedFiles)
                        {
                            var o = GetCsvFormat(processedFile);

                            try
                            {
                                foreach (var dateTimeOffset in processedFile.LastRunTimes)
                                {
                                    var t = new CsvOutTl();

                                    var exePath =
                                        processedFile.Filenames.FirstOrDefault(
                                            y => y.EndsWith(processedFile.Header.ExecutableFilename));

                                    if (exePath == null)
                                    {
                                        exePath = processedFile.Header.ExecutableFilename;
                                    }

                                    t.ExecutableName = exePath;
                                    t.RunTime        = dateTimeOffset.ToString(_fluentCommandLineParser.Object.DateTimeFormat);

                                    csvTl?.WriteRecord(t);
                                    csvTl?.NextRecord();
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.Error(
                                    $"Error getting time line record for '{processedFile.SourceFilename}' to '{_fluentCommandLineParser.Object.CsvDirectory}'. Error: {ex.Message}");
                            }

                            try
                            {
                                csv?.WriteRecord(o);
                                csv?.NextRecord();
                            }
                            catch (Exception ex)
                            {
                                _logger.Error(
                                    $"Error writing CSV record for '{processedFile.SourceFilename}' to '{_fluentCommandLineParser.Object.CsvDirectory}'. Error: {ex.Message}");
                            }

                            if (_fluentCommandLineParser.Object.JsonDirectory?.Length > 0)
                            {
                                SaveJson(processedFile, _fluentCommandLineParser.Object.JsonPretty,
                                         _fluentCommandLineParser.Object.JsonDirectory);
                            }

                            //XHTML
                            xml?.WriteStartElement("Container");
                            xml?.WriteElementString("SourceFile", o.SourceFilename);
                            xml?.WriteElementString("SourceCreated", o.SourceCreated);
                            xml?.WriteElementString("SourceModified", o.SourceModified);
                            xml?.WriteElementString("SourceAccessed", o.SourceAccessed);

                            xml?.WriteElementString("LastRun", o.LastRun);

                            xml?.WriteElementString("PreviousRun0", $"{o.PreviousRun0}");
                            xml?.WriteElementString("PreviousRun1", $"{o.PreviousRun1}");
                            xml?.WriteElementString("PreviousRun2", $"{o.PreviousRun2}");
                            xml?.WriteElementString("PreviousRun3", $"{o.PreviousRun3}");
                            xml?.WriteElementString("PreviousRun4", $"{o.PreviousRun4}");
                            xml?.WriteElementString("PreviousRun5", $"{o.PreviousRun5}");
                            xml?.WriteElementString("PreviousRun6", $"{o.PreviousRun6}");

                            xml?.WriteStartElement("ExecutableName");
                            xml?.WriteAttributeString("title",
                                                      "Note: The name of the executable tracked by the pf file");
                            xml?.WriteString(o.ExecutableName);
                            xml?.WriteEndElement();

                            xml?.WriteElementString("RunCount", $"{o.RunCount}");

                            xml?.WriteStartElement("Size");
                            xml?.WriteAttributeString("title", "Note: The size of the executable in bytes");
                            xml?.WriteString(o.Size);
                            xml?.WriteEndElement();

                            xml?.WriteStartElement("Hash");
                            xml?.WriteAttributeString("title",
                                                      "Note: The calculated hash for the pf file that should match the hash in the source file name");
                            xml?.WriteString(o.Hash);
                            xml?.WriteEndElement();

                            xml?.WriteStartElement("Version");
                            xml?.WriteAttributeString("title",
                                                      "Note: The operating system that generated the prefetch file");
                            xml?.WriteString(o.Version);
                            xml?.WriteEndElement();

                            xml?.WriteElementString("Note", o.Note);

                            xml?.WriteElementString("Volume0Name", o.Volume0Name);
                            xml?.WriteElementString("Volume0Serial", o.Volume0Serial);
                            xml?.WriteElementString("Volume0Created", o.Volume0Created);

                            xml?.WriteElementString("Volume1Name", o.Volume1Name);
                            xml?.WriteElementString("Volume1Serial", o.Volume1Serial);
                            xml?.WriteElementString("Volume1Created", o.Volume1Created);


                            xml?.WriteStartElement("Directories");
                            xml?.WriteAttributeString("title",
                                                      "A comma separated list of all directories accessed by the executable");
                            xml?.WriteString(o.Directories);
                            xml?.WriteEndElement();

                            xml?.WriteStartElement("FilesLoaded");
                            xml?.WriteAttributeString("title",
                                                      "A comma separated list of all files that were loaded by the executable");
                            xml?.WriteString(o.FilesLoaded);
                            xml?.WriteEndElement();

                            xml?.WriteEndElement();
                        }


                        //Close CSV stuff
                        streamWriter?.Flush();
                        streamWriter?.Close();

                        streamWriterTl?.Flush();
                        streamWriterTl?.Close();

                        //Close XML
                        xml?.WriteEndElement();
                        xml?.WriteEndDocument();
                        xml?.Flush();
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"Error exporting data! Error: {ex.Message}");
                }
            }
        }
Esempio n. 21
0
        private static void Main(string[] args)
        {
            ExceptionlessClient.Default.Startup("IudF6lFjzvdMldPtlYyPmSMHnSEL89n2WmYbCHoy");

            SetupNLog();

            _logger = LogManager.GetCurrentClassLogger();

            _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>
            {
                IsCaseSensitive = false
            };

            _fluentCommandLineParser.Setup(arg => arg.File)
            .As('f')
            .WithDescription("File to process. Either this or -d is required");

            _fluentCommandLineParser.Setup(arg => arg.Directory)
            .As('d')
            .WithDescription("Directory to recursively process. Either this or -f is required");

            _fluentCommandLineParser.Setup(arg => arg.CsvDirectory)
            .As("csv")
            .WithDescription(
                "Directory to save CSV formatted results to. Be sure to include the full path in double quotes");

            _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.Quiet)
            .As('q')
            .WithDescription(
                "Only show the filename being processed vs all output. Useful to speed up exporting to json and/or csv\r\n")
            .SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.DateTimeFormat)
            .As("dt")
            .WithDescription(
                "The custom date/time format to use when displaying time stamps. See https://goo.gl/CNVq0k for options. Default is: yyyy-MM-dd HH:mm:ss\r\n")
            .SetDefault(_preciseTimeFormat);

            _fluentCommandLineParser.Setup(arg => arg.Debug)
            .As("debug")
            .WithDescription("Show debug information during processing").SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.Trace)
            .As("trace")
            .WithDescription("Show trace information during processing\r\n").SetDefault(false);

            var header =
                $"RBCmd version {Assembly.GetExecutingAssembly().GetName().Version}" +
                "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" +
                "\r\nhttps://github.com/EricZimmerman/RBCmd";


            var footer = @"Examples: RBCmd.exe -f ""C:\Temp\INFO2""" + "\r\n\t " +
                         @" RBCmd.exe -f ""C:\Temp\$I3VPA17"" --csv ""D:\csvOutput"" " + "\r\n\t " +
                         @" RBCmd.exe -d ""C:\Temp"" --csv ""c:\temp"" " + "\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)
            {
                _logger.Error("");
                _logger.Error(result.ErrorText);

                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                return;
            }

            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() &&
                _fluentCommandLineParser.Object.Directory.IsNullOrEmpty())
            {
                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                _logger.Warn("Either -f or -d is required. Exiting");
                return;
            }

            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() == false &&
                !File.Exists(_fluentCommandLineParser.Object.File))
            {
                _logger.Warn($"File '{_fluentCommandLineParser.Object.File}' not found. Exiting");
                return;
            }

            if (_fluentCommandLineParser.Object.Directory.IsNullOrEmpty() == false &&
                !Directory.Exists(_fluentCommandLineParser.Object.Directory))
            {
                _logger.Warn($"Directory '{_fluentCommandLineParser.Object.Directory}' not found. Exiting");
                return;
            }

            _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");
            }

            if (_fluentCommandLineParser.Object.Debug)
            {
                foreach (var r in LogManager.Configuration.LoggingRules)
                {
                    r.EnableLoggingForLevel(LogLevel.Debug);
                }

                LogManager.ReconfigExistingLoggers();
                _logger.Debug("Enabled debug messages...");
            }

            if (_fluentCommandLineParser.Object.Trace)
            {
                foreach (var r in LogManager.Configuration.LoggingRules)
                {
                    r.EnableLoggingForLevel(LogLevel.Trace);
                }

                LogManager.ReconfigExistingLoggers();
                _logger.Trace("Enabled trace messages...");
            }

            _csvOuts     = new List <CsvOut>();
            _failedFiles = new List <string>();

            var files = new List <string>();

            var sw = new Stopwatch();

            sw.Start();

            if (_fluentCommandLineParser.Object.File?.Length > 0)
            {
                files.Add(_fluentCommandLineParser.Object.File);
            }
            else
            {
                if (_fluentCommandLineParser.Object.Quiet)
                {
                    _logger.Info("");
                }

                files = GetRecycleBinFiles(_fluentCommandLineParser.Object.Directory);
            }

            foreach (var file in files)
            {
                ProcessFile(file);
            }

            sw.Stop();

            _logger.Info(
                $"Processed {files.Count - _failedFiles.Count:N0} out of {files.Count:N0} files in {sw.Elapsed.TotalSeconds:N4} seconds\r\n");

            if (_failedFiles.Count > 0)
            {
                _logger.Info("");
                _logger.Warn("Failed files");
                foreach (var failedFile in _failedFiles)
                {
                    _logger.Info($"  {failedFile}");
                }
            }

            if (_fluentCommandLineParser.Object.CsvDirectory.IsNullOrEmpty() == false && files.Count > 0)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false)
                {
                    _logger.Warn($"'{_fluentCommandLineParser.Object.CsvDirectory} does not exist. Creating...'");
                    Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory);
                }

                var outName = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_RBCmd_Output.csv";

                if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.CsvName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName);

                _fluentCommandLineParser.Object.CsvDirectory =
                    Path.GetFullPath(outFile);
                _logger.Warn(
                    $"CSV output will be saved to '{Path.GetFullPath(outFile)}'");

                try
                {
                    var sw1 = new StreamWriter(outFile);
                    var csv = new CsvWriter(sw1, CultureInfo.InvariantCulture);

                    csv.WriteHeader(typeof(CsvOut));
                    csv.NextRecord();

                    foreach (var csvOut in _csvOuts)
                    {
                        csv.WriteRecord(csvOut);
                        csv.NextRecord();
                    }

                    sw1.Flush();
                    sw1.Close();
                }
                catch (Exception ex)
                {
                    _logger.Error(
                        $"Unable to open '{outFile}' for writing. CSV export canceled. Error: {ex.Message}");
                }
            }
        }
Esempio n. 22
0
        private async Task InstallArchive(WorkQueue queue, Archive archive, string absolutePath, IGrouping <string, FromArchive> grouping)
        {
            Status($"Extracting {archive.Name}");

            List <FromArchive> vFiles = grouping.Select(g =>
            {
                var file   = VFS.Index.FileForArchiveHashPath(g.ArchiveHashPath);
                g.FromFile = file;
                return(g);
            }).ToList();

            var onFinish = await VFS.Stage(vFiles.Select(f => f.FromFile).Distinct());


            Status($"Copying files for {archive.Name}");

            void CopyFile(string from, string to, bool useMove)
            {
                if (File.Exists(to))
                {
                    var fi = new FileInfo(to);
                    if (fi.IsReadOnly)
                    {
                        fi.IsReadOnly = false;
                    }
                    File.Delete(to);
                }

                if (File.Exists(from))
                {
                    var fi = new FileInfo(from);
                    if (fi.IsReadOnly)
                    {
                        fi.IsReadOnly = false;
                    }
                }


                if (useMove)
                {
                    File.Move(from, to);
                }
                else
                {
                    File.Copy(from, to);
                }
                // If we don't do this, the file will use the last-modified date of the file when it was compressed
                // into an archive, which isn't really what we want in the case of files installed archives
                File.SetLastWriteTime(to, DateTime.Now);
            }

            await vFiles.GroupBy(f => f.FromFile)
            .PDoIndexed(queue, (idx, group) =>
            {
                Utils.Status("Installing files", idx * 100 / vFiles.Count);
                var firstDest = Path.Combine(OutputFolder, group.First().To);
                CopyFile(group.Key.StagedPath, firstDest, true);

                foreach (var copy in group.Skip(1))
                {
                    var nextDest = Path.Combine(OutputFolder, copy.To);
                    CopyFile(firstDest, nextDest, false);
                }
            });

            Status("Unstaging files");
            onFinish();

            // Now patch all the files from this archive
            foreach (var toPatch in grouping.OfType <PatchedFromArchive>())
            {
                using (var patchStream = new MemoryStream())
                {
                    Status($"Patching {Path.GetFileName(toPatch.To)}");
                    // Read in the patch data

                    byte[] patchData = LoadBytesFromPath(toPatch.PatchID);

                    var toFile  = Path.Combine(OutputFolder, toPatch.To);
                    var oldData = new MemoryStream(File.ReadAllBytes(toFile));

                    // Remove the file we're about to patch
                    File.Delete(toFile);

                    // Patch it
                    using (var outStream = File.Open(toFile, FileMode.Create))
                    {
                        BSDiff.Apply(oldData, () => new MemoryStream(patchData), outStream);
                    }

                    Status($"Verifying Patch {Path.GetFileName(toPatch.To)}");
                    var resultSha = toFile.FileHash();
                    if (resultSha != toPatch.Hash)
                    {
                        throw new InvalidDataException($"Invalid Hash for {toPatch.To} after patching");
                    }
                }
            }
        }
Esempio n. 23
0
    public AppCompatCache(string filename, int controlSet, bool noLogs)
    {
        byte[] rawBytes = null;
        Caches = new List <IAppCompatCache>();

        var controlSetIds = new List <int>();

        RegistryKey subKey = null;

        var isLiveRegistry = string.IsNullOrEmpty(filename);

        if (isLiveRegistry)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new NotSupportedException("Live Registry support is not supported on non-Windows platforms.");
            }

            var keyCurrUser = Microsoft.Win32.Registry.LocalMachine;
            var subKey2     =
                keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache");

            if (subKey2 == null)
            {
                subKey2 =
                    keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility");

                if (subKey2 == null)
                {
                    Console.WriteLine(
                        @"'CurrentControlSet\Control\Session Manager\AppCompatCache' key not found! Exiting");
                    return;
                }
            }

            rawBytes = (byte[])subKey2.GetValue("AppCompatCache", null);

            subKey2    = keyCurrUser.OpenSubKey(@"SYSTEM\Select");
            ControlSet = (int)subKey2.GetValue("Current");

            var is32Bit = Is32Bit(filename, null);

            var cache = Init(rawBytes, is32Bit, ControlSet);

            Caches.Add(cache);

            return;
        }

        RegistryHive reg;

        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            Privilege[] privileges = { Privilege.EnableDelegation, Privilege.Impersonate, Privilege.Tcb };
            using var enabler = new PrivilegeEnabler(Privilege.Backup, privileges);
        }

        ControlSet = controlSet;

        if (File.Exists(filename) == false && Helper.RawFileExists(filename) == false)
        {
            throw new FileNotFoundException($"File not found ({filename})!");
        }

        var dirname  = Path.GetDirectoryName(Path.GetFullPath(filename));
        var hiveBase = Path.GetFileName(filename);



        List <RawCopyReturn> rawFiles = null;

        try
        {
            reg = new RegistryHive(filename)
            {
                RecoverDeleted = true
            };
        }
        catch (IOException)
        {
            //file is in use

            if (Helper.IsAdministrator() == false)
            {
                throw new UnauthorizedAccessException("Administrator privileges not found!");
            }

            Log.Warning("'{Filename}' is in use. Rerouting...", filename);

            var files = new List <string>();
            files.Add(filename);

            var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList();

            var log1 = $"{dirname}\\{hiveBase}.LOG1";
            var log2 = $"{dirname}\\{hiveBase}.LOG2";

            if (logFiles.Count == 0)
            {
                if (Helper.RawFileExists(log1))
                {
                    logFiles.Add(log1);
                }

                if (Helper.RawFileExists(log2))
                {
                    logFiles.Add(log2);
                }
            }

            foreach (var logFile in logFiles)
            {
                files.Add(logFile);
            }

            rawFiles = Helper.GetRawFiles(files);
            var b = new byte[rawFiles.First().FileStream.Length];

            rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length);


            reg = new RegistryHive(b, rawFiles.First().InputFilename);
        }

        if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber)
        {
            if (string.IsNullOrEmpty(dirname))
            {
                dirname = ".";
            }

            var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList();

            var log1 = $"{dirname}\\{hiveBase}.LOG1";
            var log2 = $"{dirname}\\{hiveBase}.LOG2";

            if (logFiles.Count == 0)
            {
                if (File.Exists(log1))
                {
                    logFiles.Add(log1);
                }

                if (File.Exists(log2))
                {
                    logFiles.Add(log2);
                }
            }

            if (logFiles.Count == 0)
            {
                if (Helper.IsAdministrator())
                {
                    if (Helper.RawFileExists(log1))
                    {
                        logFiles.Add(log1);
                    }

                    if (Helper.RawFileExists(log2))
                    {
                        logFiles.Add(log2);
                    }
                }
                else
                {
                    Log.Fatal("Log files not found and no administrator access to look for them!");
                }
            }


            if (logFiles.Count == 0)
            {
                if (noLogs == false)
                {
                    Log.Warning(
                        "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!");
                    throw new Exception(
                              "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting");
                }

                Log.Warning(
                    "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways...");
            }
            else
            {
                if (noLogs == false)
                {
                    if (rawFiles != null)
                    {
                        var lt = new List <TransactionLogFileInfo>();
                        foreach (var rawCopyReturn in rawFiles.Skip(1).ToList())
                        {
                            var b = new byte[rawCopyReturn.FileStream.Length];

                            var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename,
                                                                b);
                            lt.Add(tt);
                        }

                        reg.ProcessTransactionLogs(lt, true);
                    }
                    else
                    {
                        reg.ProcessTransactionLogs(logFiles.ToList(), true);
                    }
                }
                else
                {
                    Log.Warning(
                        "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways...");
                }
            }
        }


        reg.ParseHive();

        if (controlSet == -1)
        {
            for (var i = 0; i < 10; i++)
            {
                subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatCache");

                if (subKey == null)
                {
                    subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatibility");
                }

                if (subKey != null)
                {
                    controlSetIds.Add(i);
                }
            }

            if (controlSetIds.Count > 1)
            {
                Log.Warning(
                    "***The following ControlSet00x keys will be exported: {Cs}. Use -c to process keys individually", string.Join(",", controlSetIds));
            }
        }
        else
        {
            //a control set was passed in
            subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatCache");

            if (subKey == null)
            {
                subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatibility");
            }

            if (subKey == null)
            {
                throw new Exception($"Could not find ControlSet00{ControlSet}. Exiting");
            }

            controlSetIds.Add(ControlSet);
        }


        var is32 = Is32Bit(filename, reg);


        Log.Debug("**** Found {Count} ids to process", controlSetIds.Count);


        foreach (var id in controlSetIds)
        {
            Log.Debug("**** Processing id {Id}", id);

            //  var hive2 = new RegistryHiveOnDemand(filename);

            subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatCache");

            if (subKey == null)
            {
                Log.Debug("**** Initial subkey null, getting appCompatability key");
                subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatibility");
            }

            Log.Debug("**** Looking for AppCompatcache value");

            var val = subKey?.Values.SingleOrDefault(c => c.ValueName == "AppCompatCache");

            if (val != null)
            {
                Log.Debug("**** Found AppCompatcache value");
                rawBytes = val.ValueDataRaw;
            }

            if (rawBytes == null)
            {
                Log.Error("'AppCompatCache' value not found for 'ControlSet00{Id}'! Exiting", id);
            }

            var cache = Init(rawBytes, is32, id);

            Caches.Add(cache);
        }
    }
Esempio n. 24
0
        public static bool LoadMaps(string mapPath)
        {
            EventLogMaps = new Dictionary <string, EventLogMap>();

            var f = new DirectoryEnumerationFilters();

            f.InclusionFilter = fsei => fsei.Extension.ToUpperInvariant() == ".MAP";

            f.RecursionFilter = null;//entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink;

            f.ErrorFilter = (errorCode, errorMessage, pathProcessed) => true;

            var dirEnumOptions =
                DirectoryEnumerationOptions.Files |
                DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                DirectoryEnumerationOptions.BasicSearch;

            var mapFiles =
                Directory.EnumerateFileSystemEntries(mapPath, dirEnumOptions, f).ToList();

            var l = LogManager.GetLogger("LoadMaps");

            var deserializer = new DeserializerBuilder()
                               .Build();

            var validator = new EventLogMapValidator();

            var errorMaps = new List <string>();

            foreach (var mapFile in mapFiles.OrderBy(t => t))
            {
                try
                {
                    var eventMapFile = deserializer.Deserialize <EventLogMap>(File.ReadAllText(mapFile));

                    l.Trace(eventMapFile.Dump);

                    var validate = validator.Validate(eventMapFile);

                    if (DisplayValidationResults(validate, mapFile))
                    {
                        if (EventLogMaps.ContainsKey(
                                $"{eventMapFile.EventId}-{eventMapFile.Channel.ToUpperInvariant()}") == false)
                        {
                            l.Debug($"'{Path.GetFileName(mapFile)}' is valid. Adding to maps...");
                            EventLogMaps.Add($"{eventMapFile.EventId}-{eventMapFile.Channel.ToUpperInvariant()}",
                                             eventMapFile);
                        }
                        else
                        {
                            l.Warn(
                                $"A map for event id '{eventMapFile.EventId}' with Channel '{eventMapFile.Channel}' already exists. Map '{Path.GetFileName(mapFile)}' will be skipped");
                        }
                    }
                    else
                    {
                        errorMaps.Add(Path.GetFileName(mapFile));
                    }
                }
                catch (SyntaxErrorException se)
                {
                    errorMaps.Add(Path.GetFileName(mapFile));

                    Console.WriteLine();
                    l.Warn($"Syntax error in '{mapFile}':");
                    l.Fatal(se.Message);

                    var lines        = File.ReadLines(mapFile).ToList();
                    var fileContents = mapFile.ReadAllText();

                    var badLine = lines[se.Start.Line - 1];
                    Console.WriteLine();
                    l.Fatal(
                        $"Bad line (or close to it) '{badLine}' has invalid data at column '{se.Start.Column}'");

                    if (fileContents.Contains('\t'))
                    {
                        Console.WriteLine();
                        l.Error(
                            "Bad line contains one or more tab characters. Replace them with spaces");
                        Console.WriteLine();
                        l.Info(fileContents.Replace("\t", "<TAB>"));
                    }
                }
                catch (YamlException ye)
                {
                    errorMaps.Add(Path.GetFileName(mapFile));

                    Console.WriteLine();
                    l.Warn($"Syntax error in '{mapFile}':");

                    var fileContents = mapFile.ReadAllText();

                    l.Info(fileContents);

                    if (ye.InnerException != null)
                    {
                        l.Fatal(ye.InnerException.Message);
                    }

                    Console.WriteLine();
                    l.Fatal("Verify all properties against example files or manual and try again.");
                }
                catch (Exception e)
                {
                    l.Error($"Error loading map file '{mapFile}': {e.Message}");
                }
            }

            if (errorMaps.Count > 0)
            {
                l.Error("\r\nThe following maps had errors. Scroll up to review errors, correct them, and try again.");
                foreach (var errorMap in errorMaps)
                {
                    l.Info(errorMap);
                }

                l.Info("");
            }

            return(errorMaps.Count > 0);
        }
Esempio n. 25
0
        private static void UpdateFromRepo()
        {
            Console.WriteLine();

            _logger.Info(
                "Checking for updated maps at https://github.com/EricZimmerman/evtx/tree/master/evtx/Maps...");
            Console.WriteLine();
            var archivePath = Path.Combine(BaseDirectory, "____master.zip");

            if (File.Exists(archivePath))
            {
                File.Delete(archivePath);
            }

            using (var client = new WebClient())
            {
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol  = SecurityProtocolType.Tls12;
                client.DownloadFile("https://github.com/EricZimmerman/evtx/archive/master.zip", archivePath);
            }

            var fff = new FastZip();

            if (Directory.Exists(Path.Combine(BaseDirectory, "Maps")) == false)
            {
                Directory.CreateDirectory(Path.Combine(BaseDirectory, "Maps"));
            }

            var directoryFilter = "Maps";

            // Will prompt to overwrite if target file names already exist
            fff.ExtractZip(archivePath, BaseDirectory, FastZip.Overwrite.Always, null,
                           null, directoryFilter, true);

            if (File.Exists(archivePath))
            {
                File.Delete(archivePath);
            }

            var newMapPath = Path.Combine(BaseDirectory, "evtx-master", "evtx", "Maps");

            var orgMapPath = Path.Combine(BaseDirectory, "Maps");

            var newMaps = Directory.GetFiles(newMapPath);

            var newlocalMaps = new List <string>();

            var updatedlocalMaps = new List <string>();

            if (File.Exists(Path.Combine(orgMapPath, "Security_4624.map")))
            {
                _logger.Warn($"Old map format found. Zipping to '!!oldMaps.zip' and cleaning up old maps");
                //old maps found, so zip em first
                var oldZip = Path.Combine(orgMapPath, "!!oldMaps.zip");
                fff.CreateZip(oldZip, orgMapPath, false, @"\.map$");
                foreach (var m in Directory.GetFiles(orgMapPath, "*.map"))
                {
                    File.Delete(m);
                }
            }

            if (File.Exists(Path.Combine(orgMapPath, "!!!!README.txt")))
            {
                File.Delete(Path.Combine(orgMapPath, "!!!!README.txt"));
            }

            foreach (var newMap in newMaps)
            {
                var mName = Path.GetFileName(newMap);
                var dest  = Path.Combine(orgMapPath, mName);

                if (File.Exists(dest) == false)
                {
                    //new target
                    newlocalMaps.Add(mName);
                }
                else
                {
                    //current destination file exists, so compare to new
                    var fiNew = new FileInfo(newMap);
                    var fi    = new FileInfo(dest);

                    if (fiNew.GetHash(HashType.SHA1) != fi.GetHash(HashType.SHA1))
                    {
                        //updated file
                        updatedlocalMaps.Add(mName);
                    }
                }

                File.Copy(newMap, dest, CopyOptions.None);
            }



            if (newlocalMaps.Count > 0 || updatedlocalMaps.Count > 0)
            {
                _logger.Fatal("Updates found!");
                Console.WriteLine();

                if (newlocalMaps.Count > 0)
                {
                    _logger.Error("New maps");
                    foreach (var newLocalMap in newlocalMaps)
                    {
                        _logger.Info(Path.GetFileNameWithoutExtension(newLocalMap));
                    }

                    Console.WriteLine();
                }

                if (updatedlocalMaps.Count > 0)
                {
                    _logger.Error("Updated maps");
                    foreach (var um in updatedlocalMaps)
                    {
                        _logger.Info(Path.GetFileNameWithoutExtension(um));
                    }

                    Console.WriteLine();
                }

                Console.WriteLine();
            }
            else
            {
                Console.WriteLine();
                _logger.Info("No new maps available");
                Console.WriteLine();
            }

            Directory.Delete(Path.Combine(BaseDirectory, "evtx-master"), true);
        }
Esempio n. 26
0
    private static void UpdateFromRepo()
    {
        Console.WriteLine();

        Log.Information("Checking for updated maps at {Url}...", "https://github.com/EricZimmerman/evtx/tree/master/evtx/Maps");
        Console.WriteLine();
        var archivePath = Path.Combine(BaseDirectory, "____master.zip");

        if (File.Exists(archivePath))
        {
            File.Delete(archivePath);
        }
        // using (var client = new WebClient())
        // {
        //     ServicePointManager.Expect100Continue = true;
        //     ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        //     client.DownloadFile("https://github.com/EricZimmerman/evtx/archive/master.zip", archivePath);
        // }

        "https://github.com/EricZimmerman/evtx/archive/master.zip".DownloadFileTo(archivePath);

        var fff = new FastZip();

        if (Directory.Exists(Path.Combine(BaseDirectory, "Maps")) == false)
        {
            Directory.CreateDirectory(Path.Combine(BaseDirectory, "Maps"));
        }

        var directoryFilter = "Maps";

        // Will prompt to overwrite if target file names already exist
        fff.ExtractZip(archivePath, BaseDirectory, FastZip.Overwrite.Always, null,
                       null, directoryFilter, true);

        if (File.Exists(archivePath))
        {
            File.Delete(archivePath);
        }

        var newMapPath = Path.Combine(BaseDirectory, "evtx-master", "evtx", "Maps");

        var orgMapPath = Path.Combine(BaseDirectory, "Maps");

        var newMaps = Directory.GetFiles(newMapPath);

        var newLocalMaps = new List <string>();

        var updatedLocalMaps = new List <string>();

        if (File.Exists(Path.Combine(orgMapPath, "Security_4624.map")))
        {
            Log.Warning("Old map format found. Zipping to {Old} and cleaning up old maps", "!!oldMaps.zip");
            //old maps found, so zip em first
            var oldZip = Path.Combine(orgMapPath, "!!oldMaps.zip");
            fff.CreateZip(oldZip, orgMapPath, false, @"\.map$");
            foreach (var m in Directory.GetFiles(orgMapPath, "*.map"))
            {
                File.Delete(m);
            }
        }

        if (File.Exists(Path.Combine(orgMapPath, "!!!!README.txt")))
        {
            File.Delete(Path.Combine(orgMapPath, "!!!!README.txt"));
        }

        foreach (var newMap in newMaps)
        {
            var mName = Path.GetFileName(newMap);
            var dest  = Path.Combine(orgMapPath, mName);

            if (File.Exists(dest) == false)
            {
                //new target
                newLocalMaps.Add(mName);
            }
            else
            {
                //current destination file exists, so compare to new

                var s1     = new StreamReader(newMap);
                var newSha = Helper.GetSha1FromStream(s1.BaseStream, 0);

                var s2 = new StreamReader(dest);

                var destSha = Helper.GetSha1FromStream(s2.BaseStream, 0);

                s2.Close();
                s1.Close();

                if (newSha != destSha)
                {
                    //updated file
                    updatedLocalMaps.Add(mName);
                }
            }

#if !NET6_0
            File.Copy(newMap, dest, CopyOptions.None);
#else
            File.Copy(newMap, dest, true);
#endif
        }

        if (newLocalMaps.Count > 0 || updatedLocalMaps.Count > 0)
        {
            Log.Information("Updates found!");
            Console.WriteLine();

            if (newLocalMaps.Count > 0)
            {
                Log.Information("New maps");
                foreach (var newLocalMap in newLocalMaps)
                {
                    Log.Information("{File}", Path.GetFileNameWithoutExtension(newLocalMap));
                }

                Console.WriteLine();
            }

            if (updatedLocalMaps.Count > 0)
            {
                Log.Information("Updated maps");
                foreach (var um in updatedLocalMaps)
                {
                    Log.Information("{File}", Path.GetFileNameWithoutExtension(um));
                }

                Console.WriteLine();
            }

            Console.WriteLine();
        }
        else
        {
            Console.WriteLine();
            Log.Information("No new maps available");
            Console.WriteLine();
        }

        Directory.Delete(Path.Combine(BaseDirectory, "evtx-master"), true);
    }
Esempio n. 27
0
        protected override async Task <ExitCode> Run()
        {
            var modListPath = (AbsolutePath)Modlist;

            if (modListPath.Extension != Consts.ModListExtension && modListPath.FileName != (RelativePath)"modlist.txt")
            {
                return(CLIUtils.Exit($"The file {Modlist} is not a valid modlist file!", ExitCode.BadArguments));
            }

            if (Copy && Move)
            {
                return(CLIUtils.Exit("You can't set both copy and move flags!", ExitCode.BadArguments));
            }

            var isModlist = modListPath.Extension == Consts.ModListExtension;

            var list = new List <TransferFile>();

            if (isModlist)
            {
                ModList modlist;

                try
                {
                    modlist = AInstaller.LoadFromFile(modListPath);
                }
                catch (Exception e)
                {
                    return(CLIUtils.Exit($"Error while loading the Modlist!\n{e}", ExitCode.Error));
                }

                if (modlist == null)
                {
                    return(CLIUtils.Exit("The Modlist could not be loaded!", ExitCode.Error));
                }

                CLIUtils.Log($"Modlist contains {modlist.Archives.Count} archives.");

                modlist.Archives.Do(a =>
                {
                    var inputPath  = Path.Combine(Input, a.Name);
                    var outputPath = Path.Combine(Output, a.Name);

                    if (!File.Exists(inputPath))
                    {
                        CLIUtils.Log($"File {inputPath} does not exist, skipping.");
                        return;
                    }

                    CLIUtils.Log($"Adding {inputPath} to the transfer list.");
                    list.Add(new TransferFile(inputPath, outputPath));

                    var metaInputPath  = Path.Combine(inputPath, ".meta");
                    var metaOutputPath = Path.Combine(outputPath, ".meta");

                    if (File.Exists(metaInputPath))
                    {
                        CLIUtils.Log($"Found meta file {metaInputPath}");
                        if (IncludeMeta)
                        {
                            CLIUtils.Log($"Adding {metaInputPath} to the transfer list.");
                            list.Add(new TransferFile(metaInputPath, metaOutputPath));
                        }
                        else
                        {
                            CLIUtils.Log($"Meta file {metaInputPath} will be ignored.");
                        }
                    }
                    else
                    {
                        CLIUtils.Log($"Found no meta file for {inputPath}");
                        if (IncludeMeta)
                        {
                            if (string.IsNullOrWhiteSpace(a.Meta))
                            {
                                CLIUtils.Log($"Meta for {a.Name} is empty, this should not be possible but whatever.");
                                return;
                            }

                            CLIUtils.Log("Adding meta from archive info the transfer list");
                            list.Add(new TransferFile(a.Meta, metaOutputPath, true));
                        }
                        else
                        {
                            CLIUtils.Log($"Meta will be ignored for {a.Name}");
                        }
                    }
                });
            }
            else
            {
                if (!Directory.Exists(Mods))
                {
                    return(CLIUtils.Exit($"Mods directory {Mods} does not exist!", ExitCode.BadArguments));
                }

                CLIUtils.Log($"Reading modlist.txt from {Modlist}");
                string[] modlist = File.ReadAllLines(Modlist);

                if (modlist == null || modlist.Length == 0)
                {
                    return(CLIUtils.Exit($"Provided modlist.txt file at {Modlist} is empty or could not be read!", ExitCode.BadArguments));
                }

                var mods = modlist.Where(s => s.StartsWith("+")).Select(s => s.Substring(1)).ToHashSet();

                if (mods.Count == 0)
                {
                    return(CLIUtils.Exit("Counted mods from modlist.txt are 0!", ExitCode.BadArguments));
                }

                CLIUtils.Log($"Found {mods.Count} mods in modlist.txt");

                var downloads = new HashSet <string>();

                Directory.EnumerateDirectories(Mods, "*", SearchOption.TopDirectoryOnly)
                .Where(d => mods.Contains(Path.GetRelativePath(Path.GetDirectoryName(d), d)))
                .Do(d =>
                {
                    var meta = Path.Combine(d, "meta.ini");
                    if (!File.Exists(meta))
                    {
                        CLIUtils.Log($"Mod meta file {meta} does not exist, skipping");
                        return;
                    }

                    string[] ini = File.ReadAllLines(meta);
                    if (ini == null || ini.Length == 0)
                    {
                        CLIUtils.Log($"Mod meta file {meta} could not be read or is empty!");
                        return;
                    }

                    ini.Where(i => !string.IsNullOrWhiteSpace(i) && i.StartsWith("installationFile="))
                    .Select(i => i.Replace("installationFile=", ""))
                    .Do(i =>
                    {
                        CLIUtils.Log($"Found installationFile {i}");
                        downloads.Add(i);
                    });
                });

                CLIUtils.Log($"Found {downloads.Count} installationFiles from mod metas.");

                Directory.EnumerateFiles(Input, "*", SearchOption.TopDirectoryOnly)
                .Where(f => downloads.Contains(Path.GetFileNameWithoutExtension(f)))
                .Do(f =>
                {
                    CLIUtils.Log($"Found archive {f}");

                    var outputPath = Path.Combine(Output, Path.GetFileName(f));

                    CLIUtils.Log($"Adding {f} to the transfer list");
                    list.Add(new TransferFile(f, outputPath));

                    var metaInputPath = Path.Combine(f, ".meta");
                    if (File.Exists(metaInputPath))
                    {
                        CLIUtils.Log($"Found meta file for {f} at {metaInputPath}");
                        if (IncludeMeta)
                        {
                            var metaOutputPath = Path.Combine(outputPath, ".meta");
                            CLIUtils.Log($"Adding {metaInputPath} to the transfer list.");
                            list.Add(new TransferFile(metaInputPath, metaOutputPath));
                        }
                        else
                        {
                            CLIUtils.Log("Meta file will be ignored");
                        }
                    }
                    else
                    {
                        CLIUtils.Log($"Found no meta file for {f}");
                    }
                });
            }

            CLIUtils.Log($"Transfer list contains {list.Count} items");
            var success = 0;
            var failed  = 0;
            var skipped = 0;

            list.Do(f =>
            {
                if (File.Exists(f.Output))
                {
                    if (Overwrite)
                    {
                        CLIUtils.Log($"Output file {f.Output} already exists, it will be overwritten");
                        if (f.IsMeta || Move)
                        {
                            CLIUtils.Log($"Deleting file at {f.Output}");
                            try
                            {
                                File.Delete(f.Output);
                            }
                            catch (Exception e)
                            {
                                CLIUtils.Log($"Could not delete file {f.Output}!\n{e}");
                                failed++;
                            }
                        }
                    }
                    else
                    {
                        CLIUtils.Log($"Output file {f.Output} already exists, skipping");
                        skipped++;
                        return;
                    }
                }

                if (f.IsMeta)
                {
                    CLIUtils.Log($"Writing meta data to {f.Output}");
                    try
                    {
                        File.WriteAllText(f.Output, f.Input, Encoding.UTF8);
                        success++;
                    }
                    catch (Exception e)
                    {
                        CLIUtils.Log($"Error while writing meta data to {f.Output}!\n{e}");
                        failed++;
                    }
                }
                else
                {
                    if (Copy)
                    {
                        CLIUtils.Log($"Copying file {f.Input} to {f.Output}");
                        try
                        {
                            File.Copy(f.Input, f.Output, Overwrite ? CopyOptions.None : CopyOptions.FailIfExists, CopyMoveProgressHandler, null);
                            success++;
                        }
                        catch (Exception e)
                        {
                            CLIUtils.Log($"Error while copying file {f.Input} to {f.Output}!\n{e}");
                            failed++;
                        }
                    }
                    else if (Move)
                    {
                        CLIUtils.Log($"Moving file {f.Input} to {f.Output}");
                        try
                        {
                            File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None, CopyMoveProgressHandler, null);
                            success++;
                        }
                        catch (Exception e)
                        {
                            CLIUtils.Log($"Error while moving file {f.Input} to {f.Output}!\n{e}");
                            failed++;
                        }
                    }
                }
            });

            CLIUtils.Log($"Skipped transfers: {skipped}");
            CLIUtils.Log($"Failed transfers: {failed}");
            CLIUtils.Log($"Successful transfers: {success}");

            return(0);
        }
Esempio n. 28
0
    private static void DoWork(string d, string f, bool q, string csv, string csvf, string dt, bool debug, bool trace)
    {
        ActiveDateTimeFormat = dt;

        var formatter =
            new DateTimeOffsetFormatter(CultureInfo.CurrentCulture);

        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, formatProvider: formatter)
                   .MinimumLevel.ControlledBy(levelSwitch);

        Log.Logger = conf.CreateLogger();

        if (f.IsNullOrEmpty() &&
            d.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("Either -f or -d is required. Exiting");
            return;
        }

        if (f.IsNullOrEmpty() == false &&
            !File.Exists(f))
        {
            Log.Warning("File {F} not found. Exiting", f);
            return;
        }

        if (d.IsNullOrEmpty() == false &&
            !Directory.Exists(d))
        {
            Log.Warning("Directory {D} not found. Exiting", d);
            return;
        }

        Log.Information("{Header}", Header);
        Console.WriteLine();
        Log.Information("Command line: {Args}", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));

        if (IsAdministrator() == false)
        {
            Log.Warning("Warning: Administrator privileges not found!");
            Console.WriteLine();
        }

        _csvOuts     = new List <CsvOut>();
        _failedFiles = new List <string>();

        var files = new List <string>();

        var sw = new Stopwatch();

        sw.Start();

        if (f?.Length > 0)
        {
            files.Add(f);
        }
        else
        {
            Console.WriteLine();

            Log.Information("Looking for files in {Dir}", d);
            if (!q)
            {
                Console.WriteLine();
            }

            files = GetRecycleBinFiles(d);
        }

        Log.Information("Found {Count:N0} files. Processing...", files.Count);

        if (!q)
        {
            Console.WriteLine();
        }

        foreach (var file in files)
        {
            ProcessFile(file, q, dt);
        }

        sw.Stop();

        Console.WriteLine();
        Log.Information(
            "Processed {FailedFilesCount:N0} out of {Count:N0} files in {TotalSeconds:N4} seconds", files.Count - _failedFiles.Count, files.Count, sw.Elapsed.TotalSeconds);
        Console.WriteLine();

        if (_failedFiles.Count > 0)
        {
            Console.WriteLine();
            Log.Information("Failed files");
            foreach (var failedFile in _failedFiles)
            {
                Log.Information("  {FailedFile}", failedFile);
            }
        }

        if (csv.IsNullOrEmpty() == false && files.Count > 0)
        {
            if (Directory.Exists(csv) == false)
            {
                Log.Information("{Csv} does not exist. Creating...", csv);
                Directory.CreateDirectory(csv);
            }

            var outName = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_RBCmd_Output.csv";

            if (csvf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(csvf);
            }


            var outFile = Path.Combine(csv, outName);

            outFile =
                Path.GetFullPath(outFile);

            Log.Warning("CSV output will be saved to {Path}", Path.GetFullPath(outFile));

            try
            {
                var sw1       = new StreamWriter(outFile);
                var csvWriter = new CsvWriter(sw1, CultureInfo.InvariantCulture);

                csvWriter.WriteHeader(typeof(CsvOut));
                csvWriter.NextRecord();

                foreach (var csvOut in _csvOuts)
                {
                    csvWriter.WriteRecord(csvOut);
                    csvWriter.NextRecord();
                }

                sw1.Flush();
                sw1.Close();
            }
            catch (Exception ex)
            {
                Log.Error(ex,
                          "Unable to open {OutFile} for writing. CSV export canceled. Error: {Message}", outFile, ex.Message);
            }
        }
    }
Esempio n. 29
0
        private static void Main(string[] args)
        {
            ExceptionlessClient.Default.Startup("tYeWS6A5K5uItgpB44dnNy2qSb2xJxiQWRRGWebq");

            SetupNLog();

            _logger = LogManager.GetLogger("EvtxECmd");

            _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments>
            {
                IsCaseSensitive = false
            };

            _fluentCommandLineParser.Setup(arg => arg.File)
            .As('f')
            .WithDescription("File to process. This or -d is required\r\n");
            _fluentCommandLineParser.Setup(arg => arg.Directory)
            .As('d')
            .WithDescription("Directory to process that contains evtx files. This or -f is required");

            _fluentCommandLineParser.Setup(arg => arg.CsvDirectory)
            .As("csv")
            .WithDescription(
                "Directory to save CSV formatted results to.");     // This, --json, or --xml required

            _fluentCommandLineParser.Setup(arg => arg.CsvName)
            .As("csvf")
            .WithDescription(
                "File name to save CSV formatted results to. When present, overrides default name");

            _fluentCommandLineParser.Setup(arg => arg.JsonDirectory)
            .As("json")
            .WithDescription(
                "Directory to save JSON formatted results to.");     // This, --csv, or --xml required
            _fluentCommandLineParser.Setup(arg => arg.JsonName)
            .As("jsonf")
            .WithDescription(
                "File name to save JSON formatted results to. When present, overrides default name");

            _fluentCommandLineParser.Setup(arg => arg.XmlDirectory)
            .As("xml")
            .WithDescription(
                "Directory to save XML formatted results to.");     // This, --csv, or --json required

            _fluentCommandLineParser.Setup(arg => arg.XmlName)
            .As("xmlf")
            .WithDescription(
                "File name to save XML formatted results to. When present, overrides default name\r\n");

            _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.fffffff")
            .SetDefault("yyyy-MM-dd HH:mm:ss.fffffff");

            _fluentCommandLineParser.Setup(arg => arg.IncludeIds)
            .As("inc")
            .WithDescription(
                "List of event IDs to process. All others are ignored. Overrides --exc Format is 4624,4625,5410")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.ExcludeIds)
            .As("exc")
            .WithDescription(
                "List of event IDs to IGNORE. All others are included. Format is 4624,4625,5410")
            .SetDefault(string.Empty);

            _fluentCommandLineParser.Setup(arg => arg.FullJson)
            .As("fj")
            .WithDescription(
                "When true, export all available data when using --json. Default is FALSE.")
            .SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.Metrics)
            .As("met")
            .WithDescription(
                "When true, show metrics about processed event log. Default is TRUE.\r\n")
            .SetDefault(true);

            _fluentCommandLineParser.Setup(arg => arg.MapsDirectory)
            .As("maps")
            .WithDescription(
                "The path where event maps are located. Defaults to 'Maps' folder where program was executed\r\n  ")
            .SetDefault(Path.Combine(BaseDirectory, "Maps"));

            _fluentCommandLineParser.Setup(arg => arg.Debug)
            .As("debug")
            .WithDescription("Show debug information during processing").SetDefault(false);

            _fluentCommandLineParser.Setup(arg => arg.Trace)
            .As("trace")
            .WithDescription("Show trace information during processing\r\n").SetDefault(false);

            var header =
                $"EvtxECmd version {Assembly.GetExecutingAssembly().GetName().Version}" +
                "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" +
                "\r\nhttps://github.com/EricZimmerman/evtx";

            var footer =
                @"Examples: EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --csv ""c:\temp\out"" --csvf MyOutputFile.csv" +
                "\r\n\t " +
                @" EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --csv ""c:\temp\out""" + "\r\n\t " +
                @" EvtxECmd.exe -f ""C:\Temp\Application.evtx"" --json ""c:\temp\jsonout""" + "\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)
            {
                _logger.Error("");
                _logger.Error(result.ErrorText);

                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                return;
            }

            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() &&
                _fluentCommandLineParser.Object.Directory.IsNullOrEmpty())
            {
                _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options);

                _logger.Warn("-f or -d is required. Exiting");
                return;
            }

            _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");
            }

            if (_fluentCommandLineParser.Object.Debug)
            {
                LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Debug);
            }

            if (_fluentCommandLineParser.Object.Trace)
            {
                LogManager.Configuration.LoggingRules.First().EnableLoggingForLevel(LogLevel.Trace);
            }

            LogManager.ReconfigExistingLoggers();

            var sw = new Stopwatch();

            sw.Start();

            var ts = DateTimeOffset.UtcNow;

            _errorFiles = new Dictionary <string, int>();

            if (_fluentCommandLineParser.Object.JsonDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.JsonDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.JsonDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.JsonDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.JsonDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.json";

                if (_fluentCommandLineParser.Object.JsonName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.JsonName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.JsonDirectory, outName);

                _logger.Warn($"json output will be saved to '{outFile}'\r\n");



                try
                {
                    _swJson = new StreamWriter(outFile, false, Encoding.UTF8);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }
            }

            if (_fluentCommandLineParser.Object.XmlDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.XmlDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.XmlDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.XmlDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.XmlDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.xml";

                if (_fluentCommandLineParser.Object.XmlName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.XmlName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.XmlDirectory, outName);

                _logger.Warn($"XML output will be saved to '{outFile}'\r\n");

                try
                {
                    _swXml = new StreamWriter(outFile, false, Encoding.UTF8);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }
            }

            if (_fluentCommandLineParser.Object.CsvDirectory.IsNullOrEmpty() == false)
            {
                if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false)
                {
                    _logger.Warn(
                        $"Path to '{_fluentCommandLineParser.Object.CsvDirectory}' doesn't exist. Creating...");

                    try
                    {
                        Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory);
                    }
                    catch (Exception)
                    {
                        _logger.Fatal(
                            $"Unable to create directory '{_fluentCommandLineParser.Object.CsvDirectory}'. Does a file with the same name exist? Exiting");
                        return;
                    }
                }

                var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.csv";

                if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false)
                {
                    outName = Path.GetFileName(_fluentCommandLineParser.Object.CsvName);
                }

                var outFile = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName);

                _logger.Warn($"CSV output will be saved to '{outFile}'\r\n");

                try
                {
                    _swCsv = new StreamWriter(outFile, false, Encoding.UTF8);

                    _csvWriter = new CsvWriter(_swCsv);
                }
                catch (Exception)
                {
                    _logger.Error($"Unable to open '{outFile}'! Is it in use? Exiting!\r\n");
                    Environment.Exit(0);
                }

                var foo = _csvWriter.Configuration.AutoMap <EventRecord>();

                foo.Map(t => t.PayloadXml).Ignore();
                foo.Map(t => t.RecordPosition).Ignore();
                foo.Map(t => t.Size).Ignore();
                foo.Map(t => t.Timestamp).Ignore();

                foo.Map(t => t.RecordNumber).Index(0);
                foo.Map(t => t.TimeCreated).Index(1);
                foo.Map(t => t.TimeCreated).ConvertUsing(t =>
                                                         $"{t.TimeCreated.ToString(_fluentCommandLineParser.Object.DateTimeFormat)}");
                foo.Map(t => t.EventId).Index(2);
                foo.Map(t => t.Level).Index(3);
                foo.Map(t => t.Provider).Index(4);
                foo.Map(t => t.Channel).Index(5);
                foo.Map(t => t.ProcessId).Index(6);
                foo.Map(t => t.ThreadId).Index(7);
                foo.Map(t => t.Computer).Index(8);
                foo.Map(t => t.UserId).Index(9);
                foo.Map(t => t.MapDescription).Index(10);
                foo.Map(t => t.UserName).Index(11);
                foo.Map(t => t.RemoteHost).Index(12);
                foo.Map(t => t.PayloadData1).Index(13);
                foo.Map(t => t.PayloadData2).Index(14);
                foo.Map(t => t.PayloadData3).Index(15);
                foo.Map(t => t.PayloadData4).Index(16);
                foo.Map(t => t.PayloadData5).Index(17);
                foo.Map(t => t.PayloadData6).Index(18);
                foo.Map(t => t.ExecutableInfo).Index(19);
                foo.Map(t => t.SourceFile).Index(20);

                _csvWriter.Configuration.RegisterClassMap(foo);
                _csvWriter.WriteHeader <EventRecord>();
                _csvWriter.NextRecord();
            }

            if (Directory.Exists(_fluentCommandLineParser.Object.MapsDirectory) == false)
            {
                _logger.Warn(
                    $"Maps directory '{_fluentCommandLineParser.Object.MapsDirectory}' does not exist! Event ID maps will not be loaded!!");
            }
            else
            {
                _logger.Debug($"Loading maps from '{Path.GetFullPath(_fluentCommandLineParser.Object.MapsDirectory)}'");
                var errors = EventLog.LoadMaps(Path.GetFullPath(_fluentCommandLineParser.Object.MapsDirectory));


                if (errors)
                {
                    return;
                }

                _logger.Info($"Maps loaded: {EventLog.EventLogMaps.Count:N0}");
            }

            _includeIds = new HashSet <int>();
            _excludeIds = new HashSet <int>();

            if (_fluentCommandLineParser.Object.ExcludeIds.IsNullOrEmpty() == false)
            {
                var excSegs = _fluentCommandLineParser.Object.ExcludeIds.Split(',');

                foreach (var incSeg in excSegs)
                {
                    if (int.TryParse(incSeg, out var goodId))
                    {
                        _excludeIds.Add(goodId);
                    }
                }
            }

            if (_fluentCommandLineParser.Object.IncludeIds.IsNullOrEmpty() == false)
            {
                _excludeIds.Clear();
                var incSegs = _fluentCommandLineParser.Object.IncludeIds.Split(',');

                foreach (var incSeg in incSegs)
                {
                    if (int.TryParse(incSeg, out var goodId))
                    {
                        _includeIds.Add(goodId);
                    }
                }
            }


            if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() == false)
            {
                if (File.Exists(_fluentCommandLineParser.Object.File) == false)
                {
                    _logger.Warn($"'{_fluentCommandLineParser.Object.File}' does not exist! Exiting");
                    return;
                }

                ProcessFile(_fluentCommandLineParser.Object.File);
            }
            else
            {
                _logger.Info($"Looking for event log files in '{_fluentCommandLineParser.Object.Directory}'");
                _logger.Info("");

                var f = new DirectoryEnumerationFilters();
                f.InclusionFilter = fsei => fsei.Extension.ToUpperInvariant() == ".EVTX";

                f.RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink;

                f.ErrorFilter = (errorCode, errorMessage, pathProcessed) => true;

                var dirEnumOptions =
                    DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive |
                    DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                    DirectoryEnumerationOptions.BasicSearch;

                var files2 =
                    Directory.EnumerateFileSystemEntries(Path.GetFullPath(_fluentCommandLineParser.Object.Directory), dirEnumOptions, f);

                foreach (var file in files2)
                {
                    ProcessFile(file);
                }
            }

            _swCsv?.Flush();
            _swCsv?.Close();

            _swJson?.Flush();
            _swJson?.Close();

            _swXml?.Flush();
            _swXml?.Close();

            sw.Stop();
            _logger.Info("");

            var suff = string.Empty;

            if (_fileCount != 1)
            {
                suff = "s";
            }

            _logger.Error(
                $"Processed {_fileCount:N0} file{suff} in {sw.Elapsed.TotalSeconds:N4} seconds\r\n");

            if (_errorFiles.Count > 0)
            {
                _logger.Info("");
                _logger.Error("Files with errors");
                foreach (var errorFile in _errorFiles)
                {
                    _logger.Info($"'{errorFile.Key}' error count: {errorFile.Value:N0}");
                }

                _logger.Info("");
            }
        }
Esempio n. 30
0
    private static void DoWork(string f, string d, string csv, string csvf, string json, string jsonf, string xml, string xmlf, string dt, string inc, string exc, string sd, string ed, bool fj, int tdt, bool met, string maps, bool vss, bool dedupe, bool sync, bool debug, bool trace)
    {
        var levelSwitch = new LoggingLevelSwitch();

        _activeDateTimeFormat = dt;

        var formatter =
            new DateTimeOffsetFormatter(CultureInfo.CurrentCulture);

        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, formatProvider: formatter)
                   .MinimumLevel.ControlledBy(levelSwitch);

        Log.Logger = conf.CreateLogger();

        if (sync)
        {
            try
            {
                Log.Information("{Header}", Header);
                UpdateFromRepo();
            }
            catch (Exception e)
            {
                Log.Error(e, "There was an error checking for updates: {Message}", e.Message);
            }

            Environment.Exit(0);
        }

        if (f.IsNullOrEmpty() &&
            d.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("-f or -d is required. Exiting");
            Console.WriteLine();
            return;
        }

        Log.Information("{Header}", Header);
        Console.WriteLine();
        Log.Information("Command line: {Args}", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
        Console.WriteLine();

        if (IsAdministrator() == false)
        {
            Log.Warning("Warning: Administrator privileges not found!");
            Console.WriteLine();
        }

        if (vss & !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            vss = false;
            Log.Warning("{Vss} not supported on non-Windows platforms. Disabling...", "--vss");
            Console.WriteLine();
        }

        if (vss & (IsAdministrator() == false))
        {
            Log.Error("{Vss} is present, but administrator rights not found. Exiting", "--vss");
            Console.WriteLine();
            return;
        }

        var sw = new Stopwatch();

        sw.Start();

        var ts = DateTimeOffset.UtcNow;

        _errorFiles = new Dictionary <string, int>();

        if (json.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(json) == false)
            {
                Log.Information("Path to {Json} doesn't exist. Creating...", json);

                try
                {
                    Directory.CreateDirectory(json);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Json}. Does a file with the same name exist? Exiting", json);
                    Console.WriteLine();
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.json";

            if (jsonf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(jsonf);
            }

            var outFile = Path.Combine(json, outName);

            Log.Information("json output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swJson = new StreamWriter(outFile, false, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }

            JsConfig.DateHandler = DateHandler.ISO8601;
        }

        if (xml.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(xml) == false)
            {
                Log.Information("Path to {Xml} doesn't exist. Creating...", xml);

                try
                {
                    Directory.CreateDirectory(xml);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Xml}. Does a file with the same name exist? Exiting", xml);
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.xml";

            if (xmlf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(xmlf);
            }

            var outFile = Path.Combine(xml, outName);

            Log.Information("XML output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swXml = new StreamWriter(outFile, false, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }
        }

        if (sd.IsNullOrEmpty() == false)
        {
            if (DateTimeOffset.TryParse(sd, null, DateTimeStyles.AssumeUniversal, out var dateTimeOffset))
            {
                _startDate = dateTimeOffset;
                Log.Information("Setting Start date to {StartDate}", _startDate.Value);
            }
            else
            {
                Log.Warning("Could not parse {Sd} to a valid datetime! Events will not be filtered by Start date!", sd);
            }
        }

        if (ed.IsNullOrEmpty() == false)
        {
            if (DateTimeOffset.TryParse(ed, null, DateTimeStyles.AssumeUniversal, out var dateTimeOffset))
            {
                _endDate = dateTimeOffset;
                Log.Information("Setting End date to {EndDate}", _endDate.Value);
            }
            else
            {
                Log.Warning("Could not parse {Ed} to a valid datetime! Events will not be filtered by End date!", ed);
            }
        }

        if (_startDate.HasValue || _endDate.HasValue)
        {
            Console.WriteLine();
        }


        if (csv.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(csv) == false)
            {
                Log.Information(
                    "Path to {Csv} doesn't exist. Creating...", csv);

                try
                {
                    Directory.CreateDirectory(csv);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Csv}. Does a file with the same name exist? Exiting", csv);
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.csv";

            if (csvf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(csvf);
            }

            var outFile = Path.Combine(csv, outName);

            Log.Information("CSV output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swCsv = new StreamWriter(outFile, false, Encoding.UTF8);

                var opt = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    ShouldUseConstructorParameters = _ => false
                };

                _csvWriter = new CsvWriter(_swCsv, opt);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }


            var foo = _csvWriter.Context.AutoMap <EventRecord>();

            foo.Map(t => t.RecordPosition).Ignore();
            foo.Map(t => t.Size).Ignore();
            foo.Map(t => t.Timestamp).Ignore();

            foo.Map(t => t.RecordNumber).Index(0);
            foo.Map(t => t.EventRecordId).Index(1);
            foo.Map(t => t.TimeCreated).Index(2);
            foo.Map(t => t.TimeCreated).Convert(t =>
                                                $"{t.Value.TimeCreated.ToString(dt)}");
            foo.Map(t => t.EventId).Index(3);
            foo.Map(t => t.Level).Index(4);
            foo.Map(t => t.Provider).Index(5);
            foo.Map(t => t.Channel).Index(6);
            foo.Map(t => t.ProcessId).Index(7);
            foo.Map(t => t.ThreadId).Index(8);
            foo.Map(t => t.Computer).Index(9);
            foo.Map(t => t.UserId).Index(10);
            foo.Map(t => t.MapDescription).Index(11);
            foo.Map(t => t.UserName).Index(12);
            foo.Map(t => t.RemoteHost).Index(13);
            foo.Map(t => t.PayloadData1).Index(14);
            foo.Map(t => t.PayloadData2).Index(15);
            foo.Map(t => t.PayloadData3).Index(16);
            foo.Map(t => t.PayloadData4).Index(17);
            foo.Map(t => t.PayloadData5).Index(18);
            foo.Map(t => t.PayloadData6).Index(19);
            foo.Map(t => t.ExecutableInfo).Index(20);
            foo.Map(t => t.HiddenRecord).Index(21);
            foo.Map(t => t.SourceFile).Index(22);
            foo.Map(t => t.Keywords).Index(23);
            foo.Map(t => t.Payload).Index(24);

            _csvWriter.Context.RegisterClassMap(foo);
            _csvWriter.WriteHeader <EventRecord>();
            _csvWriter.NextRecord();
        }

        if (Directory.Exists(maps) == false)
        {
            Log.Warning("Maps directory {Maps} does not exist! Event ID maps will not be loaded!!", maps);
        }
        else
        {
            Log.Debug("Loading maps from {Path}", Path.GetFullPath(maps));
            var errors = EventLog.LoadMaps(Path.GetFullPath(maps));

            if (errors)
            {
                return;
            }

            Log.Information("Maps loaded: {Count:N0}", EventLog.EventLogMaps.Count);
        }

        _includeIds = new HashSet <int>();
        _excludeIds = new HashSet <int>();

        if (exc.IsNullOrEmpty() == false)
        {
            var excSegs = exc.Split(',');

            foreach (var incSeg in excSegs)
            {
                if (int.TryParse(incSeg, out var goodId))
                {
                    _excludeIds.Add(goodId);
                }
            }
        }

        if (inc.IsNullOrEmpty() == false)
        {
            _excludeIds.Clear();
            var incSegs = inc.Split(',');

            foreach (var incSeg in incSegs)
            {
                if (int.TryParse(incSeg, out var goodId))
                {
                    _includeIds.Add(goodId);
                }
            }
        }

        if (vss)
        {
            string driveLetter;
            if (f.IsEmpty() == false)
            {
                driveLetter = Path.GetPathRoot(Path.GetFullPath(f))
                              .Substring(0, 1);
            }
            else
            {
                driveLetter = Path.GetPathRoot(Path.GetFullPath(d))
                              .Substring(0, 1);
            }


            Helper.MountVss(driveLetter, VssDir);
            Console.WriteLine();
        }

        EventLog.TimeDiscrepancyThreshold = tdt;

        if (f.IsNullOrEmpty() == false)
        {
            if (File.Exists(f) == false)
            {
                Log.Warning("\t{F} does not exist! Exiting", f);
                Console.WriteLine();
                return;
            }

            if (_swXml == null && _swJson == null && _swCsv == null)
            {
                //no need for maps
                Log.Debug("Clearing map collection since no output specified");
                EventLog.EventLogMaps.Clear();
            }

            dedupe = false;

            ProcessFile(Path.GetFullPath(f), dedupe, fj, met);

            if (vss)
            {
                var vssDirs = Directory.GetDirectories(VssDir);

                var root = Path.GetPathRoot(Path.GetFullPath(f));
                var stem = Path.GetFullPath(f).Replace(root, "");

                foreach (var vssDir in vssDirs)
                {
                    var newPath = Path.Combine(vssDir, stem);
                    if (File.Exists(newPath))
                    {
                        ProcessFile(newPath, dedupe, fj, met);
                    }
                }
            }
        }
        else
        {
            if (Directory.Exists(d) == false)
            {
                Log.Warning("\t{D} does not exist! Exiting", d);
                Console.WriteLine();
                return;
            }

            Log.Information("Looking for event log files in {D}", d);
            Console.WriteLine();

#if !NET6_0
            var directoryEnumerationFilters = new DirectoryEnumerationFilters
            {
                InclusionFilter = fsei => fsei.Extension.ToUpperInvariant() == ".EVTX",
                RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink,
                ErrorFilter     = (errorCode, errorMessage, pathProcessed) => true
            };

            var dirEnumOptions =
                DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive |
                DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                DirectoryEnumerationOptions.BasicSearch;

            var files2 =
                Directory.EnumerateFileSystemEntries(Path.GetFullPath(d), dirEnumOptions, directoryEnumerationFilters);
#else
            var enumerationOptions = new EnumerationOptions
            {
                IgnoreInaccessible    = true,
                MatchCasing           = MatchCasing.CaseInsensitive,
                RecurseSubdirectories = true,
                AttributesToSkip      = 0
            };

            var files2 =
                Directory.EnumerateFileSystemEntries(d, "*.evtx", enumerationOptions);
#endif

            if (_swXml == null && _swJson == null && _swCsv == null)
            {
                //no need for maps
                Log.Debug("Clearing map collection since no output specified");
                EventLog.EventLogMaps.Clear();
            }

            foreach (var file in files2)
            {
                ProcessFile(file, dedupe, fj, met);
            }

            if (vss)
            {
                var vssDirs = Directory.GetDirectories(VssDir);

                Console.WriteLine();

                foreach (var vssDir in vssDirs)
                {
                    var root = Path.GetPathRoot(Path.GetFullPath(d));
                    var stem = Path.GetFullPath(d).Replace(root, "");

                    var target = Path.Combine(vssDir, stem);

                    Console.WriteLine();
                    Log.Information("Searching {Vss} for event logs...", $"VSS{target.Replace($"{VssDir}\\", "")}");

                    var vssFiles = Helper.GetFilesFromPath(target, "*.evtx", true);

                    foreach (var file in vssFiles)
                    {
                        ProcessFile(file, dedupe, fj, met);
                    }
                }
            }
        }

        try
        {
            _swCsv?.Flush();
            _swCsv?.Close();

            _swJson?.Flush();
            _swJson?.Close();

            _swXml?.Flush();
            _swXml?.Close();
        }
        catch (Exception e)
        {
            Log.Error(e, "Error when flushing output files to disk! Error message: {Message}", e.Message);
        }

        sw.Stop();
        Console.WriteLine();

        if (_fileCount == 1)
        {
            Log.Information("Processed {FileCount:N0} file in {TotalSeconds:N4} seconds", _fileCount, sw.Elapsed.TotalSeconds);
        }
        else
        {
            Log.Information("Processed {FileCount:N0} files in {TotalSeconds:N4} seconds", _fileCount, sw.Elapsed.TotalSeconds);
        }

        Console.WriteLine();

        if (_errorFiles.Count > 0)
        {
            Console.WriteLine();
            Log.Information("Files with errors");
            foreach (var errorFile in _errorFiles)
            {
                Log.Information("{Key} error count: {Value:N0}", errorFile.Key, errorFile.Value);
            }

            Console.WriteLine();
        }

        if (vss)
        {
            if (Directory.Exists(VssDir))
            {
                foreach (var directory in Directory.GetDirectories(VssDir))
                {
                    Directory.Delete(directory);
                }

#if !NET6_0
                Directory.Delete(VssDir, true, true);
#else
                Directory.Delete(VssDir, true);
#endif
            }
        }
    }