diff --git a/BinaryObjectScanner.FileType/Executable.cs b/BinaryObjectScanner.FileType/Executable.cs
index 133ea9c0..5d57262f 100644
--- a/BinaryObjectScanner.FileType/Executable.cs
+++ b/BinaryObjectScanner.FileType/Executable.cs
@@ -56,6 +56,20 @@ namespace BinaryObjectScanner.FileType
}
}
+ ///
+ /// Cache for all IMSDOSExecutableCheck types
+ ///
+ public static IEnumerable MSDOSExecutableCheckClasses
+ {
+ get
+ {
+ if (msdosExecutableCheckClasses == null)
+ msdosExecutableCheckClasses = InitCheckClasses();
+
+ return msdosExecutableCheckClasses;
+ }
+ }
+
///
/// Cache for all INewExecutableCheck types
///
@@ -98,6 +112,11 @@ namespace BinaryObjectScanner.FileType
///
private static IEnumerable linearExecutableCheckClasses;
+ ///
+ /// Cache for all IMSDOSExecutableCheck types
+ ///
+ private static IEnumerable msdosExecutableCheckClasses;
+
///
/// Cache for all INewExecutableCheck types
///
@@ -141,9 +160,11 @@ namespace BinaryObjectScanner.FileType
protections.AddRange(subProtections.Values.ToArray());
}
- if (wrapper is MSDOS)
+ if (wrapper is MSDOS mz)
{
- // No-op until protection classes implmented
+ var subProtections = RunMSDOSExecutableChecks(file, stream, mz, includeDebug);
+ if (subProtections != null)
+ protections.AddRange(subProtections.Values.ToArray());
}
else if (wrapper is LinearExecutable lex)
{
@@ -252,6 +273,36 @@ namespace BinaryObjectScanner.FileType
return protections;
}
+ ///
+ /// Handle a single file based on all MS-DOS 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 RunMSDOSExecutableChecks(string file, Stream stream, MSDOS mz, bool includeDebug)
+ {
+ // Create the output dictionary
+ var protections = new ConcurrentDictionary();
+
+ // Iterate through all checks
+ Parallel.ForEach(MSDOSExecutableCheckClasses, checkClass =>
+ {
+ // Get the protection for the class, if possible
+ string protection = checkClass.CheckMSDOSExecutable(file, mz, 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
///
diff --git a/BinaryObjectScanner.Interfaces/IMSDOSExecutableCheck.cs b/BinaryObjectScanner.Interfaces/IMSDOSExecutableCheck.cs
new file mode 100644
index 00000000..19d8f3b9
--- /dev/null
+++ b/BinaryObjectScanner.Interfaces/IMSDOSExecutableCheck.cs
@@ -0,0 +1,19 @@
+using BinaryObjectScanner.Wrappers;
+
+namespace BinaryObjectScanner.Interfaces
+{
+ ///
+ /// Check a MS-DOS Executable (MZ) for protection
+ ///
+ public interface IMSDOSExecutableCheck
+ {
+ ///
+ /// Check a path for protections based on file contents
+ ///
+ /// File to check for protection indicators
+ /// MSDOS representing the read-in file
+ /// True to include debug data, false otherwise
+ /// String containing any protections found in the file
+ string CheckMSDOSExecutable(string file, MSDOS mz, bool includeDebug);
+ }
+}
diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs
index 11766d4f..cf3a663a 100644
--- a/BurnOutSharp/Scanner.cs
+++ b/BurnOutSharp/Scanner.cs
@@ -391,9 +391,19 @@ namespace BurnOutSharp
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
}
- if (wrapper is MSDOS)
+ if (wrapper is MSDOS mz)
{
- // No-op until protection classes implmented
+ var subProtections = executable.RunMSDOSExecutableChecks(fileName, stream, mz, IncludeDebug);
+ if (subProtections == null)
+ return protections;
+
+ // Append the returned values
+ AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+
+ // If we have any extractable packers
+ var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, stream);
+ if (extractedProtections != null)
+ AppendToDictionary(protections, extractedProtections);
}
else if (wrapper is LinearExecutable lex)
{