- work in progress

- added measurement method to measure search speed
- added new search implementation using Parallel.ForEach
This commit is contained in:
makikvues 2021-01-07 23:23:10 +01:00
parent 2a81943af1
commit 365848d9a1
4 changed files with 240 additions and 12 deletions

View File

@ -590,7 +590,7 @@ namespace winPEAS
} }
} }
try if (!string.IsNullOrEmpty(pathname))
{ {
FileVersionInfo info = FileVersionInfo.GetVersionInfo(pathname.ToString()); FileVersionInfo info = FileVersionInfo.GetVersionInfo(pathname.ToString());
if (!ignore_company.IsMatch(info.CompanyName)) if (!ignore_company.IsMatch(info.CompanyName))
@ -598,10 +598,6 @@ namespace winPEAS
results[pathname] = info; results[pathname] = info;
} }
} }
catch (Exception ex)
{
Beaprint.GrayPrint("Error: " + ex);
}
} }
return results; return results;
} }

View File

@ -0,0 +1,142 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace FastSearchLibrary
{
/// <summary>
/// Represents a class for fast file search.
/// </summary>
public class FileSearcher
{
static public List<FileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null)
{
ConcurrentBag<FileInfo> files = new ConcurrentBag<FileInfo>();
List<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, excludedDirs);
//startDirs.AsParallel().ForAll((d) =>
//{
// GetStartDirectories(d.FullName, files, pattern).AsParallel().ForAll((dir) =>
// {
// GetFiles(dir.FullName, pattern).ForEach((f) => files.Add(f));
// });
//});
Parallel.ForEach(startDirs, (d) =>
{
Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, excludedDirs), (dir) =>
{
GetFiles(dir.FullName, pattern).ForEach((f) => files.Add(f));
});
});
return files.ToList();
}
static private List<DirectoryInfo> GetStartDirectories(
string folder,
ConcurrentBag<FileInfo> files,
string pattern,
HashSet<string> excludedDirs = null)
{
DirectoryInfo[] directories;
if (excludedDirs != null)
{
foreach (var excludedDir in excludedDirs)
{
if (folder.Contains(excludedDir))
{
return new List<DirectoryInfo>();
}
}
}
try
{
DirectoryInfo dirInfo = new DirectoryInfo(folder);
directories = dirInfo.GetDirectories();
foreach (var f in dirInfo.GetFiles(pattern))
{
files.Add(f);
}
if (directories.Length > 1)
return new List<DirectoryInfo>(directories);
if (directories.Length == 0)
return new List<DirectoryInfo>();
}
catch (UnauthorizedAccessException ex)
{
return new List<DirectoryInfo>();
}
catch (PathTooLongException ex)
{
return new List<DirectoryInfo>();
}
catch (DirectoryNotFoundException ex)
{
return new List<DirectoryInfo>();
}
return GetStartDirectories(directories[0].FullName, files, pattern);
}
static public List<FileInfo> GetFiles(string folder, string pattern = "*")
{
DirectoryInfo dirInfo;
DirectoryInfo[] directories;
try
{
dirInfo = new DirectoryInfo(folder);
directories = dirInfo.GetDirectories();
if (directories.Length == 0)
return new List<FileInfo>(dirInfo.GetFiles(pattern));
}
catch (UnauthorizedAccessException ex)
{
return new List<FileInfo>();
}
catch (PathTooLongException ex)
{
return new List<FileInfo>();
}
catch (DirectoryNotFoundException ex)
{
return new List<FileInfo>();
}
List<FileInfo> result = new List<FileInfo>();
foreach (var d in directories)
{
result.AddRange(GetFiles(d.FullName, pattern));
}
try
{
result.AddRange(dirInfo.GetFiles(pattern));
}
catch (UnauthorizedAccessException ex)
{
}
catch (PathTooLongException ex)
{
}
catch (DirectoryNotFoundException ex)
{
}
return result;
}
}
}

View File

@ -5,16 +5,16 @@ using System.IO;
using Microsoft.Win32; using Microsoft.Win32;
using System.Security.Principal; using System.Security.Principal;
using System.Diagnostics; using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Reflection; using System.Reflection;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using FastSearchLibrary;
namespace winPEAS namespace winPEAS
{ {
class MyUtils public class MyUtils
{ {
////////////////////// //////////////////////
/// IsDomainJoined /// /// IsDomainJoined ///
@ -598,7 +598,7 @@ namespace winPEAS
return false; return false;
} }
public static List<string> FindFiles(string path, string patterns) public static List<string> FindFiles_old_implementation(string path, string patterns)
{ {
// finds files matching one or more patterns under a given path, recursive // finds files matching one or more patterns under a given path, recursive
// adapted from http://csharphelper.com/blog/2015/06/find-files-that-match-multiple-patterns-in-c/ // adapted from http://csharphelper.com/blog/2015/06/find-files-that-match-multiple-patterns-in-c/
@ -606,6 +606,11 @@ namespace winPEAS
var files = new List<string>(); var files = new List<string>();
if (!Directory.Exists(path))
{
return files;
}
try try
{ {
// search every pattern in this directory's files // search every pattern in this directory's files
@ -616,18 +621,74 @@ namespace winPEAS
// go recurse in all sub-directories // go recurse in all sub-directories
foreach (var directory in Directory.GetDirectories(path)) foreach (var directory in Directory.GetDirectories(path))
files.AddRange(FindFiles(directory, patterns)); files.AddRange(FindFiles_old_implementation(directory, patterns));
} }
catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) { }
catch (PathTooLongException) { } catch (PathTooLongException) { }
catch (DirectoryNotFoundException) { }
return files; return files;
} }
public static void FindFiles(string path, string patterns, Dictionary<string, string> color) public static List<string> FindFiles_fileSearcher(string path, string patterns)
{
var files = new List<string>();
foreach (string pattern in patterns.Split(';'))
{
// var found = Directory.GetFiles(path, pattern, SearchOption.AllDirectories);
List<FileInfo> res = FileSearcher.GetFilesFast(path, pattern);
files.AddRange(res.Select(s => s.FullName));
}
return files;
}
private static void MeasureMethod(Action action, string description = null)
{
var timer = new Stopwatch();
timer.Start();
action();
timer.Stop();
TimeSpan timeTaken = timer.Elapsed;
string log = $"({description ?? string.Empty}) Time taken: " + timeTaken.ToString(@"m\:ss\.fff");
Beaprint.LinkPrint(log);
}
private static void PrintSearchResults(IEnumerable<string> results, string description = null)
{
Beaprint.LinkPrint($"------------------------- results: {description ?? string.Empty} --------------------------------");
if (results != null)
{
Beaprint.LinkPrint(string.Join("\n", results ?? Enumerable.Empty<string>()));
}
Beaprint.LinkPrint($"------------------------- results: {description ?? string.Empty} --------------------------------");
Beaprint.LinkPrint("\n\n\n\n");
}
public static List<string> FindFiles(string path, string patterns)
{
List<string> result = new List<string>();
MeasureMethod(() => result = FindFiles_old_implementation(path, patterns), "old implementation");
PrintSearchResults(result, "old implementation");
MeasureMethod(() => result = FindFiles_fileSearcher(path, patterns), "new implementation");
PrintSearchResults(result, "new implementation");
return result;
}
public static void FindFiles_old_implementation(string path, string patterns, Dictionary<string, string> color)
{ {
try try
{ {
if (!Directory.Exists(path))
{
return;
}
// search every pattern in this directory's files // search every pattern in this directory's files
foreach (string pattern in patterns.Split(';')) foreach (string pattern in patterns.Split(';'))
{ {
@ -641,13 +702,37 @@ namespace winPEAS
foreach (string directory in Directory.GetDirectories(path)) foreach (string directory in Directory.GetDirectories(path))
{ {
if (!directory.Contains("AppData")) if (!directory.Contains("AppData"))
FindFiles(directory, patterns, color); FindFiles_old_implementation(directory, patterns, color);
} }
} }
catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) { }
catch (PathTooLongException) { } catch (PathTooLongException) { }
catch (DirectoryNotFoundException) { }
} }
public static void FindFiles_fileSearcher(string path, string patterns, Dictionary<string, string> color, HashSet<string> excludedDirs = null)
{
// search every pattern in this directory's files
foreach (string pattern in patterns.Split(';'))
{
// var found = Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly).Where(filepath => !filepath.Contains(".dll"));
List<FileInfo> res = FileSearcher.GetFilesFast(path, pattern, excludedDirs);
var found = res.Where(filepath => filepath.Extension != null && !filepath.Extension.Equals("dll")).Select(s => s.FullName);
Beaprint.AnsiPrint(" " + String.Join("\n ", found), color);
}
}
public static void FindFiles(string path, string patterns, Dictionary<string, string> color)
{
Beaprint.LinkPrint($"------------------------- results: old implementation --------------------------------");
MeasureMethod(() => FindFiles_old_implementation(path, patterns, color), "old implementation");
Beaprint.LinkPrint($"------------------------- results: old implementation --------------------------------");
Beaprint.LinkPrint("\n\n\n\n");
Beaprint.LinkPrint($"------------------------- results: new implementation --------------------------------");
HashSet<string> excludedDirs = new HashSet<string>() { "AppData" };
MeasureMethod(() => FindFiles_fileSearcher(path, patterns, color, excludedDirs), "new implementation");
Beaprint.LinkPrint($"------------------------- results: new implementation --------------------------------");
}
////////////////////// //////////////////////
//////// MISC //////// //////// MISC ////////

View File

@ -87,6 +87,9 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<StartupObject>winPEAS.Program</StartupObject>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -104,6 +107,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="ApplicationInfo.cs" /> <Compile Include="ApplicationInfo.cs" />
<Compile Include="Beaprint.cs" /> <Compile Include="Beaprint.cs" />
<Compile Include="FastSearch\FileSearcher\FileSearcher.cs" />
<Compile Include="InterestingFiles.cs" /> <Compile Include="InterestingFiles.cs" />
<Compile Include="KnownFileCredsInfo.cs" /> <Compile Include="KnownFileCredsInfo.cs" />
<Compile Include="MyUtils.cs" /> <Compile Include="MyUtils.cs" />
@ -173,5 +177,6 @@
<EmbeddedResource Include="Properties\Resources.ru.resx" /> <EmbeddedResource Include="Properties\Resources.ru.resx" />
<EmbeddedResource Include="Properties\Resources.zh-CN.resx" /> <EmbeddedResource Include="Properties\Resources.zh-CN.resx" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>