- work in progress
- added measurement method to measure search speed - added new search implementation using Parallel.ForEach
This commit is contained in:
parent
2a81943af1
commit
365848d9a1
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 ////////
|
||||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user