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