diff --git a/BinaryObjectScanner.FileType/Executable.cs b/BinaryObjectScanner.FileType/Executable.cs
new file mode 100644
index 00000000..9a891943
--- /dev/null
+++ b/BinaryObjectScanner.FileType/Executable.cs
@@ -0,0 +1,54 @@
+using System;
+using System.IO;
+using BinaryObjectScanner.Interfaces;
+
+namespace BinaryObjectScanner.FileType
+{
+ ///
+ /// Executable or library
+ ///
+ ///
+ /// Due to the complexity of executables, all actual handling is offloaded to
+ /// another class that is used by the scanner
+ ///
+ public class Executable : IDetectable, IExtractable
+ {
+ ///
+ public string Detect(string file, bool includeDebug)
+ {
+ if (!File.Exists(file))
+ return null;
+
+ using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ return Detect(fs, file, includeDebug);
+ }
+ }
+
+ ///
+ /// This implementation should never be invoked
+ public string Detect(Stream stream, string file, bool includeDebug)
+ {
+ throw new InvalidOperationException();
+ }
+
+ ///
+ public string Extract(string file, bool includeDebug)
+ {
+ if (!File.Exists(file))
+ return null;
+
+ using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ return Extract(fs, file, includeDebug);
+ }
+ }
+
+ ///
+ /// This implementation should never be invoked
+ public string Extract(Stream stream, string file, bool includeDebug)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+}
diff --git a/BurnOutSharp/Factory.cs b/BurnOutSharp/Factory.cs
index 6a8997ba..964d1704 100644
--- a/BurnOutSharp/Factory.cs
+++ b/BurnOutSharp/Factory.cs
@@ -67,17 +67,5 @@ namespace BurnOutSharp
default: return null;
}
}
-
- ///
- /// Create an instance of a scannable based on file type
- ///
- public static IScannable CreateScannable(SupportedFileType fileType)
- {
- switch (fileType)
- {
- case SupportedFileType.Executable: return new BinaryObjectScanner.FileType.Executable();
- default: return null;
- }
- }
}
}
diff --git a/BurnOutSharp/FileType/Executable.cs b/BurnOutSharp/FileType/Executable.cs
deleted file mode 100644
index 1a8d4940..00000000
--- a/BurnOutSharp/FileType/Executable.cs
+++ /dev/null
@@ -1,339 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-using BurnOutSharp;
-using BinaryObjectScanner.Interfaces;
-using BinaryObjectScanner.Wrappers;
-using static BinaryObjectScanner.Utilities.Dictionary;
-
-namespace BinaryObjectScanner.FileType
-{
- ///
- /// Executable or library
- ///
- public class Executable : IDetectable, IExtractable, IScannable
- {
- ///
- public string Detect(string file, bool includeDebug)
- {
- if (!File.Exists(file))
- return null;
-
- using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- return Detect(fs, file, includeDebug);
- }
- }
-
- ///
- public string Detect(Stream stream, string file, bool includeDebug)
- {
- // Implementation notes:
- // - Executables may house more than one sort of packer/protection (see Textfile for details)
- // - The output of Detect directly influences which types of packers should be attempted for extraction
- // - There are no other file types that require this input, so is it worth changing the interface?
- // - Can this somehow delegate to the proper extractable type?
-
- return null;
-
- // The below code is a copy of what is currently in Scan, but without any of the
- // extraction code or packer filtering code. It is not currently enabled since it
- // is not as complete as the IScannable implementation and therefore cannot be reasonably
- // used as a replacement yet.
-
- // Files can be protected in multiple ways
- var protections = new ConcurrentQueue();
-
- // Load the current file content for debug only
- byte[] fileContent = null;
- if (includeDebug)
- {
- try
- {
- using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
- {
- fileContent = br.ReadBytes((int)stream.Length);
- }
- }
- catch (Exception ex)
- {
- if (includeDebug) Console.WriteLine(ex);
- }
- }
-
- // Get the wrapper for the appropriate executable type
- WrapperBase wrapper = WrapperFactory.CreateExecutableWrapper(stream);
- if (wrapper == null)
- return null;
-
- // Iterate through all generic content checks
- if (fileContent != null)
- {
- Parallel.ForEach(ScanningClasses.ContentCheckClasses, checkClass =>
- {
- string protection = checkClass.CheckContents(file, fileContent, includeDebug);
- protections.Enqueue(protection);
- });
- }
-
- // If we have an MS-DOS executable
- if (wrapper is MSDOS mz)
- {
- // No-op
- }
-
- // If we have a New Executable
- else if (wrapper is NewExecutable nex)
- {
- Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, checkClass =>
- {
- string protection = checkClass.CheckNewExecutable(file, nex, includeDebug);
- protections.Enqueue(protection);
- });
- }
-
- // If we have a Linear Executable
- else if (wrapper is LinearExecutable lex)
- {
- Parallel.ForEach(ScanningClasses.LinearExecutableCheckClasses, checkClass =>
- {
- string protection = checkClass.CheckLinearExecutable(file, lex, includeDebug);
- protections.Enqueue(protection);
- });
- }
-
- // If we have a Portable Executable
- else if (wrapper is PortableExecutable pex)
- {
- Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, checkClass =>
- {
- string protection = checkClass.CheckPortableExecutable(file, pex, includeDebug);
- protections.Enqueue(protection);
- });
- }
-
- return string.Join(";", protections.ToArray());
- }
-
- ///
- public string Extract(string file, bool includeDebug)
- {
- if (!File.Exists(file))
- return null;
-
- using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- return Extract(fs, file, includeDebug);
- }
- }
-
- ///
- public string Extract(Stream stream, string file, bool includeDebug)
- {
- // Implementation notes:
- // - Executables may house more than one sort of extractable packer/protection
- // - We currently have no way of defining what folder is output for a given extractable
- // - Everything else should be basically the same for other extractable types
- // - Which extractions to run is directly influenced by the detected protections
- // - Can this somehow delegate to the proper extractable type?
- // - Can we have a check in Scanner that then runs all extractable implementations if the class is Executable?
-
- // The following packers fully implement IExtractable (extract and doesn't return null)
- // -
- // -
- // -
- // -
- // -
-
- return null;
- }
-
- ///
- public ConcurrentDictionary> Scan(Scanner scanner, string file)
- {
- if (!File.Exists(file))
- return null;
-
- using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- return Scan(scanner, fs, file);
- }
- }
-
- ///
- public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file)
- {
- // Files can be protected in multiple ways
- var protections = new ConcurrentDictionary>();
-
- // Load the current file content for debug only
- byte[] fileContent = null;
- if (scanner.IncludeDebug)
- {
- try
- {
- using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
- {
- fileContent = br.ReadBytes((int)stream.Length);
- }
- }
- catch (Exception ex)
- {
- if (scanner.IncludeDebug) Console.WriteLine(ex);
-
- // Enable for odd files, keep disabled otherwise
- // AppendToDictionary(protections, file, "[Out of memory attempting to open]");
- // return protections;
- }
- }
-
- // Get the wrapper for the appropriate executable type
- WrapperBase wrapper = WrapperFactory.CreateExecutableWrapper(stream);
- if (wrapper == null)
- return protections;
-
- // Iterate through all generic content checks
- if (fileContent != null)
- {
- Parallel.ForEach(ScanningClasses.ContentCheckClasses, checkClass =>
- {
- // Get the protection for the class, if possible
- string protection = checkClass.CheckContents(file, fileContent, scanner.IncludeDebug);
- AppendToDictionary(protections, file, protection);
- });
- }
-
- // If we have an MS-DOS executable
- if (wrapper is MSDOS mz)
- {
- // No-op
- }
-
- // If we have a New Executable
- else if (wrapper is NewExecutable nex)
- {
- Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, checkClass =>
- {
- // Get the protection for the class, if possible
- string protection = checkClass.CheckNewExecutable(file, nex, scanner.IncludeDebug);
- if (ShouldAddProtection(checkClass, scanner.ScanPackers, protection))
- AppendToDictionary(protections, file, protection);
-
- // If we had a protection, check if it is extractable
- if (!string.IsNullOrWhiteSpace(protection))
- HandleExtractable(scanner, stream, file, checkClass, protections);
- });
- }
-
- // If we have a Linear Executable
- else if (wrapper is LinearExecutable lex)
- {
- Parallel.ForEach(ScanningClasses.LinearExecutableCheckClasses, checkClass =>
- {
- // Get the protection for the class, if possible
- string protection = checkClass.CheckLinearExecutable(file, lex, scanner.IncludeDebug);
- if (ShouldAddProtection(checkClass, scanner.ScanPackers, protection))
- AppendToDictionary(protections, file, protection);
-
- // If we had a protection, check if it is extractable
- if (!string.IsNullOrWhiteSpace(protection))
- HandleExtractable(scanner, stream, file, checkClass, protections);
- });
- }
-
- // If we have a Portable Executable
- else if (wrapper is PortableExecutable pex)
- {
- Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, checkClass =>
- {
- // Get the protection for the class, if possible
- string protection = checkClass.CheckPortableExecutable(file, pex, scanner.IncludeDebug);
- if (ShouldAddProtection(checkClass, scanner.ScanPackers, protection))
- AppendToDictionary(protections, file, protection);
-
- // If we had a protection, check if it is extractable
- if (!string.IsNullOrWhiteSpace(protection))
- HandleExtractable(scanner, stream, file, checkClass, protections);
- });
- }
-
- return protections;
- }
-
- #region Helpers
-
- ///
- /// Check to see if a protection should be added or not
- ///
- /// Class that was last used to check
- /// Determines if packers should be included in the output
- /// The protection result to be checked
- private bool ShouldAddProtection(object checkClass, bool scanPackers, string protection)
- {
- // If we have an invalid protection
- if (string.IsNullOrWhiteSpace(protection))
- return false;
-
- // If we have a valid content check based on settings
- if (scanPackers || !checkClass.GetType().Namespace.ToLowerInvariant().Contains("packer"))
- return true;
-
- // Everything else fails
- return false;
- }
-
- ///
- /// Handle extractable protections and packers
- ///
- /// Scanner object for state tracking
- /// Stream representing the input file
- /// Path to the input file
- /// Class representing the current packer or protection
- /// Set of existing protections to append to
- private static void HandleExtractable(Scanner scanner, Stream stream, string file, object checkingClass, ConcurrentDictionary> protections)
- {
- // If we don't have an IExtractable implementation
- if (!(checkingClass is IExtractable extractable))
- return;
-
- // If we have an invalid file
- if (file == null)
- return;
-
- // If the extractable file itself fails
- try
- {
- // Extract and get the output path
- string tempPath = extractable.Extract(stream, file, scanner.IncludeDebug);
- if (tempPath != null)
- return;
-
- // Collect and format all found protections
- var subProtections = scanner.GetProtections(tempPath);
-
- // If temp directory cleanup fails
- try
- {
- Directory.Delete(tempPath, true);
- }
- catch (Exception ex)
- {
- if (scanner.IncludeDebug) Console.WriteLine(ex);
- }
-
- // Prepare the returned protections
- StripFromKeys(protections, tempPath);
- PrependToKeys(subProtections, file);
- AppendToDictionary(protections, subProtections);
- }
- catch (Exception ex)
- {
- if (scanner.IncludeDebug) Console.WriteLine(ex);
- }
- }
-
- #endregion
- }
-}
diff --git a/BurnOutSharp/Handler.cs b/BurnOutSharp/Handler.cs
index 8ece76c3..34293b25 100644
--- a/BurnOutSharp/Handler.cs
+++ b/BurnOutSharp/Handler.cs
@@ -10,7 +10,6 @@ using static BinaryObjectScanner.Utilities.Dictionary;
namespace BurnOutSharp
{
- // TODO: Implement IExtractable handler
// TODO: Implement IPathCheck handler
internal static class Handler
{
@@ -21,10 +20,9 @@ namespace BurnOutSharp
///
/// Name of the source file of the stream, for tracking
/// Stream to scan the contents of
- /// True to include packers in the output, false otherwise
- /// True to include debug data, false otherwise
+ /// Scanner object to use for options and scanning
/// Set of protections in file, null on error
- public static ConcurrentQueue HandleContentChecks(string fileName, Stream stream, bool scanPackers, bool includeDebug)
+ public static ConcurrentQueue HandleContentChecks(string fileName, Stream stream, Scanner scanner)
{
// If we have an invalid file
if (string.IsNullOrWhiteSpace(fileName))
@@ -45,7 +43,7 @@ namespace BurnOutSharp
}
catch (Exception ex)
{
- if (includeDebug) Console.WriteLine(ex);
+ if (scanner.IncludeDebug) Console.WriteLine(ex);
return null;
}
@@ -56,11 +54,11 @@ namespace BurnOutSharp
Parallel.ForEach(ScanningClasses.ContentCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
- var subProtections = HandleContentCheck(checkClass, fileName, fileContent, includeDebug);
+ var subProtections = HandleContentCheck(checkClass, fileName, fileContent, scanner.IncludeDebug);
if (subProtections != null)
{
// If we are filtering the output of the check
- if (!CheckIfPacker(checkClass) || !scanPackers)
+ if (!CheckIfPacker(checkClass) || !scanner.ScanPackers)
return;
protections.AddRange(subProtections);
@@ -75,11 +73,9 @@ namespace BurnOutSharp
///
/// Name of the source file of the executable, for tracking
/// Executable to scan
- /// True to include extractable contents in the output, false otherwise
- /// True to include packers in the output, false otherwise
- /// True to include debug data, false otherwise
+ /// Scanner object to use for options and scanning
/// Set of protections in file, null on error
- public static ConcurrentDictionary> HandleNewExecutableChecks(string fileName, LinearExecutable lex, bool scanArchives, bool scanPackers, bool includeDebug)
+ public static ConcurrentDictionary> HandleLinearExecutableChecks(string fileName, Stream stream, LinearExecutable lex, Scanner scanner)
{
// Create the output dictionary
var protections = new ConcurrentDictionary>();
@@ -88,17 +84,24 @@ namespace BurnOutSharp
Parallel.ForEach(ScanningClasses.LinearExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
- var subProtections = HandleLinearExecutableCheck(checkClass, fileName, lex, includeDebug);
- if (subProtections != null)
+ var subProtections = HandleLinearExecutableCheck(checkClass, 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)
{
- // If we are filtering the output of the check
- if (!CheckIfPacker(checkClass) || !scanPackers)
- return;
-
- AppendToDictionary(protections, fileName, subProtections);
+ var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner);
+ if (extractedProtections != null)
+ AppendToDictionary(protections, extractedProtections);
}
-
- // TODO: Handle extractable implementations
});
return protections;
@@ -109,11 +112,9 @@ namespace BurnOutSharp
///
/// Name of the source file of the executable, for tracking
/// Executable to scan
- /// True to include extractable contents in the output, false otherwise
- /// True to include packers in the output, false otherwise
- /// True to include debug data, false otherwise
+ /// Scanner object to use for options and scanning
/// Set of protections in file, null on error
- public static ConcurrentDictionary> HandleNewExecutableChecks(string fileName, NewExecutable nex, bool scanArchives, bool scanPackers, bool includeDebug)
+ public static ConcurrentDictionary> HandleNewExecutableChecks(string fileName, Stream stream, NewExecutable nex, Scanner scanner)
{
// Create the output dictionary
var protections = new ConcurrentDictionary>();
@@ -122,17 +123,24 @@ namespace BurnOutSharp
Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
- var subProtections = HandleNewExecutableCheck(checkClass, fileName, nex, includeDebug);
- if (subProtections != null)
+ var subProtections = HandleNewExecutableCheck(checkClass, 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)
{
- // If we are filtering the output of the check
- if (!CheckIfPacker(checkClass) || !scanPackers)
- return;
-
- AppendToDictionary(protections, fileName, subProtections);
+ var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner);
+ if (extractedProtections != null)
+ AppendToDictionary(protections, extractedProtections);
}
-
- // TODO: Handle extractable implementations
});
return protections;
@@ -143,11 +151,9 @@ namespace BurnOutSharp
///
/// Name of the source file of the executable, for tracking
/// Executable to scan
- /// True to include extractable contents in the output, false otherwise
- /// True to include packers in the output, false otherwise
- /// True to include debug data, false otherwise
+ /// Scanner object to use for options and scanning
/// Set of protections in file, null on error
- public static ConcurrentDictionary> HandlePortableExecutableChecks(string fileName, PortableExecutable pex, bool scanArchives, bool scanPackers, bool includeDebug)
+ public static ConcurrentDictionary> HandlePortableExecutableChecks(string fileName, Stream stream, PortableExecutable pex, Scanner scanner)
{
// Create the output dictionary
var protections = new ConcurrentDictionary>();
@@ -156,17 +162,24 @@ namespace BurnOutSharp
Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
- var subProtections = HandlePortableExecutableCheck(checkClass, fileName, pex, includeDebug);
- if (subProtections != null)
+ var subProtections = HandlePortableExecutableCheck(checkClass, 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)
{
- // If we are filtering the output of the check
- if (!CheckIfPacker(checkClass) || !scanPackers)
- return;
-
- AppendToDictionary(protections, fileName, subProtections);
+ var extractedProtections = HandleExtractable(extractable, fileName, stream, scanner);
+ if (extractedProtections != null)
+ AppendToDictionary(protections, extractedProtections);
}
-
- // TODO: Handle extractable implementations
});
return protections;
@@ -204,6 +217,50 @@ namespace BurnOutSharp
return ProcessProtectionString(protection);
}
+ ///
+ /// Handle files based on an IExtractable implementation
+ ///
+ /// IDetectable class representing the file type
+ /// Name of the source file of the stream, for tracking
+ /// Stream to scan the contents of
+ /// Scanner object to use on extractable contents
+ /// Set of protections in file, null on error
+ public static ConcurrentDictionary> HandleExtractable(IExtractable impl, string fileName, Stream stream, Scanner scanner)
+ {
+ // If the extractable file itself fails
+ try
+ {
+ // Extract and get the output path
+ string tempPath = impl.Extract(stream, fileName, scanner.IncludeDebug);
+ if (tempPath == null)
+ return null;
+
+ // Collect and format all found protections
+ var subProtections = scanner.GetProtections(tempPath);
+
+ // If temp directory cleanup fails
+ try
+ {
+ Directory.Delete(tempPath, true);
+ }
+ catch (Exception ex)
+ {
+ if (scanner.IncludeDebug) Console.WriteLine(ex);
+ }
+
+ // Prepare the returned protections
+ StripFromKeys(subProtections, tempPath);
+ PrependToKeys(subProtections, fileName);
+ return subProtections;
+ }
+ catch (Exception ex)
+ {
+ if (scanner.IncludeDebug) Console.WriteLine(ex);
+ }
+
+ return null;
+ }
+
///
/// Handle files based on an ILinearExecutableCheck implementation
///
diff --git a/BurnOutSharp/Interfaces/IScannable.cs b/BurnOutSharp/Interfaces/IScannable.cs
deleted file mode 100644
index e0d5670e..00000000
--- a/BurnOutSharp/Interfaces/IScannable.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Collections.Concurrent;
-using System.IO;
-using BurnOutSharp;
-
-namespace BinaryObjectScanner.Interfaces
-{
- ///
- /// Mark a file type as being able to be scanned
- ///
- ///
- /// This is also used for packers, embedded archives, and other
- /// installer formats that may need to be "extracted" before they
- /// can be fully scanned.
- ///
- public interface IScannable
- {
- ///
- /// Scan a file for all internal protections
- ///
- /// Scanner object for state tracking
- /// Path to the input file
- /// Dictionary mapping paths to protection lists
- /// Ideally, this should just point to the other scan implementation
- ConcurrentDictionary> Scan(Scanner scanner, string file);
-
- ///
- /// Scan a stream for all internal protections
- ///
- /// Scanner object for state tracking
- /// Stream representing the input file
- /// Path to the input file
- /// Dictionary mapping paths to protection lists
- ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file);
- }
-}
diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs
index 30762d80..38925ad2 100644
--- a/BurnOutSharp/Scanner.cs
+++ b/BurnOutSharp/Scanner.cs
@@ -6,8 +6,8 @@ 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;
namespace BurnOutSharp
@@ -351,9 +351,7 @@ namespace BurnOutSharp
// TODO: Write custom executable handling
if (detectable is Executable)
{
- var subProtections = Handler.HandleDetectable(detectable, fileName, stream, IncludeDebug);
- if (subProtections != null)
- AppendToDictionary(protections, fileName, subProtections);
+ ProcessExecutable(fileName, stream, protections);
}
// Otherwise, use the default implementation
@@ -380,16 +378,6 @@ namespace BurnOutSharp
}
}
- // Create a scannable for the given file type
- var scannable = Factory.CreateScannable(fileType);
-
- // If we're scanning file contents
- if (scannable != null && ScanContents)
- {
- var subProtections = scannable.Scan(this, stream, fileName);
- AppendToDictionary(protections, subProtections);
- }
-
#endregion
#region Archive File Types
@@ -400,19 +388,10 @@ namespace BurnOutSharp
// If we're scanning archives
if (extractable != null && ScanArchives)
{
- // If we have an executable, it needs to bypass normal handling
- // TODO: Write custom executable handling
- if (extractable is Executable)
+ // We only want to process non-executables
+ if (!(extractable is Executable))
{
- var subProtections = HandleExtractable(extractable, fileName, stream);
- if (subProtections != null)
- AppendToDictionary(protections, subProtections);
- }
-
- // Otherwise, use the default implementation
- else
- {
- var subProtections = HandleExtractable(extractable, fileName, stream);
+ var subProtections = Handler.HandleExtractable(extractable, fileName, stream, this);
if (subProtections != null)
AppendToDictionary(protections, subProtections);
}
@@ -423,7 +402,6 @@ namespace BurnOutSharp
catch (Exception ex)
{
if (IncludeDebug) Console.WriteLine(ex);
-
AppendToDictionary(protections, fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
}
@@ -435,49 +413,55 @@ namespace BurnOutSharp
#endregion
- #region Interface Handlers
+ #region Executable Handling
///
- /// Handle files based on an IExtractable implementation
+ /// Process scanning for an Executable type
///
- /// IExtractable class representing the file type
/// Name of the source file of the stream, for tracking
/// Stream to scan the contents of
- /// Set of protections in internal files, null on error
- private ConcurrentDictionary> HandleExtractable(IExtractable extractable, string fileName, Stream stream)
+ /// 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)
{
- // If the extractable file itself fails
- try
+ // Try to create a wrapper for the proper executable type
+ var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
+ if (wrapper == null)
+ return;
+
+ // Only use generic content checks if we're in debug mode
+ if (IncludeDebug)
{
- // Extract and get the output path
- string tempPath = extractable.Extract(stream, fileName, IncludeDebug);
- if (tempPath == null)
- return null;
-
- // Collect and format all found protections
- var subProtections = GetProtections(tempPath);
-
- // If temp directory cleanup fails
- try
- {
- Directory.Delete(tempPath, true);
- }
- catch (Exception ex)
- {
- if (IncludeDebug) Console.WriteLine(ex);
- }
-
- // Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
- return subProtections;
- }
- catch (Exception ex)
- {
- if (IncludeDebug) Console.WriteLine(ex);
+ var subProtections = Handler.HandleContentChecks(fileName, stream, this);
+ if (subProtections != null)
+ AppendToDictionary(protections, fileName, subProtections);
}
- return null;
+ if (wrapper is MSDOS)
+ {
+ // No-op until protection classes implmented
+ }
+ else if (wrapper is LinearExecutable lex)
+ {
+ var subProtections = Handler.HandleLinearExecutableChecks(fileName, stream, lex, this);
+ if (subProtections != null)
+ AppendToDictionary(protections, subProtections);
+ }
+ else if (wrapper is NewExecutable nex)
+ {
+ var subProtections = Handler.HandleNewExecutableChecks(fileName, stream, nex, this);
+ if (subProtections != null)
+ AppendToDictionary(protections, subProtections);
+ }
+ else if (wrapper is PortableExecutable pex)
+ {
+ var subProtections = Handler.HandlePortableExecutableChecks(fileName, stream, pex, this);
+ if (subProtections != null)
+ AppendToDictionary(protections, subProtections);
+ }
}
#endregion