diff --git a/winPEAS/winPEASexe/winPEAS/ApplicationInfo.cs b/winPEAS/winPEASexe/winPEAS/ApplicationInfo.cs index 35dcf97..a1a1c49 100755 --- a/winPEAS/winPEASexe/winPEAS/ApplicationInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/ApplicationInfo.cs @@ -590,7 +590,7 @@ namespace winPEAS } } - try + if (!string.IsNullOrEmpty(pathname)) { FileVersionInfo info = FileVersionInfo.GetVersionInfo(pathname.ToString()); if (!ignore_company.IsMatch(info.CompanyName)) @@ -598,10 +598,6 @@ namespace winPEAS results[pathname] = info; } } - catch (Exception ex) - { - Beaprint.GrayPrint("Error: " + ex); - } } return results; } diff --git a/winPEAS/winPEASexe/winPEAS/FastSearch/FileSearcher/FileSearcher.cs b/winPEAS/winPEASexe/winPEAS/FastSearch/FileSearcher/FileSearcher.cs new file mode 100644 index 0000000..e35b851 --- /dev/null +++ b/winPEAS/winPEASexe/winPEAS/FastSearch/FileSearcher/FileSearcher.cs @@ -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 +{ + + /// + /// Represents a class for fast file search. + /// + public class FileSearcher + { + static public List GetFilesFast(string folder, string pattern = "*", HashSet excludedDirs = null) + { + ConcurrentBag files = new ConcurrentBag(); + + List 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 GetStartDirectories( + string folder, + ConcurrentBag files, + string pattern, + HashSet excludedDirs = null) + { + DirectoryInfo[] directories; + + if (excludedDirs != null) + { + foreach (var excludedDir in excludedDirs) + { + if (folder.Contains(excludedDir)) + { + return new List(); + } + } + } + + 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(directories); + + if (directories.Length == 0) + return new List(); + + } + catch (UnauthorizedAccessException ex) + { + return new List(); + } + catch (PathTooLongException ex) + { + return new List(); + } + catch (DirectoryNotFoundException ex) + { + return new List(); + } + + return GetStartDirectories(directories[0].FullName, files, pattern); + } + + static public List GetFiles(string folder, string pattern = "*") + { + DirectoryInfo dirInfo; + DirectoryInfo[] directories; + try + { + dirInfo = new DirectoryInfo(folder); + directories = dirInfo.GetDirectories(); + + if (directories.Length == 0) + return new List(dirInfo.GetFiles(pattern)); + } + catch (UnauthorizedAccessException ex) + { + return new List(); + } + catch (PathTooLongException ex) + { + return new List(); + } + catch (DirectoryNotFoundException ex) + { + return new List(); + } + + List result = new List(); + + 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; + } + } +} diff --git a/winPEAS/winPEASexe/winPEAS/MyUtils.cs b/winPEAS/winPEASexe/winPEAS/MyUtils.cs index e9749e3..6a5983c 100755 --- a/winPEAS/winPEASexe/winPEAS/MyUtils.cs +++ b/winPEAS/winPEASexe/winPEAS/MyUtils.cs @@ -5,16 +5,16 @@ using System.IO; using Microsoft.Win32; using System.Security.Principal; using System.Diagnostics; -using System.Net; using System.Text.RegularExpressions; using System.Reflection; using System.Security.AccessControl; using System.Runtime.InteropServices; using System.Threading; +using FastSearchLibrary; namespace winPEAS { - class MyUtils + public class MyUtils { ////////////////////// /// IsDomainJoined /// @@ -598,7 +598,7 @@ namespace winPEAS return false; } - public static List FindFiles(string path, string patterns) + public static List FindFiles_old_implementation(string path, string patterns) { // 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/ @@ -606,6 +606,11 @@ namespace winPEAS var files = new List(); + if (!Directory.Exists(path)) + { + return files; + } + try { // search every pattern in this directory's files @@ -616,22 +621,78 @@ namespace winPEAS // go recurse in all sub-directories foreach (var directory in Directory.GetDirectories(path)) - files.AddRange(FindFiles(directory, patterns)); + files.AddRange(FindFiles_old_implementation(directory, patterns)); } catch (UnauthorizedAccessException) { } catch (PathTooLongException) { } + catch (DirectoryNotFoundException) { } return files; } - public static void FindFiles(string path, string patterns, Dictionary color) + public static List FindFiles_fileSearcher(string path, string patterns) + { + var files = new List(); + + foreach (string pattern in patterns.Split(';')) + { + // var found = Directory.GetFiles(path, pattern, SearchOption.AllDirectories); + List 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 results, string description = null) + { + Beaprint.LinkPrint($"------------------------- results: {description ?? string.Empty} --------------------------------"); + if (results != null) + { + Beaprint.LinkPrint(string.Join("\n", results ?? Enumerable.Empty())); + } + Beaprint.LinkPrint($"------------------------- results: {description ?? string.Empty} --------------------------------"); + Beaprint.LinkPrint("\n\n\n\n"); + } + + public static List FindFiles(string path, string patterns) + { + List result = new List(); + + 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 color) { try { + if (!Directory.Exists(path)) + { + return; + } + // search every pattern in this directory's files foreach (string pattern in patterns.Split(';')) { - Beaprint.AnsiPrint(" "+String.Join("\n ", Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly).Where(filepath => !filepath.Contains(".dll"))), color); + Beaprint.AnsiPrint(" " + String.Join("\n ", Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly).Where(filepath => !filepath.Contains(".dll"))), color); } if (!Program.search_fast) @@ -641,13 +702,37 @@ namespace winPEAS foreach (string directory in Directory.GetDirectories(path)) { if (!directory.Contains("AppData")) - FindFiles(directory, patterns, color); + FindFiles_old_implementation(directory, patterns, color); } } catch (UnauthorizedAccessException) { } catch (PathTooLongException) { } + catch (DirectoryNotFoundException) { } } + public static void FindFiles_fileSearcher(string path, string patterns, Dictionary color, HashSet 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 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 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 excludedDirs = new HashSet() { "AppData" }; + MeasureMethod(() => FindFiles_fileSearcher(path, patterns, color, excludedDirs), "new implementation"); + Beaprint.LinkPrint($"------------------------- results: new implementation --------------------------------"); + } ////////////////////// //////// MISC //////// diff --git a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj index 3aa6459..6767e0d 100755 --- a/winPEAS/winPEASexe/winPEAS/winPEAS.csproj +++ b/winPEAS/winPEASexe/winPEAS/winPEAS.csproj @@ -87,6 +87,9 @@ MinimumRecommendedRules.ruleset false + + winPEAS.Program + @@ -104,6 +107,7 @@ + @@ -173,5 +177,6 @@ + \ No newline at end of file