public static ScanResults PopulateFileProperties(ScanParameters parameters, char driveLetter, INode node)
        {
            CancellationToken cancelToken = parameters.CancelToken;

            cancelToken.ThrowIfCancellationRequested();

            ScanResults results = new ScanResults();

            byte[] fileBytes = new byte[0];
            if (!node.Streams.Any())             //workaround for no file stream such as with hard links
            {
                try
                {
                    using (FileStream fsSource = new FileStream(node.FullName,
                                                                FileMode.Open, FileAccess.Read))
                    {
                        // Read the source file into a byte array.
                        fileBytes = new byte[fsSource.Length];
                        int numBytesToRead = (int)fsSource.Length;
                        int numBytesRead   = 0;
                        while (numBytesToRead > 0)
                        {
                            // Read may return anything from 0 to numBytesToRead.
                            int n = fsSource.Read(fileBytes, numBytesRead, numBytesToRead);

                            // Break when the end of the file is reached.
                            if (n == 0)
                            {
                                break;
                            }

                            numBytesRead   += n;
                            numBytesToRead -= n;
                        }
                        numBytesToRead = fileBytes.Length;
                    }
                }
                catch
                { }
            }
            else
            {
                fileBytes = node.GetBytes().SelectMany(chunk => chunk).ToArray();
                cancelToken.ThrowIfCancellationRequested();
            }

            string yaraIndexFilename = results.PopulateYaraInfo(parameters.YaraParameters);

            if (!string.IsNullOrWhiteSpace(yaraIndexFilename))
            {
                results.YaraDetections = YaraHelper.ScanBytes(fileBytes, yaraIndexFilename);
            }

            throw new NotImplementedException();

            return(results);
        }
        public static void LaunchFileScan(ScanParameters parameters)
        {
            var fileEnumerationDelegate
                = new Func <ScanParameters, List <string> >((args) => Worker(args));

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

            Task reportResultsTask = enumerationTask.ContinueWith((antecedent) => parameters.ReportResultsFunction(antecedent.Result));
        }
        private static List <string> Worker(ScanParameters parameters)
        {
            List <string> resultsAggregate = new List <string>();

            try
            {
                IEnumerable <INode>   mftNodes             = FileEnumerator.EnumerateFiles(parameters);
                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}";

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

                    ScanResults results = new ScanResults();
                    results = PopulateFileProperties(parameters, parameters.SelectedFolder[0], node);

                    resultsAggregate.AddRange(results.YaraDetections);

                    // Insert scan results into IDataPersistenceLayer
                    bool insertResult = dataPersistenceLayer.PersistFileProperties(results);
                    if (insertResult)
                    {
                    }
                    else
                    {
                    }

                    parameters.CancelToken.ThrowIfCancellationRequested();
                }

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

            return(resultsAggregate);
        }
Esempio n. 4
0
        public static IEnumerable <INode> EnumerateFiles(ScanParameters parameters)
        {
            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();

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

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

            return(mftNodes);
        }
        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);

                string selectedFolder = tbPath.Text;

                List <YaraFilter> yaraParameters = new List <YaraFilter>();
                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);
                }

                ScanParameters parameters =
                    new ScanParameters(
                        cancelToken,
                        selectedFolder,
                        yaraParameters,
                        dataPersistenceLayer,
                        Log.ToUI,
                        Log.ToFile,
                        ReporResults,
                        Log.ExceptionMessage
                        );

                enumerationStart = DateTime.Now;

                bool didThrow = false;
                try
                {
                    parameters.ThrowIfAnyParametersInvalid();
                }
                catch (Exception ex)
                {
                    didThrow = true;
                    string message = ex.ToString().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
                    Log.ToAll(message);
                    MessageBox.Show(message, "", 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)");
                    FileScanner.LaunchFileScan(parameters);
                }
            }
        }