From 683cfb6306f072e1093a50e6540548fdf9cf3f81 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 31 Oct 2024 21:10:06 -0400 Subject: [PATCH] Start using ProtectionDictionary --- BinaryObjectScanner/Handler.cs | 65 ++--- BinaryObjectScanner/Interfaces/IPathCheck.cs | 2 +- BinaryObjectScanner/ProtectionDictionary.cs | 12 +- BinaryObjectScanner/Scanner.cs | 181 ++++---------- BinaryObjectScanner/Utilities/Dictionary.cs | 238 ------------------- Test/Protector.cs | 6 +- 6 files changed, 78 insertions(+), 426 deletions(-) delete mode 100644 BinaryObjectScanner/Utilities/Dictionary.cs diff --git a/BinaryObjectScanner/Handler.cs b/BinaryObjectScanner/Handler.cs index ba76668d..a4d8fc38 100644 --- a/BinaryObjectScanner/Handler.cs +++ b/BinaryObjectScanner/Handler.cs @@ -10,7 +10,6 @@ using BinaryObjectScanner.Interfaces; using BinaryObjectScanner.Utilities; using SabreTools.Serialization.Wrappers; -using static BinaryObjectScanner.Utilities.Dictionary; namespace BinaryObjectScanner { @@ -49,18 +48,10 @@ public static IEnumerable PathCheckClasses /// Path of the file or directory to check /// Scanner object to use for options and scanning /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary> HandlePathChecks(string path, IEnumerable? files) -#else - public static ConcurrentDictionary> HandlePathChecks(string path, IEnumerable? files) -#endif + public static ProtectionDictionary HandlePathChecks(string path, IEnumerable? files) { // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // Preprocess the list of files files = files?.Select(f => f.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))?.ToList(); @@ -74,7 +65,7 @@ public static ConcurrentDictionary> HandlePathCh { var subProtections = checkClass?.PerformCheck(path, files); if (subProtections != null) - AppendToDictionary(protections, path, subProtections); + protections.Append(path, subProtections); #if NET20 || NET35 } #else @@ -114,11 +105,7 @@ public static ConcurrentDictionary> HandlePathCh /// Stream to scan the contents of /// Scanner object to use on extractable contents /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner) -#else - public static ConcurrentDictionary>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner) -#endif + public static ProtectionDictionary? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner) { // If the extractable file itself fails try @@ -142,8 +129,8 @@ public static ConcurrentDictionary> HandlePathCh } // Prepare the returned protections - StripFromKeys(subProtections, tempPath); - PrependToKeys(subProtections, fileName); + subProtections.StripFromKeys(tempPath); + subProtections.PrependToKeys(fileName); return subProtections; } catch (Exception ex) @@ -162,11 +149,7 @@ public static ConcurrentDictionary> HandlePathCh /// MSDOS to scan the contents of /// Scanner object to use on extractable contents /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner) -#else - public static ConcurrentDictionary>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner) -#endif + public static ProtectionDictionary? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner) { // If the extractable file itself fails try @@ -190,8 +173,8 @@ public static ConcurrentDictionary> HandlePathCh } // Prepare the returned protections - StripFromKeys(subProtections, tempPath); - PrependToKeys(subProtections, fileName); + subProtections.StripFromKeys(tempPath); + subProtections.PrependToKeys(fileName); return subProtections; } catch (Exception ex) @@ -210,11 +193,7 @@ public static ConcurrentDictionary> HandlePathCh /// LinearExecutable to scan the contents of /// Scanner object to use on extractable contents /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner) -#else - public static ConcurrentDictionary>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner) -#endif + public static ProtectionDictionary? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner) { // If the extractable file itself fails try @@ -238,8 +217,8 @@ public static ConcurrentDictionary> HandlePathCh } // Prepare the returned protections - StripFromKeys(subProtections, tempPath); - PrependToKeys(subProtections, fileName); + subProtections.StripFromKeys(tempPath); + subProtections.PrependToKeys(fileName); return subProtections; } catch (Exception ex) @@ -258,11 +237,7 @@ public static ConcurrentDictionary> HandlePathCh /// NewExecutable to scan the contents of /// Scanner object to use on extractable contents /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner) -#else - public static ConcurrentDictionary>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner) -#endif + public static ProtectionDictionary? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner) { // If the extractable file itself fails try @@ -286,8 +261,8 @@ public static ConcurrentDictionary> HandlePathCh } // Prepare the returned protections - StripFromKeys(subProtections, tempPath); - PrependToKeys(subProtections, fileName); + subProtections.StripFromKeys(tempPath); + subProtections.PrependToKeys(fileName); return subProtections; } catch (Exception ex) @@ -306,11 +281,7 @@ public static ConcurrentDictionary> HandlePathCh /// PortableExecutable to scan the contents of /// Scanner object to use on extractable contents /// Set of protections in file, null on error -#if NET20 || NET35 - public static Dictionary>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner) -#else - public static ConcurrentDictionary>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner) -#endif + public static ProtectionDictionary? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner) { // If the extractable file itself fails try @@ -334,8 +305,8 @@ public static ConcurrentDictionary> HandlePathCh } // Prepare the returned protections - StripFromKeys(subProtections, tempPath); - PrependToKeys(subProtections, fileName); + subProtections.StripFromKeys(tempPath); + subProtections.PrependToKeys(fileName); return subProtections; } catch (Exception ex) diff --git a/BinaryObjectScanner/Interfaces/IPathCheck.cs b/BinaryObjectScanner/Interfaces/IPathCheck.cs index 4d081966..dbda4de7 100644 --- a/BinaryObjectScanner/Interfaces/IPathCheck.cs +++ b/BinaryObjectScanner/Interfaces/IPathCheck.cs @@ -20,7 +20,7 @@ public interface IPathCheck /// Enumerable of strings representing files in a directory /// This can do some limited content checking as well, but it's suggested to use a content check instead, if possible #if NET20 || NET35 - Queue CheckDirectoryPath(string path, IEnumerable? files); + List CheckDirectoryPath(string path, IEnumerable? files); #else ConcurrentQueue CheckDirectoryPath(string path, IEnumerable? files); #endif diff --git a/BinaryObjectScanner/ProtectionDictionary.cs b/BinaryObjectScanner/ProtectionDictionary.cs index e9f11fbf..550a6f87 100644 --- a/BinaryObjectScanner/ProtectionDictionary.cs +++ b/BinaryObjectScanner/ProtectionDictionary.cs @@ -48,8 +48,8 @@ public void Append(string key, string[] values) // Add the key if needed and then append the lists #if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); + if (!ContainsKey(key)) + this[key] = new Queue(); #else TryAdd(key, new ConcurrentQueue()); #endif @@ -72,8 +72,8 @@ public void Append(string key, ConcurrentQueue values) // Add the key if needed and then append the lists #if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); + if (!ContainsKey(key)) + this[key] = new Queue(); #else TryAdd(key, new ConcurrentQueue()); #endif @@ -94,8 +94,8 @@ public void Append(ProtectionDictionary? addition) foreach (string key in addition.Keys) { #if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); + if (!ContainsKey(key)) + this[key] = new Queue(); #else TryAdd(key, new ConcurrentQueue()); #endif diff --git a/BinaryObjectScanner/Scanner.cs b/BinaryObjectScanner/Scanner.cs index b4019541..e35af71d 100644 --- a/BinaryObjectScanner/Scanner.cs +++ b/BinaryObjectScanner/Scanner.cs @@ -17,7 +17,6 @@ using SabreTools.IO.Extensions; using SabreTools.Serialization.Interfaces; using SabreTools.Serialization.Wrappers; -using static BinaryObjectScanner.Utilities.Dictionary; namespace BinaryObjectScanner { @@ -92,24 +91,14 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// /// Path to scan /// Dictionary of list of strings representing the found protections -#if NET20 || NET35 - public Dictionary>? GetProtections(string path) -#else - public ConcurrentDictionary>? GetProtections(string path) -#endif - { - return GetProtections([path]); - } + public ProtectionDictionary? GetProtections(string path) + => GetProtections([path]); /// /// Scan the list of paths and get all found protections /// /// Dictionary of list of strings representing the found protections -#if NET20 || NET35 - public Dictionary>? GetProtections(List? paths) -#else - public ConcurrentDictionary>? GetProtections(List? paths) -#endif + public ProtectionDictionary? GetProtections(List? paths) { // If we have no paths, we can't scan if (paths == null || !paths.Any()) @@ -126,11 +115,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool string tempFilePathWithGuid = Path.Combine(tempFilePath, Guid.NewGuid().ToString()); // Loop through each path and get the returned values -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); foreach (string path in paths) { // Directories scan each internal file individually @@ -143,7 +128,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool if (ScanPaths) { var directoryPathProtections = Handler.HandlePathChecks(path, files); - AppendToDictionary(protections, directoryPathProtections); + protections.Append(directoryPathProtections); } // Scan each file in directory separately @@ -164,25 +149,14 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool if (ScanPaths) { var filePathProtections = Handler.HandlePathChecks(file, files: null); - AppendToDictionary(protections, filePathProtections); + if (filePathProtections != null && filePathProtections.Any()) + protections.Append(filePathProtections); } // Scan for content-detectable protections var fileProtections = GetInternalProtections(file); if (fileProtections != null && fileProtections.Any()) - { - foreach (string key in fileProtections.Keys) - { - if (!protections.ContainsKey(key)) -#if NET20 || NET35 - protections[key] = new Queue(); -#else - protections[key] = new ConcurrentQueue(); -#endif - - protections[key].AddRange(fileProtections[key]); - } - } + protections.Append(fileProtections); // Checkpoint protections.TryGetValue(file, out var fullProtectionList); @@ -206,25 +180,14 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool if (ScanPaths) { var filePathProtections = Handler.HandlePathChecks(path, files: null); - AppendToDictionary(protections, filePathProtections); + if (filePathProtections != null && filePathProtections.Any()) + protections.Append(filePathProtections); } // Scan for content-detectable protections var fileProtections = GetInternalProtections(path); if (fileProtections != null && fileProtections.Any()) - { - foreach (string key in fileProtections.Keys) - { - if (!protections.ContainsKey(key)) -#if NET20 || NET35 - protections[key] = new Queue(); -#else - protections[key] = new ConcurrentQueue(); -#endif - - protections[key].AddRange(fileProtections[key]); - } - } + protections.Append(fileProtections); // Checkpoint protections.TryGetValue(path, out var fullProtectionList); @@ -241,7 +204,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool } // Clear out any empty keys - ClearEmptyKeys(protections); + protections.ClearEmptyKeys(); // If we're in debug, output the elasped time to console if (IncludeDebug) @@ -255,11 +218,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// /// Path to the file to scan /// Dictionary of list of strings representing the found protections -#if NET20 || NET35 - private Dictionary>? GetInternalProtections(string file) -#else - private ConcurrentDictionary>? GetInternalProtections(string file) -#endif + private ProtectionDictionary? GetInternalProtections(string file) { // Quick sanity check before continuing if (!File.Exists(file)) @@ -275,13 +234,9 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool { if (IncludeDebug) Console.WriteLine(ex); -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif - AppendToDictionary(protections, file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]"); - ClearEmptyKeys(protections); + var protections = new ProtectionDictionary(); + protections.Append(file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]"); + protections.ClearEmptyKeys(); return protections; } } @@ -292,22 +247,14 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// Name of the source file of the stream, for tracking /// Stream to scan the contents of /// Dictionary of list of strings representing the found protections -#if NET20 || NET35 - private Dictionary>? GetInternalProtections(string fileName, Stream stream) -#else - private ConcurrentDictionary>? GetInternalProtections(string fileName, Stream stream) -#endif + private ProtectionDictionary? GetInternalProtections(string fileName, Stream stream) { // Quick sanity check before continuing if (stream == null || !stream.CanRead || !stream.CanSeek) return null; // Initialize the protections found -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // Get the extension for certain checks string extension = Path.GetExtension(fileName).ToLower().TrimStart('.'); @@ -349,7 +296,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool executable.IncludePackers = ScanPackers; var subProtections = ProcessExecutable(executable, fileName, stream); if (subProtections != null) - AppendToDictionary(protections, subProtections); + protections.Append(subProtections); } // Otherwise, use the default implementation @@ -357,7 +304,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool { var subProtections = Handler.HandleDetectable(detectable, fileName, stream, IncludeDebug); if (subProtections != null) - AppendToDictionary(protections, fileName, subProtections); + protections.Append(fileName, subProtections); } var subProtection = detectable.Detect(stream, fileName, IncludeDebug); @@ -367,11 +314,11 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool if (subProtection.Contains(';')) { var splitProtections = subProtection!.Split(';'); - AppendToDictionary(protections, fileName, splitProtections); + protections.Append(fileName, splitProtections); } else { - AppendToDictionary(protections, fileName, subProtection!); + protections.Append(fileName, subProtection!); } } } @@ -388,7 +335,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool { var subProtections = Handler.HandleExtractable(extractable, fileName, stream, this); if (subProtections != null) - AppendToDictionary(protections, subProtections); + protections.Append(subProtections); } #endregion @@ -396,11 +343,11 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool catch (Exception ex) { if (IncludeDebug) Console.WriteLine(ex); - AppendToDictionary(protections, fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]"); + protections.Append(fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]"); } // Clear out any empty keys - ClearEmptyKeys(protections); + protections.ClearEmptyKeys(); return protections; } @@ -419,11 +366,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// Ideally, we wouldn't need to circumvent the proper handling of file types just for Executable, /// but due to the complexity of scanning, this is not currently possible. /// -#if NET20 || NET35 - private Dictionary>? ProcessExecutable(Executable executable, string fileName, Stream stream) -#else - private ConcurrentDictionary>? ProcessExecutable(Executable executable, string fileName, Stream stream) -#endif + private ProtectionDictionary? ProcessExecutable(Executable executable, string fileName, Stream stream) { // Try to create a wrapper for the proper executable type IWrapper? wrapper; @@ -440,18 +383,14 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool } // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // Only use generic content checks if we're in debug mode if (IncludeDebug) { var subProtections = executable.RunContentChecks(fileName, stream, IncludeDebug); if (subProtections != null) - AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + protections.Append(fileName, subProtections.Values.ToArray()); } if (wrapper is MSDOS mz) @@ -461,12 +400,12 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return protections; // Append the returned values - AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + protections.Append(fileName, subProtections.Values.ToArray()); // If we have any extractable packers var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, mz); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); } else if (wrapper is LinearExecutable lex) { @@ -475,12 +414,12 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return protections; // Append the returned values - AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + protections.Append(fileName, subProtections.Values.ToArray()); // If we have any extractable packers var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, lex); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); } else if (wrapper is NewExecutable nex) { @@ -489,12 +428,12 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return protections; // Append the returned values - AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + protections.Append(fileName, subProtections.Values.ToArray()); // If we have any extractable packers var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, nex); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); } else if (wrapper is PortableExecutable pex) { @@ -503,12 +442,12 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return protections; // Append the returned values - AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + protections.Append(fileName, subProtections.Values.ToArray()); // If we have any extractable packers var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, pex); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); } return protections; @@ -522,9 +461,9 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// MSDOS to scan the contents of /// Set of protections found from extraction, null on error #if NET20 || NET35 - private Dictionary>? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, MSDOS mz) + private ProtectionDictionary? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, MSDOS mz) #else - private ConcurrentDictionary>? HandleExtractableProtections(IEnumerable? classes, string fileName, MSDOS mz) + private ProtectionDictionary? HandleExtractableProtections(IEnumerable? classes, string fileName, MSDOS mz) #endif { // If we have an invalid set of classes @@ -532,11 +471,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return null; // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // If we have any extractable packers var extractables = classes.Where(c => c is IExtractableMSDOSExecutable).Select(c => c as IExtractableMSDOSExecutable); @@ -557,7 +492,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, mz, this); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); #if NET20 || NET35 } #else @@ -575,9 +510,9 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// LinearExecutable to scan the contents of /// Set of protections found from extraction, null on error #if NET20 || NET35 - private Dictionary>? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, LinearExecutable lex) + private ProtectionDictionary? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, LinearExecutable lex) #else - private ConcurrentDictionary>? HandleExtractableProtections(IEnumerable? classes, string fileName, LinearExecutable lex) + private ProtectionDictionary? HandleExtractableProtections(IEnumerable? classes, string fileName, LinearExecutable lex) #endif { // If we have an invalid set of classes @@ -585,11 +520,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return null; // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // If we have any extractable packers var extractables = classes.Where(c => c is IExtractableLinearExecutable).Select(c => c as IExtractableLinearExecutable); @@ -610,7 +541,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, lex, this); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); #if NET20 || NET35 } #else @@ -628,9 +559,9 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// NewExecutable to scan the contents of /// Set of protections found from extraction, null on error #if NET20 || NET35 - private Dictionary>? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, NewExecutable nex) + private ProtectionDictionary? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, NewExecutable nex) #else - private ConcurrentDictionary>? HandleExtractableProtections(IEnumerable? classes, string fileName, NewExecutable nex) + private ProtectionDictionary? HandleExtractableProtections(IEnumerable? classes, string fileName, NewExecutable nex) #endif { // If we have an invalid set of classes @@ -638,11 +569,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return null; // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // If we have any extractable packers var extractables = classes.Where(c => c is IExtractableNewExecutable).Select(c => c as IExtractableNewExecutable); @@ -663,7 +590,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, nex, this); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); #if NET20 || NET35 } #else @@ -681,9 +608,9 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool /// PortableExecutable to scan the contents of /// Set of protections found from extraction, null on error #if NET20 || NET35 - private Dictionary>? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, PortableExecutable pex) + private ProtectionDictionary? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, PortableExecutable pex) #else - private ConcurrentDictionary>? HandleExtractableProtections(IEnumerable? classes, string fileName, PortableExecutable pex) + private ProtectionDictionary? HandleExtractableProtections(IEnumerable? classes, string fileName, PortableExecutable pex) #endif { // If we have an invalid set of classes @@ -691,11 +618,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool return null; // Create the output dictionary -#if NET20 || NET35 - var protections = new Dictionary>(); -#else - var protections = new ConcurrentDictionary>(); -#endif + var protections = new ProtectionDictionary(); // If we have any extractable packers var extractables = classes.Where(c => c is IExtractablePortableExecutable).Select(c => c as IExtractablePortableExecutable); @@ -716,7 +639,7 @@ public Scanner(bool scanArchives, bool scanContents, bool scanGameEngines, bool // Get the protection for the class, if possible var extractedProtections = Handler.HandleExtractable(extractable, fileName, pex, this); if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); + protections.Append(extractedProtections); #if NET20 || NET35 } #else diff --git a/BinaryObjectScanner/Utilities/Dictionary.cs b/BinaryObjectScanner/Utilities/Dictionary.cs deleted file mode 100644 index 22513749..00000000 --- a/BinaryObjectScanner/Utilities/Dictionary.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -#if NET20 || NET35 -using System.Collections.Generic; -#else -using System.Collections.Concurrent; -#endif -using System.IO; -using System.Linq; - -namespace BinaryObjectScanner.Utilities -{ - /// - /// Dictionary manipulation methods - /// - public static class Dictionary - { - /// - /// Append one result to a results dictionary - /// - /// Dictionary to append to - /// Key to add information to - /// String value to add -#if NET20 || NET35 - public static void AppendToDictionary(Dictionary> original, string key, string value) -#else - public static void AppendToDictionary(ConcurrentDictionary> original, string key, string value) -#endif - { - // If the value is empty, don't add it - if (string.IsNullOrEmpty(value)) - return; - -#if NET20 || NET35 - var values = new Queue(); -#else - var values = new ConcurrentQueue(); -#endif - values.Enqueue(value); - AppendToDictionary(original, key, values); - } - - /// - /// Append one set of results to a results dictionary - /// - /// Dictionary to append to - /// Key to add information to - /// String value array to add -#if NET20 || NET35 - public static void AppendToDictionary(Dictionary> original, string key, string[] values) -#else - public static void AppendToDictionary(ConcurrentDictionary> original, string key, string[] values) -#endif - { - // If the dictionary is null, just return - if (original == null) - return; - - // Use a placeholder value if the key is null - key ??= "NO FILENAME"; - - // Add the key if needed and then append the lists -#if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); -#else - original.TryAdd(key, new ConcurrentQueue()); -#endif - original[key].AddRange(values); - } - - /// - /// Append one set of results to a results dictionary - /// - /// Dictionary to append to - /// Key to add information to - /// String value to add -#if NET20 || NET35 - public static void AppendToDictionary(Dictionary> original, string key, Queue values) -#else - public static void AppendToDictionary(ConcurrentDictionary> original, string key, ConcurrentQueue values) -#endif - { - // If the dictionary is null, just return - if (original == null) - return; - - // Use a placeholder value if the key is null - key ??= "NO FILENAME"; - - // Add the key if needed and then append the lists -#if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); -#else - original.TryAdd(key, new ConcurrentQueue()); -#endif - original[key].AddRange(values); - } - - /// - /// Append one results dictionary to another - /// - /// Dictionary to append to - /// Dictionary to pull from -#if NET20 || NET35 - public static void AppendToDictionary(Dictionary> original, Dictionary> addition) -#else - public static void AppendToDictionary(ConcurrentDictionary> original, ConcurrentDictionary> addition) -#endif - { - // If either dictionary is missing, just return - if (original == null || addition == null) - return; - - // Loop through each of the addition keys and add accordingly - foreach (string key in addition.Keys) - { -#if NET20 || NET35 - if (!original.ContainsKey(key)) - original[key] = new Queue(); -#else - original.TryAdd(key, new ConcurrentQueue()); -#endif - original[key].AddRange(addition[key]); - } - } - - /// - /// Remove empty or null keys from a results dictionary - /// - /// Dictionary to clean -#if NET20 || NET35 - public static void ClearEmptyKeys(Dictionary> original) -#else - public static void ClearEmptyKeys(ConcurrentDictionary> original) -#endif - { - // If the dictionary is missing, we can't do anything - if (original == null) - return; - - // Get a list of all of the keys - var keys = original.Keys.ToList(); - - // Iterate and reset keys - for (int i = 0; i < keys.Count; i++) - { - // Get the current key - string key = keys[i]; - - // If the key is empty, remove it - if (original[key] == null || !original[key].Any()) -#if NET20 || NET35 - original.Remove(key); -#else - original.TryRemove(key, out _); -#endif - } - } - - /// - /// Prepend a parent path from dictionary keys, if possible - /// - /// Dictionary to strip values from - /// Path to strip from the keys -#if NET20 || NET35 - public static void PrependToKeys(Dictionary>? original, string pathToPrepend) -#else - public static void PrependToKeys(ConcurrentDictionary>? original, string pathToPrepend) -#endif - { - // If the dictionary is missing, we can't do anything - if (original == null) - return; - - // Use a placeholder value if the path is null - pathToPrepend = (pathToPrepend ?? "ARCHIVE").TrimEnd(Path.DirectorySeparatorChar); - - // Get a list of all of the keys - var keys = original.Keys.ToList(); - - // Iterate and reset keys - for (int i = 0; i < keys.Count; i++) - { - // Get the current key - string currentKey = keys[i]; - - // Otherwise, get the new key name and transfer over - string newKey = $"{pathToPrepend}{Path.DirectorySeparatorChar}{currentKey.Trim(Path.DirectorySeparatorChar)}"; - original[newKey] = original[currentKey]; -#if NET20 || NET35 - original.Remove(currentKey); -#else - original.TryRemove(currentKey, out _); -#endif - } - } - - /// - /// Strip a parent path from dictionary keys, if possible - /// - /// Dictionary to strip values from - /// Path to strip from the keys -#if NET20 || NET35 - public static void StripFromKeys(Dictionary>? original, string? pathToStrip) -#else - public static void StripFromKeys(ConcurrentDictionary>? original, string? pathToStrip) -#endif - { - // If either is missing, we can't do anything - if (original == null || string.IsNullOrEmpty(pathToStrip)) - return; - - // Get a list of all of the keys - var keys = original.Keys.ToList(); - - // Iterate and reset keys - for (int i = 0; i < keys.Count; i++) - { - // Get the current key - string currentKey = keys[i]; - - // If the key doesn't start with the path, don't touch it - if (!currentKey.StartsWith(pathToStrip, StringComparison.OrdinalIgnoreCase)) - continue; - - // Otherwise, get the new key name and transfer over - string newKey = currentKey.Substring(pathToStrip!.Length); - original[newKey] = original[currentKey]; -#if NET20 || NET35 - original.Remove(currentKey); -#else - original.TryRemove(currentKey, out _); -#endif - } - } - } -} diff --git a/Test/Protector.cs b/Test/Protector.cs index 7af02063..448cca51 100644 --- a/Test/Protector.cs +++ b/Test/Protector.cs @@ -43,11 +43,7 @@ public static void GetAndWriteProtections(Scanner scanner, string path) /// /// File or directory path /// Dictionary of protections found, if any -#if NET20 || NET35 - private static void WriteProtectionResultFile(string path, Dictionary>? protections) -#else - private static void WriteProtectionResultFile(string path, ConcurrentDictionary>? protections) -#endif + private static void WriteProtectionResultFile(string path, ProtectionDictionary? protections) { if (protections == null) {