From a85c6f40283c2b80b59254a2661aff562cebd263 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 15 Mar 2023 15:51:38 -0400 Subject: [PATCH] Rearrange Executable-related things --- .../BinaryObjectScanner.FileType.csproj | 2 + BinaryObjectScanner.FileType/Executable.cs | 322 +++++++++++++++++- BurnOutSharp/Handler.cs | 278 +++------------ BurnOutSharp/Scanner.cs | 87 ++++- BurnOutSharp/ScanningClasses.cs | 157 --------- 5 files changed, 437 insertions(+), 409 deletions(-) delete mode 100644 BurnOutSharp/ScanningClasses.cs diff --git a/BinaryObjectScanner.FileType/BinaryObjectScanner.FileType.csproj b/BinaryObjectScanner.FileType/BinaryObjectScanner.FileType.csproj index efd0cc69..12347ebb 100644 --- a/BinaryObjectScanner.FileType/BinaryObjectScanner.FileType.csproj +++ b/BinaryObjectScanner.FileType/BinaryObjectScanner.FileType.csproj @@ -24,6 +24,8 @@ + + diff --git a/BinaryObjectScanner.FileType/Executable.cs b/BinaryObjectScanner.FileType/Executable.cs index 9a891943..b4b52b50 100644 --- a/BinaryObjectScanner.FileType/Executable.cs +++ b/BinaryObjectScanner.FileType/Executable.cs @@ -1,6 +1,14 @@ using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; using BinaryObjectScanner.Interfaces; +using BinaryObjectScanner.Utilities; +using BinaryObjectScanner.Wrappers; namespace BinaryObjectScanner.FileType { @@ -8,11 +16,100 @@ namespace BinaryObjectScanner.FileType /// Executable or library /// /// - /// Due to the complexity of executables, all actual handling is offloaded to + /// Due to the complexity of executables, all extraction handling /// another class that is used by the scanner /// public class Executable : IDetectable, IExtractable { + #region Properties + + /// + /// Determines if packers are counted as detected protections or not + /// + public bool IncludePackers { get; set; } + + /// + /// Cache for all IContentCheck types + /// + public static IEnumerable ContentCheckClasses + { + get + { + if (contentCheckClasses == null) + contentCheckClasses = InitCheckClasses(); + + return contentCheckClasses; + } + } + + /// + /// Cache for all ILinearExecutableCheck types + /// + public static IEnumerable LinearExecutableCheckClasses + { + get + { + if (linearExecutableCheckClasses == null) + linearExecutableCheckClasses = InitCheckClasses(); + + return linearExecutableCheckClasses; + } + } + + /// + /// Cache for all INewExecutableCheck types + /// + public static IEnumerable NewExecutableCheckClasses + { + get + { + if (newExecutableCheckClasses == null) + newExecutableCheckClasses = InitCheckClasses(); + + return newExecutableCheckClasses; + } + } + + /// + /// Cache for all IPortableExecutableCheck types + /// + public static IEnumerable PortableExecutableCheckClasses + { + get + { + if (portableExecutableCheckClasses == null) + portableExecutableCheckClasses = InitCheckClasses(); + + return portableExecutableCheckClasses; + } + } + + #endregion + + #region Internal Instances + + /// + /// Cache for all IContentCheck types + /// + private static IEnumerable contentCheckClasses; + + /// + /// Cache for all ILinearExecutableCheck types + /// + private static IEnumerable linearExecutableCheckClasses; + + /// + /// Cache for all INewExecutableCheck types + /// + private static IEnumerable newExecutableCheckClasses; + + /// + /// Cache for all IPortableExecutableCheck types + /// + private static IEnumerable portableExecutableCheckClasses; + + #endregion + /// public string Detect(string file, bool includeDebug) { @@ -26,10 +123,48 @@ namespace BinaryObjectScanner.FileType } /// - /// This implementation should never be invoked public string Detect(Stream stream, string file, bool includeDebug) { - throw new InvalidOperationException(); + // Try to create a wrapper for the proper executable type + var wrapper = WrapperFactory.CreateExecutableWrapper(stream); + if (wrapper == null) + return null; + + // Create the internal queue + var protections = new ConcurrentQueue(); + + // Only use generic content checks if we're in debug mode + if (includeDebug) + { + var subProtections = RunContentChecks(file, stream, includeDebug); + if (subProtections != null) + protections.AddRange(subProtections.Values.ToArray()); + } + + if (wrapper is MSDOS) + { + // No-op until protection classes implmented + } + else if (wrapper is LinearExecutable lex) + { + var subProtections = RunLinearExecutableChecks(file, stream, lex, includeDebug); + if (subProtections != null) + protections.AddRange(subProtections.Values.ToArray()); + } + else if (wrapper is NewExecutable nex) + { + var subProtections = RunNewExecutableChecks(file, stream, nex, includeDebug); + if (subProtections != null) + protections.AddRange(subProtections.Values.ToArray()); + } + else if (wrapper is PortableExecutable pex) + { + var subProtections = RunPortableExecutableChecks(file, stream, pex, includeDebug); + if (subProtections != null) + protections.AddRange(subProtections.Values.ToArray()); + } + + return string.Join(";", protections); } /// @@ -50,5 +185,186 @@ namespace BinaryObjectScanner.FileType { throw new InvalidOperationException(); } + + #region Check Runners + + /// + /// Handle a single file based on all content check implementations + /// + /// Name of the source file of the stream, for tracking + /// Stream to scan the contents of + /// True to include debug data, false otherwise + /// Set of protections in file, null on error + public ConcurrentDictionary RunContentChecks(string file, Stream stream, bool includeDebug) + { + // If we have an invalid file + if (string.IsNullOrWhiteSpace(file)) + return null; + else if (!File.Exists(file)) + return null; + + // Read the file contents + byte[] fileContent = null; + try + { + using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true)) + { + fileContent = br.ReadBytes((int)stream.Length); + if (fileContent == null) + return null; + } + } + catch (Exception ex) + { + if (includeDebug) Console.WriteLine(ex); + return null; + } + + // Create the output dictionary + var protections = new ConcurrentDictionary(); + + // Iterate through all checks + Parallel.ForEach(ContentCheckClasses, checkClass => + { + // Get the protection for the class, if possible + string protection = checkClass.CheckContents(file, fileContent, includeDebug); + if (string.IsNullOrWhiteSpace(protection)) + return; + + // If we are filtering the output of the check + if (!CheckIfPacker(checkClass) || !IncludePackers) + return; + + protections.TryAdd(checkClass, protection); + }); + + return protections; + } + + /// + /// Handle a single file based on all linear executable check implementations + /// + /// Name of the source file of the executable, for tracking + /// Executable to scan + /// True to include debug data, false otherwise + /// Set of protections in file, null on error + public ConcurrentDictionary RunLinearExecutableChecks(string file, Stream stream, LinearExecutable lex, bool includeDebug) + { + // Create the output dictionary + var protections = new ConcurrentDictionary(); + + // Iterate through all checks + Parallel.ForEach(LinearExecutableCheckClasses, checkClass => + { + // Get the protection for the class, if possible + string protection = checkClass.CheckLinearExecutable(file, lex, includeDebug); + if (string.IsNullOrWhiteSpace(protection)) + return; + + // If we are filtering the output of the check + if (!CheckIfPacker(checkClass) || !IncludePackers) + return; + + protections.TryAdd(checkClass, protection); + }); + + return protections; + } + + /// + /// Handle a single file based on all new executable check implementations + /// + /// Name of the source file of the executable, for tracking + /// Executable to scan + /// True to include debug data, false otherwise + /// Set of protections in file, null on error + public ConcurrentDictionary RunNewExecutableChecks(string file, Stream stream, NewExecutable nex, bool includeDebug) + { + // Create the output dictionary + var protections = new ConcurrentDictionary(); + + // Iterate through all checks + Parallel.ForEach(NewExecutableCheckClasses, checkClass => + { + // Get the protection for the class, if possible + string protection = checkClass.CheckNewExecutable(file, nex, includeDebug); + if (string.IsNullOrWhiteSpace(protection)) + return; + + // If we are filtering the output of the check + if (!CheckIfPacker(checkClass) || !IncludePackers) + return; + + protections.TryAdd(checkClass, protection); + }); + + return protections; + } + + /// + /// Handle a single file based on all portable executable check implementations + /// + /// Name of the source file of the executable, for tracking + /// Executable to scan + /// True to include debug data, false otherwise + /// Set of protections in file, null on error + public ConcurrentDictionary RunPortableExecutableChecks(string file, Stream stream, PortableExecutable pex, bool includeDebug) + { + // Create the output dictionary + var protections = new ConcurrentDictionary(); + + // Iterate through all checks + Parallel.ForEach(PortableExecutableCheckClasses, checkClass => + { + // Get the protection for the class, if possible + string protection = checkClass.CheckPortableExecutable(file, pex, includeDebug); + if (string.IsNullOrWhiteSpace(protection)) + return; + + // If we are filtering the output of the check + if (!CheckIfPacker(checkClass) || !IncludePackers) + return; + + protections.TryAdd(checkClass, protection); + }); + + return protections; + } + + #endregion + + #region Initializers + + /// + /// Initialize all implementations of a type + /// + private static IEnumerable InitCheckClasses() + => InitCheckClasses(typeof(BinaryObjectScanner.Packer._DUMMY).Assembly) + .Concat(InitCheckClasses(typeof(BinaryObjectScanner.Protection._DUMMY).Assembly)); + + /// + /// Initialize all implementations of a type + /// + private static IEnumerable InitCheckClasses(Assembly assembly) + { + return assembly.GetTypes() + .Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null) + .Select(t => (T)Activator.CreateInstance(t)); + } + + #endregion + + #region Helpers + + /// + /// Check to see if an implementation is a packer using reflection + /// + /// Implementation that was last used to check + private static bool CheckIfPacker(object impl) + { + return impl.GetType().Namespace.ToLowerInvariant().Contains("packer"); + } + + #endregion } } diff --git a/BurnOutSharp/Handler.cs b/BurnOutSharp/Handler.cs index 2eaf22fb..4e9eae91 100644 --- a/BurnOutSharp/Handler.cs +++ b/BurnOutSharp/Handler.cs @@ -3,150 +3,45 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; +using System.Reflection; using System.Threading.Tasks; using BinaryObjectScanner.Interfaces; using BinaryObjectScanner.Utilities; -using BinaryObjectScanner.Wrappers; using static BinaryObjectScanner.Utilities.Dictionary; namespace BurnOutSharp { internal static class Handler { + #region Public Collections + + /// + /// Cache for all IPathCheck types + /// + public static IEnumerable PathCheckClasses + { + get + { + if (pathCheckClasses == null) + pathCheckClasses = InitCheckClasses(); + + return pathCheckClasses; + } + } + + #endregion + + #region Internal Instances + + /// + /// Cache for all IPathCheck types + /// + private static IEnumerable pathCheckClasses; + + #endregion + #region Multiple Implementation Wrappers - /// - /// Handle a single file based on all content check implementations - /// - /// Name of the source file of the stream, for tracking - /// Stream to scan the contents of - /// Scanner object to use for options and scanning - /// Set of protections in file, null on error - public static ConcurrentQueue HandleContentChecks(string fileName, Stream stream, Scanner scanner) - { - // If we have an invalid file - if (string.IsNullOrWhiteSpace(fileName)) - return null; - else if (!File.Exists(fileName)) - return null; - - // Read the file contents - byte[] fileContent = null; - try - { - using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true)) - { - fileContent = br.ReadBytes((int)stream.Length); - if (fileContent == null) - return null; - } - } - catch (Exception ex) - { - if (scanner.IncludeDebug) Console.WriteLine(ex); - return null; - } - - // Create the output queue - var protections = new ConcurrentQueue(); - - // Iterate through all checks - Parallel.ForEach(ScanningClasses.ContentCheckClasses, checkClass => - { - // Get the protection for the class, if possible - var subProtections = checkClass.PerformCheck(fileName, fileContent, scanner.IncludeDebug); - if (subProtections != null) - { - // If we are filtering the output of the check - if (!CheckIfPacker(checkClass) || !scanner.ScanPackers) - return; - - protections.AddRange(subProtections); - } - }); - - return protections; - } - - /// - /// Handle a single file based on all linear executable check implementations - /// - /// Name of the source file of the executable, for tracking - /// Executable to scan - /// Scanner object to use for options and scanning - /// Set of protections in file, null on error - public static ConcurrentDictionary> HandleLinearExecutableChecks(string fileName, Stream stream, LinearExecutable lex, Scanner scanner) - { - // Create the output dictionary - var protections = new ConcurrentDictionary>(); - - // Iterate through all checks - Parallel.ForEach(ScanningClasses.LinearExecutableCheckClasses, checkClass => - { - // Get the protection for the class, if possible - var subProtections = checkClass.PerformCheck(fileName, lex, scanner.IncludeDebug); - if (subProtections == null) - return; - - // If we are filtering the output of the check - if (!CheckIfPacker(checkClass) || !scanner.ScanPackers) - return; - - // Add all found protections to the output - AppendToDictionary(protections, fileName, subProtections); - - // If we have an extractable implementation - if (checkClass is IExtractable extractable) - { - var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner); - if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); - } - }); - - return protections; - } - - /// - /// Handle a single file based on all new executable check implementations - /// - /// Name of the source file of the executable, for tracking - /// Executable to scan - /// Scanner object to use for options and scanning - /// Set of protections in file, null on error - public static ConcurrentDictionary> HandleNewExecutableChecks(string fileName, Stream stream, NewExecutable nex, Scanner scanner) - { - // Create the output dictionary - var protections = new ConcurrentDictionary>(); - - // Iterate through all checks - Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, checkClass => - { - // Get the protection for the class, if possible - var subProtections = checkClass.PerformCheck(fileName, nex, scanner.IncludeDebug); - if (subProtections == null) - return; - - // If we are filtering the output of the check - if (!CheckIfPacker(checkClass) || !scanner.ScanPackers) - return; - - // Add all found protections to the output - AppendToDictionary(protections, fileName, subProtections); - - // If we have an extractable implementation - if (checkClass is IExtractable extractable) - { - var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner); - if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); - } - }); - - return protections; - } - /// /// Handle a single path based on all path check implementations /// @@ -162,7 +57,7 @@ namespace BurnOutSharp files = files?.Select(f => f.Replace('\\', '/'))?.ToList(); // Iterate through all checks - Parallel.ForEach(ScanningClasses.PathCheckClasses, checkClass => + Parallel.ForEach(PathCheckClasses, checkClass => { var subProtections = checkClass.PerformCheck(path, files); if (subProtections != null) @@ -172,45 +67,6 @@ namespace BurnOutSharp return protections; } - /// - /// Handle a single file based on all portable executable check implementations - /// - /// Name of the source file of the executable, for tracking - /// Executable to scan - /// Scanner object to use for options and scanning - /// Set of protections in file, null on error - public static ConcurrentDictionary> HandlePortableExecutableChecks(string fileName, Stream stream, PortableExecutable pex, Scanner scanner) - { - // Create the output dictionary - var protections = new ConcurrentDictionary>(); - - // Iterate through all checks - Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, checkClass => - { - // Get the protection for the class, if possible - var subProtections = checkClass.PerformCheck(fileName, pex, scanner.IncludeDebug); - if (subProtections == null) - return; - - // If we are filtering the output of the check - if (!CheckIfPacker(checkClass) || !scanner.ScanPackers) - return; - - // Add all found protections to the output - AppendToDictionary(protections, fileName, subProtections); - - // If we have an extractable implementation - if (checkClass is IExtractable extractable) - { - var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner); - if (extractedProtections != null) - AppendToDictionary(protections, extractedProtections); - } - }); - - return protections; - } - #endregion #region Single Implementation Handlers @@ -273,48 +129,6 @@ namespace BurnOutSharp return null; } - /// - /// Handle files based on an IContentCheck implementation - /// - /// IDetectable class representing the check - /// Name of the source file of the byte array, for tracking - /// Contents of the source file - /// True to include debug data, false otherwise - /// Set of protections in file, null on error - private static ConcurrentQueue PerformCheck(this IContentCheck impl, string fileName, byte[] fileContent, bool includeDebug) - { - string protection = impl.CheckContents(fileName, fileContent, includeDebug); - return ProcessProtectionString(protection); - } - - /// - /// Handle files based on an ILinearExecutableCheck implementation - /// - /// ILinearExecutableCheck class representing the check - /// Name of the source file of the executable, for tracking - /// LinearExecutable to check - /// True to include debug data, false otherwise - /// Set of protections in file, null on error - private static ConcurrentQueue PerformCheck(this ILinearExecutableCheck impl, string fileName, LinearExecutable lex, bool includeDebug) - { - string protection = impl.CheckLinearExecutable(fileName, lex, includeDebug); - return ProcessProtectionString(protection); - } - - /// - /// Handle files based on an INewExecutableCheck implementation - /// - /// INewExecutableCheck class representing the check - /// Name of the source file of the executable, for tracking - /// NewExecutable to check - /// True to include debug data, false otherwise - /// Set of protections in file, null on error - private static ConcurrentQueue PerformCheck(this INewExecutableCheck impl, string fileName, NewExecutable nex, bool includeDebug) - { - string protection = impl.CheckNewExecutable(fileName, nex, includeDebug); - return ProcessProtectionString(protection); - } - /// /// Handle files based on an IPathCheck implementation /// @@ -350,33 +164,31 @@ namespace BurnOutSharp return protections; } + #endregion + + #region Initializers + /// - /// Handle files based on an IPortableExecutableCheck implementation + /// Initialize all implementations of a type /// - /// IPortableExecutableCheck class representing the check - /// Name of the source file of the executable, for tracking - /// NewExecutable to check - /// True to include debug data, false otherwise - /// Set of protections in file, null on error - private static ConcurrentQueue PerformCheck(this IPortableExecutableCheck impl, string fileName, PortableExecutable pex, bool includeDebug) + private static IEnumerable InitCheckClasses() + => InitCheckClasses(typeof(BinaryObjectScanner.Packer._DUMMY).Assembly) + .Concat(InitCheckClasses(typeof(BinaryObjectScanner.Protection._DUMMY).Assembly)); + + /// + /// Initialize all implementations of a type + /// + private static IEnumerable InitCheckClasses(Assembly assembly) { - string protection = impl.CheckPortableExecutable(fileName, pex, includeDebug); - return ProcessProtectionString(protection); + return assembly.GetTypes() + .Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null) + .Select(t => (T)Activator.CreateInstance(t)); } #endregion #region Helpers - /// - /// Check to see if an implementation is a packer using reflection - /// - /// Implementation that was last used to check - private static bool CheckIfPacker(object impl) - { - return impl.GetType().Namespace.ToLowerInvariant().Contains("packer"); - } - /// /// Process a protection string if it includes multiple protections /// diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs index 54f37c6b..08c2e137 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -4,7 +4,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Threading.Tasks; using BinaryObjectScanner.FileType; +using BinaryObjectScanner.Interfaces; using BinaryObjectScanner.Utilities; using BinaryObjectScanner.Wrappers; using static BinaryObjectScanner.Utilities.Dictionary; @@ -297,9 +299,18 @@ namespace BurnOutSharp { // If we have an executable, it needs to bypass normal handling // TODO: Write custom executable handling - if (detectable is Executable) + if (detectable is Executable executable) { - ProcessExecutable(fileName, stream, protections); + executable.IncludePackers = ScanPackers; + + // TODO: Enable this after IExtractable is properly implemented for Executable + //var subProtections = Handler.HandleDetectable(executable, fileName, stream, IncludeDebug); + //if (subProtections != null) + // AppendToDictionary(protections, fileName, subProtections); + + var subProtections = ProcessExecutable(executable, fileName, stream); + if (subProtections != null) + AppendToDictionary(protections, subProtections); } // Otherwise, use the default implementation @@ -366,26 +377,29 @@ namespace BurnOutSharp /// /// Process scanning for an Executable type /// + /// Executable instance for processing /// Name of the source file of the stream, for tracking /// Stream to scan the contents of - /// Current set of protections to append to /// /// 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. /// - private void ProcessExecutable(string fileName, Stream stream, ConcurrentDictionary> protections) + private ConcurrentDictionary> ProcessExecutable(Executable executable, string fileName, Stream stream) { // Try to create a wrapper for the proper executable type var wrapper = WrapperFactory.CreateExecutableWrapper(stream); if (wrapper == null) - return; + return null; + + // Create the output dictionary + var protections = new ConcurrentDictionary>(); // Only use generic content checks if we're in debug mode if (IncludeDebug) { - var subProtections = Handler.HandleContentChecks(fileName, stream, this); + var subProtections = executable.RunContentChecks(fileName, stream, IncludeDebug); if (subProtections != null) - AppendToDictionary(protections, fileName, subProtections); + AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); } if (wrapper is MSDOS) @@ -394,22 +408,63 @@ namespace BurnOutSharp } else if (wrapper is LinearExecutable lex) { - var subProtections = Handler.HandleLinearExecutableChecks(fileName, stream, lex, this); - if (subProtections != null) - AppendToDictionary(protections, subProtections); + var subProtections = executable.RunLinearExecutableChecks(fileName, stream, lex, IncludeDebug); + if (subProtections == null) + return protections; + + // Append the returned values + AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + + // If we have any extractable packers + var extractables = subProtections.Keys.Where(c => c is IExtractable).Select(c => c as IExtractable); + Parallel.ForEach(extractables, extractable => + { + // Get the protection for the class, if possible + var extractedProtections = Handler.HandleExtractable(extractable, fileName, stream, this); + if (extractedProtections != null) + AppendToDictionary(protections, extractedProtections); + }); } else if (wrapper is NewExecutable nex) { - var subProtections = Handler.HandleNewExecutableChecks(fileName, stream, nex, this); - if (subProtections != null) - AppendToDictionary(protections, subProtections); + var subProtections = executable.RunNewExecutableChecks(fileName, stream, nex, IncludeDebug); + if (subProtections == null) + return protections; + + // Append the returned values + AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + + // If we have any extractable packers + var extractables = subProtections.Keys.Where(c => c is IExtractable).Select(c => c as IExtractable); + Parallel.ForEach(extractables, extractable => + { + // Get the protection for the class, if possible + var extractedProtections = Handler.HandleExtractable(extractable, fileName, stream, this); + if (extractedProtections != null) + AppendToDictionary(protections, extractedProtections); + }); } else if (wrapper is PortableExecutable pex) { - var subProtections = Handler.HandlePortableExecutableChecks(fileName, stream, pex, this); - if (subProtections != null) - AppendToDictionary(protections, subProtections); + var subProtections = executable.RunPortableExecutableChecks(fileName, stream, pex, IncludeDebug); + if (subProtections == null) + return protections; + + // Append the returned values + AppendToDictionary(protections, fileName, subProtections.Values.ToArray()); + + // If we have any extractable packers + var extractables = subProtections.Keys.Where(c => c is IExtractable).Select(c => c as IExtractable); + Parallel.ForEach(extractables, extractable => + { + // Get the protection for the class, if possible + var extractedProtections = Handler.HandleExtractable(extractable, fileName, stream, this); + if (extractedProtections != null) + AppendToDictionary(protections, extractedProtections); + }); } + + return protections; } #endregion diff --git a/BurnOutSharp/ScanningClasses.cs b/BurnOutSharp/ScanningClasses.cs deleted file mode 100644 index 7c689e69..00000000 --- a/BurnOutSharp/ScanningClasses.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using BinaryObjectScanner.Interfaces; - -namespace BurnOutSharp -{ - /// - /// Statically-generated lists of scanning classes - /// - internal static class ScanningClasses - { - #region Public Collections - - /// - /// Cache for all IContentCheck types - /// - public static IEnumerable ContentCheckClasses - { - get - { - if (contentCheckClasses == null) - contentCheckClasses = InitCheckClasses(); - - return contentCheckClasses; - } - } - - /// - /// Cache for all IExtractable types - /// - public static IEnumerable ExtractableClasses - { - get - { - if (extractableClasses == null) - extractableClasses = InitCheckClasses(); - - return extractableClasses; - } - } - - /// - /// Cache for all ILinearExecutableCheck types - /// - public static IEnumerable LinearExecutableCheckClasses - { - get - { - if (linearExecutableCheckClasses == null) - linearExecutableCheckClasses = InitCheckClasses(); - - return linearExecutableCheckClasses; - } - } - - /// - /// Cache for all INewExecutableCheck types - /// - public static IEnumerable NewExecutableCheckClasses - { - get - { - if (newExecutableCheckClasses == null) - newExecutableCheckClasses = InitCheckClasses(); - - return newExecutableCheckClasses; - } - } - - /// - /// Cache for all IPathCheck types - /// - public static IEnumerable PathCheckClasses - { - get - { - if (pathCheckClasses == null) - pathCheckClasses = InitCheckClasses(); - - return pathCheckClasses; - } - } - - /// - /// Cache for all IPortableExecutableCheck types - /// - public static IEnumerable PortableExecutableCheckClasses - { - get - { - if (portableExecutableCheckClasses == null) - portableExecutableCheckClasses = InitCheckClasses(); - - return portableExecutableCheckClasses; - } - } - - #endregion - - #region Internal Instances - - /// - /// Cache for all IContentCheck types - /// - private static IEnumerable contentCheckClasses; - - /// - /// Cache for all IExtractable types - /// - private static IEnumerable extractableClasses; - - /// - /// Cache for all ILinearExecutableCheck types - /// - private static IEnumerable linearExecutableCheckClasses; - - /// - /// Cache for all INewExecutableCheck types - /// - private static IEnumerable newExecutableCheckClasses; - - /// - /// Cache for all IPathCheck types - /// - private static IEnumerable pathCheckClasses; - - /// - /// Cache for all IPortableExecutableCheck types - /// - private static IEnumerable portableExecutableCheckClasses; - - #endregion - - #region Initializers - - /// - /// Initialize all implementations of a type - /// - private static IEnumerable InitCheckClasses() - => InitCheckClasses(typeof(BinaryObjectScanner.Packer._DUMMY).Assembly) - .Concat(InitCheckClasses(typeof(BinaryObjectScanner.Protection._DUMMY).Assembly)); - - /// - /// Initialize all implementations of a type - /// - private static IEnumerable InitCheckClasses(Assembly assembly) - { - return assembly.GetTypes() - .Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null) - .Select(t => (T)Activator.CreateInstance(t)); - } - - #endregion - } -}