From 3188c6e922cab933c724ebaa381215fccddf831d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 31 Oct 2024 23:08:05 -0400 Subject: [PATCH] Further reduce awkward framework gating --- BinaryObjectScanner/CheckDictionary.cs | 19 ++- BinaryObjectScanner/EnumerableExtensions.cs | 27 +++++ BinaryObjectScanner/FileType/Executable.cs | 128 ++------------------ BinaryObjectScanner/Handler.cs | 10 +- BinaryObjectScanner/Scanner.cs | 80 +++--------- 5 files changed, 72 insertions(+), 192 deletions(-) create mode 100644 BinaryObjectScanner/EnumerableExtensions.cs diff --git a/BinaryObjectScanner/CheckDictionary.cs b/BinaryObjectScanner/CheckDictionary.cs index de64a049..1093172b 100644 --- a/BinaryObjectScanner/CheckDictionary.cs +++ b/BinaryObjectScanner/CheckDictionary.cs @@ -4,8 +4,23 @@ namespace BinaryObjectScanner /// Represents a mapping from checker to detected protection /// #if NET20 || NET35 - public class CheckDictionary : System.Collections.Generic.Dictionary where T : notnull { } + public class CheckDictionary : System.Collections.Generic.Dictionary where T : notnull #else - public class CheckDictionary : System.Collections.Concurrent.ConcurrentDictionary where T : notnull { } + public class CheckDictionary : System.Collections.Concurrent.ConcurrentDictionary where T : notnull #endif + { + /// + /// Handles the proper Add implementation + public void Append(T key, string? value) + { + if (value == null) + return; + +#if NET20 || NET35 + this[key] = value; +#else + TryAdd(key, value); +#endif + } + } } \ No newline at end of file diff --git a/BinaryObjectScanner/EnumerableExtensions.cs b/BinaryObjectScanner/EnumerableExtensions.cs new file mode 100644 index 00000000..5eb63948 --- /dev/null +++ b/BinaryObjectScanner/EnumerableExtensions.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace BinaryObjectScanner +{ + internal static class EnumerableExtensions + { + /// + /// Wrap iterating through an enumerable with an action + /// + /// + /// .NET Frameworks 2.0 and 3.5 process in series. + /// .NET Frameworks 4.0 onward process in parallel. + /// + public static void IterateWithAction(this IEnumerable source, Action action) + { +#if NET20 || NET35 + foreach (var item in source) + { + action(item); + } +#else + System.Threading.Tasks.Parallel.ForEach(source, action); +#endif + } + } +} \ No newline at end of file diff --git a/BinaryObjectScanner/FileType/Executable.cs b/BinaryObjectScanner/FileType/Executable.cs index e761cf8a..70c8980b 100644 --- a/BinaryObjectScanner/FileType/Executable.cs +++ b/BinaryObjectScanner/FileType/Executable.cs @@ -3,9 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -#if NET40_OR_GREATER || NETCOREAPP -using System.Threading.Tasks; -#endif using BinaryObjectScanner.Interfaces; using SabreTools.IO.Extensions; using SabreTools.Serialization.Wrappers; @@ -216,44 +213,23 @@ namespace BinaryObjectScanner.FileType var protections = new CheckDictionary(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in ContentCheckClasses) -#else - Parallel.ForEach(ContentCheckClasses, checkClass => -#endif + ContentCheckClasses.IterateWithAction(checkClass => { // Get the protection for the class, if possible var protection = checkClass.CheckContents(file!, fileContent, includeDebug); if (string.IsNullOrEmpty(protection)) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on game engines if (CheckIfGameEngine(checkClass) && !IncludeGameEngines) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on packers if (CheckIfPacker(checkClass) && !IncludePackers) -#if NET20 || NET35 - continue; -#else return; -#endif -#if NET20 || NET35 - protections[checkClass] = protection!; - } -#else - protections.TryAdd(checkClass, protection!); + protections.Append(checkClass, protection); }); -#endif return protections; } @@ -271,44 +247,23 @@ namespace BinaryObjectScanner.FileType var protections = new CheckDictionary(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in LinearExecutableCheckClasses) -#else - Parallel.ForEach(LinearExecutableCheckClasses, checkClass => -#endif + LinearExecutableCheckClasses.IterateWithAction(checkClass => { // Get the protection for the class, if possible var protection = checkClass.CheckLinearExecutable(file, lex, includeDebug); if (string.IsNullOrEmpty(protection)) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on game engines if (CheckIfGameEngine(checkClass) && !IncludeGameEngines) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on packers if (CheckIfPacker(checkClass) && !IncludePackers) -#if NET20 || NET35 - continue; -#else return; -#endif -#if NET20 || NET35 - protections[checkClass] = protection!; - } -#else - protections.TryAdd(checkClass, protection!); + protections.Append(checkClass, protection); }); -#endif return protections; } @@ -326,44 +281,23 @@ namespace BinaryObjectScanner.FileType var protections = new CheckDictionary(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in MSDOSExecutableCheckClasses) -#else - Parallel.ForEach(MSDOSExecutableCheckClasses, checkClass => -#endif + MSDOSExecutableCheckClasses.IterateWithAction(checkClass => { // Get the protection for the class, if possible var protection = checkClass.CheckMSDOSExecutable(file, mz, includeDebug); if (string.IsNullOrEmpty(protection)) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on game engines if (CheckIfGameEngine(checkClass) && !IncludeGameEngines) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on packers if (CheckIfPacker(checkClass) && !IncludePackers) -#if NET20 || NET35 - continue; -#else return; -#endif -#if NET20 || NET35 - protections[checkClass] = protection!; - } -#else - protections.TryAdd(checkClass, protection!); + protections.Append(checkClass, protection); }); -#endif return protections; } @@ -381,44 +315,23 @@ namespace BinaryObjectScanner.FileType var protections = new CheckDictionary(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in NewExecutableCheckClasses) -#else - Parallel.ForEach(NewExecutableCheckClasses, checkClass => -#endif + NewExecutableCheckClasses.IterateWithAction(checkClass => { // Get the protection for the class, if possible var protection = checkClass.CheckNewExecutable(file, nex, includeDebug); if (string.IsNullOrEmpty(protection)) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on game engines if (CheckIfGameEngine(checkClass) && !IncludeGameEngines) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on packers if (CheckIfPacker(checkClass) && !IncludePackers) -#if NET20 || NET35 - continue; -#else return; -#endif -#if NET20 || NET35 - protections[checkClass] = protection!; - } -#else - protections.TryAdd(checkClass, protection!); + protections.Append(checkClass, protection); }); -#endif return protections; } @@ -436,44 +349,23 @@ namespace BinaryObjectScanner.FileType var protections = new CheckDictionary(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in PortableExecutableCheckClasses) -#else - Parallel.ForEach(PortableExecutableCheckClasses, checkClass => -#endif + PortableExecutableCheckClasses.IterateWithAction(checkClass => { // Get the protection for the class, if possible var protection = checkClass.CheckPortableExecutable(file, pex, includeDebug); if (string.IsNullOrEmpty(protection)) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on game engines if (CheckIfGameEngine(checkClass) && !IncludeGameEngines) -#if NET20 || NET35 - continue; -#else return; -#endif // If we are filtering on packers if (CheckIfPacker(checkClass) && !IncludePackers) -#if NET20 || NET35 - continue; -#else return; -#endif -#if NET20 || NET35 - protections[checkClass] = protection!; - } -#else - protections.TryAdd(checkClass, protection!); + protections.Append(checkClass, protection); }); -#endif return protections; } diff --git a/BinaryObjectScanner/Handler.cs b/BinaryObjectScanner/Handler.cs index d89826fb..51cd6d55 100644 --- a/BinaryObjectScanner/Handler.cs +++ b/BinaryObjectScanner/Handler.cs @@ -53,20 +53,12 @@ namespace BinaryObjectScanner files = files?.Select(f => f.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))?.ToList(); // Iterate through all checks -#if NET20 || NET35 - foreach (var checkClass in PathCheckClasses) -#else - Parallel.ForEach(PathCheckClasses, checkClass => -#endif + PathCheckClasses.IterateWithAction(checkClass => { var subProtections = checkClass?.PerformCheck(path, files); if (subProtections != null) protections.Append(path, subProtections); -#if NET20 || NET35 - } -#else }); -#endif return protections; } diff --git a/BinaryObjectScanner/Scanner.cs b/BinaryObjectScanner/Scanner.cs index 9cfcd6d1..f591f593 100644 --- a/BinaryObjectScanner/Scanner.cs +++ b/BinaryObjectScanner/Scanner.cs @@ -2,12 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -#if NET462_OR_GREATER || NETCOREAPP -using System.Text; -#endif -#if NET40_OR_GREATER || NETCOREAPP -using System.Threading.Tasks; -#endif using BinaryObjectScanner.FileType; using BinaryObjectScanner.Interfaces; using SabreTools.IO.Extensions; @@ -76,7 +70,7 @@ namespace BinaryObjectScanner #if NET462_OR_GREATER || NETCOREAPP // Register the codepages - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); #endif } @@ -466,30 +460,20 @@ namespace BinaryObjectScanner var protections = new ProtectionDictionary(); // If we have any extractable packers - var extractables = classes.Where(c => c is IExtractableMSDOSExecutable).Select(c => c as IExtractableMSDOSExecutable); -#if NET20 || NET35 - foreach (var extractable in extractables) -#else - Parallel.ForEach(extractables, extractable => -#endif + var extractables = classes + .Where(c => c is IExtractableMSDOSExecutable) + .Select(c => c as IExtractableMSDOSExecutable); + extractables.IterateWithAction(extractable => { // If we have an invalid extractable somehow if (extractable == null) -#if NET20 || NET35 - continue; -#else return; -#endif // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, mz, this); if (extractedProtections != null) protections.Append(extractedProtections); -#if NET20 || NET35 - } -#else }); -#endif return protections; } @@ -511,30 +495,20 @@ namespace BinaryObjectScanner var protections = new ProtectionDictionary(); // If we have any extractable packers - var extractables = classes.Where(c => c is IExtractableLinearExecutable).Select(c => c as IExtractableLinearExecutable); -#if NET20 || NET35 - foreach (var extractable in extractables) -#else - Parallel.ForEach(extractables, extractable => -#endif + var extractables = classes + .Where(c => c is IExtractableLinearExecutable) + .Select(c => c as IExtractableLinearExecutable); + extractables.IterateWithAction(extractable => { // If we have an invalid extractable somehow if (extractable == null) -#if NET20 || NET35 - continue; -#else return; -#endif // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, lex, this); if (extractedProtections != null) protections.Append(extractedProtections); -#if NET20 || NET35 - } -#else }); -#endif return protections; } @@ -556,30 +530,20 @@ namespace BinaryObjectScanner var protections = new ProtectionDictionary(); // If we have any extractable packers - var extractables = classes.Where(c => c is IExtractableNewExecutable).Select(c => c as IExtractableNewExecutable); -#if NET20 || NET35 - foreach (var extractable in extractables) -#else - Parallel.ForEach(extractables, extractable => -#endif + var extractables = classes + .Where(c => c is IExtractableNewExecutable) + .Select(c => c as IExtractableNewExecutable); + extractables.IterateWithAction(extractable => { // If we have an invalid extractable somehow if (extractable == null) -#if NET20 || NET35 - continue; -#else return; -#endif // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, nex, this); if (extractedProtections != null) protections.Append(extractedProtections); -#if NET20 || NET35 - } -#else }); -#endif return protections; } @@ -601,30 +565,20 @@ namespace BinaryObjectScanner var protections = new ProtectionDictionary(); // If we have any extractable packers - var extractables = classes.Where(c => c is IExtractablePortableExecutable).Select(c => c as IExtractablePortableExecutable); -#if NET20 || NET35 - foreach (var extractable in extractables) -#else - Parallel.ForEach(extractables, extractable => -#endif + var extractables = classes + .Where(c => c is IExtractablePortableExecutable) + .Select(c => c as IExtractablePortableExecutable); + extractables.IterateWithAction(extractable => { // If we have an invalid extractable somehow if (extractable == null) -#if NET20 || NET35 - continue; -#else return; -#endif // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, pex, this); if (extractedProtections != null) protections.Append(extractedProtections); -#if NET20 || NET35 - } -#else }); -#endif return protections; }