Esempio n. 1
0
        public static void LaunchFileEnumerator(FileEnumeratorParameters parameters)
        {
            ThrowIfParametersInvalid(parameters);

            var fileEnumerationDelegate
                = new Func <FileEnumeratorParameters, List <FailSuccessCount> >((args) => ThreadLauncher(args));

            if (!parameters.DisableWorkerThread)
            {
                Task <List <FailSuccessCount> > enumerationTask = Task.Run(() =>
                {
                    List <FailSuccessCount> results = new List <FailSuccessCount>();
                    results.AddRange(fileEnumerationDelegate.Invoke(parameters));
                    return(results);
                },
                                                                           parameters.CancelToken);

                Task reportResultsTask = enumerationTask.ContinueWith((antecedent) => parameters.ReportResultsFunction(antecedent.Result));
            }
            else
            {
                List <FailSuccessCount> results = fileEnumerationDelegate.Invoke(parameters);
                parameters.ReportResultsFunction(results);
            }
        }
Esempio n. 2
0
        private static List <FailSuccessCount> ThreadLauncher(FileEnumeratorParameters parameters)
        {
            fileEnumCount       = new FailSuccessCount("OS files enumerated");
            databaseInsertCount = new FailSuccessCount("OS database rows updated");
            directoryEnumCount  = new FailSuccessCount("directories enumerated");

            try
            {
                char           driveLetter = parameters.SelectedFolder[0];
                Queue <string> folders     = new Queue <string>(new string[] { parameters.SelectedFolder });

                while (folders.Count > 0)
                {
                    parameters.CancelToken.ThrowIfCancellationRequested();

                    string currentDirectory = folders.Dequeue();

                    // Get all _FILES_ inside folder
                    IEnumerable <FileProperties> properties = EnumerateFileProperties(parameters, driveLetter, currentDirectory);
                    foreach (FileProperties prop in properties)
                    {
                        parameters.CancelToken.ThrowIfCancellationRequested();

                        // INSERT file properties into _DATABASE_
                        bool insertResult = FilePropertiesAccessLayer.InsertFileProperties(prop);
                        if (insertResult)
                        {
                            databaseInsertCount.IncrementSucceededCount();
                        }
                        else
                        {
                            databaseInsertCount.IncrementFailedCount();
                            parameters.CancelToken.ThrowIfCancellationRequested();
                            continue;
                        }

                        parameters.CancelToken.ThrowIfCancellationRequested();
                    }

                    // Get all _FOLDERS_ at this depth inside this folder
                    IEnumerable <NtfsDirectory> nestedDirectories = MftHelper.GetDirectories(driveLetter, currentDirectory);
                    foreach (NtfsDirectory directory in nestedDirectories)
                    {
                        parameters.CancelToken.ThrowIfCancellationRequested();
                        string dirPath = Path.Combine(currentDirectory, directory.Name);
                        folders.Enqueue(dirPath);
                        directoryEnumCount.IncrementSucceededCount();
                        parameters.CancelToken.ThrowIfCancellationRequested();
                    }
                }
            }
            catch (OperationCanceledException)
            { }

            return(new List <FailSuccessCount> {
                fileEnumCount, databaseInsertCount, directoryEnumCount
            });
        }
        public BackgroundEnumerationThread(FileEnumeratorParameters parameters)
        {
            configuration = parameters;
            cancelToken   = configuration.CancelToken;
            cancelToken.Register(() => CancelBackgroundWorker());

            reportProgressFuntionDelegate = configuration.ReportOutputFunction;
            completedFuntionDelegate      = configuration.ReportResultsFunction;

            worker = new BackgroundWorker();
            worker.WorkerReportsProgress      = true;
            worker.WorkerSupportsCancellation = true;
            worker.RunWorkerCompleted        += OnRunWorkerCompleted;
            worker.ProgressChanged           += Worker_ProgressChanged;
            worker.DoWork += OnDoWork;
        }
Esempio n. 4
0
        public static void LaunchFileEnumerator(FileEnumeratorParameters parameters)
        {
            var fileEnumerationDelegate
                = new Func <FileEnumeratorParameters, FileEnumeratorReport>((args) => Worker(args));

            if (!parameters.DisableWorkerThread)
            {
                Task <FileEnumeratorReport> enumerationTask = Task.Run(() =>
                {
                    FileEnumeratorReport results = fileEnumerationDelegate.Invoke(parameters);
                    return(results);
                },
                                                                       parameters.CancelToken);

                Task reportResultsTask = enumerationTask.ContinueWith((antecedent) => parameters.ReportResultsFunction(antecedent.Result));
            }
            else
            {
                FileEnumeratorReport results = fileEnumerationDelegate.Invoke(parameters);
                parameters.ReportResultsFunction(results);
            }
        }
        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (ProcessingToggle.IsActive)
            {
                btnSearch.Enabled = false;
                ProcessingToggle.SetState(false);
            }
            else
            {
                btnSearch.Text = "Cancel";
                ProcessingToggle.SetState(true);

                bool   calculateEntropy     = checkboxCalculateEntropy.Checked;
                bool   onlineCertValidation = checkboxOnlineCertValidation.Checked;
                string selectedFolder       = tbPath.Text;
                string searchPatterns       = tbSearchPatterns.Text;

                string yaraRulesPath = "";

                if (checkBoxYaraRules.Checked)
                {
                    yaraRulesPath = tbYaraRuleFile.Text;
                }

                FileEnumeratorParameters parameters =
                    new FileEnumeratorParameters(cancelToken, Settings.FileEnumeration_DisableWorkerThread, selectedFolder, searchPatterns, calculateEntropy, onlineCertValidation, yaraRulesPath,
                                                 ReportOutput, LogOutput, ReportNumbers, LogExceptionMessage);



                tbOutput.AppendText(Environment.NewLine);
                ReportOutput($"Beginning Enumeration of folder: \"{selectedFolder}\"");

                enumerationStart = DateTime.Now;

                FileEnumerator.LaunchFileEnumerator(parameters);
            }
        }
Esempio n. 6
0
        public static IEnumerable <FileProperties> EnumerateFileProperties(FileEnumeratorParameters parameters, char driveLetter, string currentDirectory)
        {
            foreach (NtfsFile file in MftHelper.EnumerateFiles(driveLetter, currentDirectory))
            {
                parameters.CancelToken.ThrowIfCancellationRequested();

                // File _PATTERN MATCHING_
                if (FileMatchesPattern(file, parameters.SearchPatterns))
                {
                    string message = $"MFT File: {Path.Combine(currentDirectory, file.Name)}";
                    if (parameters.LogOutputFunction != null)
                    {
                        parameters.LogOutputFunction.Invoke(message);
                    }
                    if (parameters.ReportOutputFunction != null)
                    {
                        parameters.ReportOutputFunction.Invoke(message);
                    }

                    fileEnumCount.IncrementSucceededCount();
                    parameters.CancelToken.ThrowIfCancellationRequested();

                    FileProperties prop = new FileProperties();
                    prop.PopulateFileProperties(parameters, driveLetter, file);

                    parameters.CancelToken.ThrowIfCancellationRequested();

                    yield return(prop);
                }
                else
                {
                    fileEnumCount.IncrementFailedCount();
                    parameters.CancelToken.ThrowIfCancellationRequested();
                }
            }
            yield break;
        }
Esempio n. 7
0
 private static void ThrowIfParametersInvalid(FileEnumeratorParameters parameters)
 {
     if (parameters == null)
     {
         throw new ArgumentNullException(nameof(parameters));
     }
     if (parameters.SearchPatterns == null)
     {
         throw new ArgumentNullException(nameof(parameters.SearchPatterns));
     }
     if (parameters.ReportExceptionFunction == null)
     {
         throw new ArgumentNullException(nameof(parameters.ReportExceptionFunction));
     }
     if (parameters.ReportOutputFunction == null)
     {
         throw new ArgumentNullException(nameof(parameters.ReportOutputFunction));
     }
     if (parameters.LogOutputFunction == null)
     {
         throw new ArgumentNullException(nameof(parameters.LogOutputFunction));
     }
     if (parameters.ReportResultsFunction == null)
     {
         throw new ArgumentNullException(nameof(parameters.ReportResultsFunction));
     }
     if (!Directory.Exists(parameters.SelectedFolder))
     {
         throw new DirectoryNotFoundException(parameters.SelectedFolder);
     }
     if (parameters.CancelToken == null)
     {
         throw new ArgumentNullException(nameof(parameters.CancelToken), "If you do not want to pass a CancellationToken, then pass 'CancellationToken.None'");
     }
     parameters.CancelToken.ThrowIfCancellationRequested();
 }
        private void BeginScanning()
        {
            if (ProcessingToggle.CurrentState == ToggleState.Active)
            {
                btnSearch.Enabled = false;
                ProcessingToggle.SetState(ToggleState.Inactive);
            }
            else if (ProcessingToggle.CurrentState == ToggleState.Ready)
            {
                btnSearch.Enabled = false;
                ProcessingToggle.SetState(ToggleState.Active);

                bool   calculateEntropy = checkboxCalculateEntropy.Checked;
                string selectedFolder   = tbPath.Text;
                string searchPatterns   = tbSearchPatterns.Text;

                List <YaraFilter> yaraParameters = new List <YaraFilter>();
                if (checkBoxYaraRules.Checked)
                {
                    yaraParameters = currentYaraFilters.ToList();
                }

                IDataPersistenceLayer dataPersistenceLayer = null;
                if (radioPersistenceCSV.Checked)
                {
                    dataPersistenceLayer = new CsvDataPersistenceLayer(tbPersistenceParameter.Text);
                }
                else if (radioPersistenceSqlite.Checked)
                {
                    dataPersistenceLayer = new SqliteDataPersistenceLayer(tbPersistenceParameter.Text);
                }
                else if (radioPersistenceSqlServer.Checked)
                {
                    dataPersistenceLayer = new SqlDataPersistenceLayer(tbPersistenceParameter.Text);
                }

                FileEnumeratorParameters parameters =
                    new FileEnumeratorParameters(cancelToken,
                                                 Settings.FileEnumeration_DisableWorkerThread,
                                                 selectedFolder,
                                                 searchPatterns,
                                                 calculateEntropy,
                                                 yaraParameters,
                                                 dataPersistenceLayer,
                                                 Log.ToUI, Log.ToFile, ReportNumbers, Log.ExceptionMessage);

                enumerationStart = DateTime.Now;

                bool didThrow = false;
                try
                {
                    parameters.ThrowIfAnyParametersInvalid();
                }
                catch (Exception ex)
                {
                    didThrow = true;
                    MessageBox.Show(
                        ex.ToString().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(),
                        MsgBox_TitleBarText,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error
                        );
                }

                if (didThrow)
                {
                    ProcessingToggle.SetState(ToggleState.Ready);
                }
                else
                {
                    Log.ToUI(Environment.NewLine);
                    Log.ToAll($"Beginning Enumeration of folder: \"{parameters.SelectedFolder}\"");
                    Log.ToAll("Parsing MFT. (This may take a few minutes)");
                    FileEnumerator.LaunchFileEnumerator(parameters);
                }
            }
        }
        private static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                DisplayUsageSyntax();
                return;
            }

            // Will hold flag & parameter to flag, such as: "-p", "C:\Windows\"
            List <Tuple <string, string> > flags = GetFlags(args);

            if (!flags.Any())
            {
                DisplayUsageSyntax();
                return;
            }

            string            searchPath          = "";
            string            searchMask          = "*.*";
            bool              isEntropyEnabled    = false;
            bool              isYaraEnabled       = false;
            bool              isSqlServerEnabled  = false;
            bool              isSqliteEnabled     = false;
            bool              isCsvEnabled        = false;
            string            sqliteDbFile        = "";
            string            csvFile             = "";
            string            sqlConnectionString = (Settings.Database_ConnectionString == "SetMe") ? "" : Settings.Database_ConnectionString;
            string            yaraFiltersFile     = "";
            List <YaraFilter> yaraFilters         = new List <YaraFilter>();

            foreach (Tuple <string, string> flagTuple in flags)
            {
                string flag      = flagTuple.Item1;
                string parameter = flagTuple.Item2;

                switch (flag)
                {
                case "e":
                    isEntropyEnabled = true;
                    break;

                case "p":
                    searchPath = parameter;
                    break;

                case "m":
                    searchMask = parameter;
                    break;

                case "y":
                    isYaraEnabled   = true;
                    yaraFiltersFile = parameter;
                    break;

                case "s":
                    isSqlServerEnabled = true;
                    break;

                case "l":
                    isSqliteEnabled = true;
                    sqliteDbFile    = string.IsNullOrWhiteSpace(parameter) ? sqlConnectionString : parameter;
                    break;

                case "c":
                    isCsvEnabled = true;
                    csvFile      = parameter;
                    break;
                }
            }

            ReportOutput();
            ReportOutput("Running with these parameters:");
            ReportOutput($"   Search [P]ath:       \"{searchPath}\"");
            ReportOutput($"   Search [M]ask:        {searchMask}");
            ReportOutput($"   Calulate [E]ntropy:   {isEntropyEnabled}");
            if (isYaraEnabled)
            {
                ReportOutput($"   [Y]ara filters file: \"{yaraFiltersFile}\"");
            }

            if (isSqlServerEnabled)
            {
                ReportOutput($"   [S]QL connection: \"{sqlConnectionString}\"");
            }
            else if (isSqliteEnabled)
            {
                ReportOutput($"   Sq[l]ite DB: \"{sqliteDbFile}\"");
            }
            else if (isCsvEnabled)
            {
                ReportOutput($"   [C]SV file: \"{csvFile}\"");
            }

            ReportOutput();

            if (string.IsNullOrWhiteSpace(searchPath))
            {
                ReportOutput("No search path provided!");
                ReportOutput("You must supply the -p flag with a path, e.g.:");
                ReportOutput("-p:\"C:\\Program Files\\BanzaiBuddy\"");
                ReportOutput();
                ReportOutput("Aborting...");
                return;
            }

            if (isYaraEnabled)
            {
                if (!File.Exists(yaraFiltersFile))
                {
                    ReportOutput($"The yara filters file path suppled does not exist: \"{yaraFiltersFile}\".");
                    ReportOutput();
                    ReportOutput("Aborting...");
                    return;
                }
                try
                {
                    string loadJson = File.ReadAllText(yaraFiltersFile);
                    yaraFilters = JsonConvert.DeserializeObject <List <YaraFilter> >(loadJson);
                }
                catch
                {
                    ReportOutput("The yara filters file must be a JSON file.");
                    ReportOutput();
                    ReportOutput("Aborting...");
                    return;
                }
            }

            IDataPersistenceLayer dataPersistenceLayer;

            if (isSqliteEnabled)
            {
                dataPersistenceLayer = new SqliteDataPersistenceLayer(sqliteDbFile);
            }
            else if (isCsvEnabled)
            {
                dataPersistenceLayer = new CsvDataPersistenceLayer(csvFile);
            }
            else if (isSqlServerEnabled)
            {
                dataPersistenceLayer = new SqlDataPersistenceLayer(sqlConnectionString);
            }
            else
            {
                ReportOutput("No output parameter provided!");

                if (!string.IsNullOrWhiteSpace(sqlConnectionString))
                {
                    ReportOutput("(SQL server connection string supplied in config file, asuming SQL server output...)");
                    dataPersistenceLayer = new SqlDataPersistenceLayer(sqlConnectionString);
                }
                else
                {
                    ReportOutput("You must supply an output parameter, e.g.:");
                    ReportOutput("-c:C:\\out.csv");
                    ReportOutput($"OR provide a SQL server connection string in the config file: {_thisExecutableFilename}");
                    ReportOutput("(Because it defaults to a SQL server connection. However, the connection string was missing.)");
                    ReportOutput();
                    ReportOutput("Aborting...");
                    return;
                }
            }

            FileEnumeratorParameters parameters =
                new FileEnumeratorParameters(
                    CancellationToken.None,
                    true,                             // Do not change this. If set to false, it will run on a thread, return immediately and exit, killing the thread.
                    searchPath,
                    searchMask,
                    isEntropyEnabled,
                    yaraFilters,
                    dataPersistenceLayer,
                    ReportOutput,
                    Log.LogOutputAction,
                    ReportResults,
                    Log.ExceptionMessage
                    );

            parameters.ThrowIfAnyParametersInvalid();

            ReportOutput("Beginning scan...");
            FileEnumerator.LaunchFileEnumerator(parameters);
        }
Esempio n. 10
0
        private static FileEnumeratorReport Worker(FileEnumeratorParameters parameters)
        {
            TimingMetrics    timingMetrics       = new TimingMetrics();
            FailSuccessCount fileEnumCount       = new FailSuccessCount("OS files enumerated");
            FailSuccessCount databaseInsertCount = new FailSuccessCount("OS database rows updated");

            try
            {
                parameters.CancelToken.ThrowIfCancellationRequested();

                StringBuilder currentPath = new StringBuilder(parameters.SelectedFolder);
                string        lastParent  = currentPath.ToString();

                string temp = currentPath.ToString();
                if (temp.Contains(':') && (temp.Length == 2 || temp.Length == 3))                 // Is a root directory, i.e. "C:" or "C:\"
                {
                    lastParent = ".";
                }

                string drive = parameters.SelectedFolder[0].ToString().ToUpper();

                timingMetrics.Start(TimingMetric.ParsingMFT);

                List <DriveInfo> ntfsDrives = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveFormat == "NTFS").ToList();

                DriveInfo driveToAnalyze = ntfsDrives.Where(dr => dr.Name.ToUpper().Contains(drive)).Single();

                NtfsReader ntfsReader = new NtfsReader(driveToAnalyze, RetrieveMode.All);

                IEnumerable <INode> mftNodes =
                    ntfsReader.GetNodes(driveToAnalyze.Name)
                    .Where(node => (node.Attributes &
                                    (NtfsNodeAttributes.Device
                                     | NtfsNodeAttributes.Directory
                                     | NtfsNodeAttributes.ReparsePoint
                                     | NtfsNodeAttributes.SparseFile
                                    )) == 0)                                      // This means that we DONT want any matches of the above NtfsNodeAttributes type
                    .Where(node => FileMatchesPattern(node.FullName, parameters.SearchPatterns));
                //.OrderByDescending(n => n.Size);

                if (parameters.SelectedFolder.ToCharArray().Length > 3)
                {
                    string selectedFolderUppercase = parameters.SelectedFolder.ToUpperInvariant().TrimEnd(new char[] { '\\' });
                    mftNodes = mftNodes.Where(node => node.FullName.ToUpperInvariant().Contains(selectedFolderUppercase));
                }

                timingMetrics.Stop(TimingMetric.ParsingMFT);

                IDataPersistenceLayer dataPersistenceLayer = parameters.DataPersistenceLayer;

                foreach (INode node in mftNodes)
                {
                    string message = $"MFT#: {node.MFTRecordNumber.ToString().PadRight(7)} Seq.#: {node.SequenceNumber.ToString().PadRight(4)} Path: {node.FullName}";

                    parameters.ReportAndLogOutputFunction.Invoke(message);

                    fileEnumCount.IncrementSucceededCount();

                    FileProperties prop = new FileProperties();
                    prop.PopulateFileProperties(parameters, parameters.SelectedFolder[0], node, timingMetrics);

                    // INSERT file properties into _DATABASE_
                    timingMetrics.Start(TimingMetric.PersistingFileProperties);
                    bool insertResult = dataPersistenceLayer.PersistFileProperties(prop);
                    if (insertResult)
                    {
                        databaseInsertCount.IncrementSucceededCount();
                    }
                    else
                    {
                        databaseInsertCount.IncrementFailedCount();
                    }
                    timingMetrics.Stop(TimingMetric.PersistingFileProperties);

                    parameters.CancelToken.ThrowIfCancellationRequested();
                }

                dataPersistenceLayer.Dispose();
                FileProperties.CleanUp();
            }
            catch (OperationCanceledException)
            { }

            return(new FileEnumeratorReport(new List <FailSuccessCount> {
                fileEnumCount, databaseInsertCount
            }, timingMetrics));
        }
Esempio n. 11
0
        private static List <FailSuccessCount> Worker(FileEnumeratorParameters parameters)
        {
            fileEnumCount       = new FailSuccessCount("OS files enumerated");
            databaseInsertCount = new FailSuccessCount("OS database rows updated");
            directoryEnumCount  = new FailSuccessCount("directories enumerated");

            try
            {
                parameters.CancelToken.ThrowIfCancellationRequested();

                StringBuilder currentPath = new StringBuilder(parameters.SelectedFolder);
                string        lastParent  = currentPath.ToString();

                string temp = currentPath.ToString();
                if (temp.Contains(':') && (temp.Length == 2 || temp.Length == 3))                 // Is a root directory, i.e. "C:" or "C:\"
                {
                    lastParent = ".";
                }

                string drive = parameters.SelectedFolder[0].ToString();

                List <DriveInfo> ntfsDrives = DriveInfo.GetDrives().Where(d => d.DriveFormat == "NTFS").ToList();

                DriveInfo driveToAnalyze = ntfsDrives.Where(dr => dr.Name.ToUpper().Contains(drive.ToUpper())).Single();

                IEnumerable <INode> mftNodes = MftHelper.EnumerateMft(driveToAnalyze);

                if (parameters.SelectedFolder.ToCharArray().Length > 3)
                {
                    string selectedFolderUppercase = parameters.SelectedFolder.ToUpperInvariant().TrimEnd(new char[] { '\\' });
                    mftNodes = mftNodes.Where(node => node.FullName.ToUpperInvariant().Contains(selectedFolderUppercase));
                }

                foreach (INode node in mftNodes)
                {
                    // File _PATTERN MATCHING_
                    if (FileMatchesPattern(node.FullName, parameters.SearchPatterns))
                    {
                        string message = $"MFT#: {node.MFTRecordNumber.ToString().PadRight(7)} Seq.#: {node.SequenceNumber.ToString().PadRight(4)} Path: {node.FullName}";

                        if (parameters.LogOutputFunction != null)
                        {
                            parameters.LogOutputFunction.Invoke(message);
                        }
                        if (parameters.ReportOutputFunction != null)
                        {
                            parameters.ReportOutputFunction.Invoke(message);
                        }

                        fileEnumCount.IncrementSucceededCount();
                        parameters.CancelToken.ThrowIfCancellationRequested();

                        FileProperties prop = new FileProperties();
                        prop.PopulateFileProperties(parameters, parameters.SelectedFolder[0], node);

                        parameters.CancelToken.ThrowIfCancellationRequested();

                        // INSERT file properties into _DATABASE_
                        bool insertResult = FilePropertiesAccessLayer.InsertFileProperties(prop);
                        if (insertResult)
                        {
                            databaseInsertCount.IncrementSucceededCount();
                        }
                        else
                        {
                            databaseInsertCount.IncrementFailedCount();
                        }
                    }
                    else
                    {
                        if (parameters.LogOutputFunction != null)
                        {
                            parameters.LogOutputFunction.Invoke($"FileMatchingPattern returned false: \"{node.FullName}\"");
                        }

                        fileEnumCount.IncrementFailedCount();
                    }

                    parameters.CancelToken.ThrowIfCancellationRequested();
                }
            }
            catch (OperationCanceledException)
            { }

            return(new List <FailSuccessCount> {
                fileEnumCount, databaseInsertCount, directoryEnumCount
            });
        }
Esempio n. 12
0
        private static void Main(string[] args)
        {
            string connectionString = Settings.Database_ConnectionString;

            if (string.IsNullOrWhiteSpace(connectionString) || connectionString == "SetMe")
            {
                ReportOutput("ERROR: Connection string not set! Please set the SQL connection string in .config file.");
                ReportOutput("Aborting...");
                return;
            }
            else
            {
                FilePropertiesAccessLayer.SetConnectionString(connectionString);
            }

            if (args.Length == 0)
            {
                DisplayUsageSyntax();
                return;
            }

            // Will hold flag & parameter to flag, such as: "-p", "C:\Windows\"
            List <Tuple <string, string> > flags = GetFlags(args);

            if (!flags.Any())
            {
                return;
            }

            string searchPath       = "";
            string searchMask       = "*.*";
            bool   calcEntropy      = false;
            bool   onlineValidation = false;
            string yaraRulesFile    = "";

            foreach (Tuple <string, string> flagTuple in flags)
            {
                string flag      = flagTuple.Item1;
                string parameter = flagTuple.Item2;

                switch (flag)
                {
                case "e":
                    calcEntropy = true;
                    break;

                case "v":
                    onlineValidation = true;
                    break;

                case "p":
                    searchPath = parameter;
                    break;

                case "m":
                    searchMask = parameter;
                    break;

                case "y":
                    yaraRulesFile = parameter;
                    break;
                }
            }

            ReportOutput($"Search [P]ath: \"{searchPath}\"");
            ReportOutput($"Search [M]ask: {searchMask}");
            ReportOutput($"Calulate [E]ntropy: {calcEntropy}");
            ReportOutput($"Online [V]alidation: {onlineValidation}");
            ReportOutput($"[Y]ara Rules File: \"{yaraRulesFile}\"");
            ReportOutput("");

            FileEnumeratorParameters parameters = new FileEnumeratorParameters(CancellationToken.None, Settings.FileEnumeration_DisableWorkerThread, searchPath, searchMask, calcEntropy, onlineValidation, yaraRulesFile, ReportOutput, LogOutput, ReportResults, ReportException);

            ReportOutput("Beginning enumeration...");
            FileEnumerator.LaunchFileEnumerator(parameters);
        }