From f4310206e926a5db7949d6e886f0d13e5cd577f6 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 26 Feb 2021 09:26:23 -0800 Subject: [PATCH] Add IScannable interface --- BurnOutSharp/FileType/BFPK.cs | 20 ++++++- BurnOutSharp/FileType/BZip2.cs | 23 ++++++-- BurnOutSharp/FileType/Executable.cs | 47 ++++++++++++--- BurnOutSharp/FileType/GZIP.cs | 20 ++++++- BurnOutSharp/FileType/InstallShieldCAB.cs | 20 ++++++- BurnOutSharp/FileType/MPQ.cs | 20 ++++++- BurnOutSharp/FileType/MSI.cs | 20 ++++++- BurnOutSharp/FileType/MicrosoftCAB.cs | 20 ++++++- BurnOutSharp/FileType/PKZIP.cs | 20 ++++++- BurnOutSharp/FileType/RAR.cs | 20 ++++++- BurnOutSharp/FileType/SevenZip.cs | 20 ++++++- BurnOutSharp/FileType/TapeArchive.cs | 20 ++++++- BurnOutSharp/FileType/Textfile.cs | 42 ++++++++++--- BurnOutSharp/FileType/Valve.cs | 20 ++++++- BurnOutSharp/FileType/XZ.cs | 20 ++++++- BurnOutSharp/IScannable.cs | 33 +++++++++++ BurnOutSharp/ProtectionType/WiseInstaller.cs | 42 ++++++------- BurnOutSharp/Scanner.cs | 62 ++++++++++---------- 18 files changed, 379 insertions(+), 110 deletions(-) create mode 100644 BurnOutSharp/IScannable.cs diff --git a/BurnOutSharp/FileType/BFPK.cs b/BurnOutSharp/FileType/BFPK.cs index 22cbde80..a56a196e 100644 --- a/BurnOutSharp/FileType/BFPK.cs +++ b/BurnOutSharp/FileType/BFPK.cs @@ -7,9 +7,10 @@ using SharpCompress.Compressors.Deflate; namespace BurnOutSharp.FileType { - internal class BFPK + internal class BFPK : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x42, 0x46, 0x50, 0x4b })) return true; @@ -17,7 +18,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the BFPK file itself fails try diff --git a/BurnOutSharp/FileType/BZip2.cs b/BurnOutSharp/FileType/BZip2.cs index fba6077c..7dbc6bf0 100644 --- a/BurnOutSharp/FileType/BZip2.cs +++ b/BurnOutSharp/FileType/BZip2.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using SharpCompress.Compressors; using SharpCompress.Compressors.BZip2; namespace BurnOutSharp.FileType { - internal class BZip2 + internal class BZip2 : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x42, 0x52, 0x68 })) return true; @@ -17,9 +17,22 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) { - // If the 7-zip file itself fails + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) + { + // If the BZip2 file itself fails try { string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); diff --git a/BurnOutSharp/FileType/Executable.cs b/BurnOutSharp/FileType/Executable.cs index b330732f..1a376e75 100644 --- a/BurnOutSharp/FileType/Executable.cs +++ b/BurnOutSharp/FileType/Executable.cs @@ -6,9 +6,10 @@ using BurnOutSharp.ProtectionType; namespace BurnOutSharp.FileType { - internal class Executable + internal class Executable : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { // DOS MZ executable file format (and descendants) if (magic.StartsWith(new byte[] { 0x4d, 0x5a })) @@ -41,7 +42,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream, string file = null) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // Load the current file content byte[] fileContent = null; @@ -56,7 +70,6 @@ namespace BurnOutSharp.FileType // Files can be protected in multiple ways var protections = new Dictionary>(); - var subProtections = new Dictionary>(); string protection; #region Protections @@ -236,11 +249,6 @@ namespace BurnOutSharp.FileType if (!string.IsNullOrWhiteSpace(protection)) Utilities.AppendToDictionary(protections, file, protection); - // Wise Installer - subProtections = WiseInstaller.CheckContents(scanner, file, fileContent); - if (subProtections != null && subProtections.Count > 0) - Utilities.AppendToDictionary(protections, subProtections); - // WTM CD Protect protection = new WTMCDProtect().CheckContents(file, fileContent, scanner.IncludePosition); if (!string.IsNullOrWhiteSpace(protection)) @@ -258,6 +266,22 @@ namespace BurnOutSharp.FileType #endregion + #region Archive-as-Executable Formats / Installers + + // If we're looking for archives too, run scans + if (scanner.ScanArchives) + { + // Wise Installer + if (file != null && !string.IsNullOrEmpty(new WiseInstaller().CheckContents(file, fileContent, scanner.IncludePosition))) + { + var subProtections = new WiseInstaller().Scan(scanner, null, file); + Utilities.PrependToKeys(subProtections, file); + Utilities.AppendToDictionary(protections, subProtections); + } + } + + #endregion + #region Packers // If we're looking for packers too, run scans @@ -292,6 +316,11 @@ namespace BurnOutSharp.FileType protection = new UPX().CheckContents(file, fileContent, scanner.IncludePosition); if (!string.IsNullOrWhiteSpace(protection)) Utilities.AppendToDictionary(protections, file, protection); + + // Wise Installer + protection = new WiseInstaller().CheckContents(file, fileContent, scanner.IncludePosition); + if (!string.IsNullOrWhiteSpace(protection)) + Utilities.AppendToDictionary(protections, file, protection); } #endregion diff --git a/BurnOutSharp/FileType/GZIP.cs b/BurnOutSharp/FileType/GZIP.cs index 7bbb804a..6d65642b 100644 --- a/BurnOutSharp/FileType/GZIP.cs +++ b/BurnOutSharp/FileType/GZIP.cs @@ -6,9 +6,10 @@ using SharpCompress.Archives.GZip; namespace BurnOutSharp.FileType { - internal class GZIP + internal class GZIP : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x1f, 0x8b })) return true; @@ -16,7 +17,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the gzip file itself fails try diff --git a/BurnOutSharp/FileType/InstallShieldCAB.cs b/BurnOutSharp/FileType/InstallShieldCAB.cs index dd8ce43b..9f89e3cd 100644 --- a/BurnOutSharp/FileType/InstallShieldCAB.cs +++ b/BurnOutSharp/FileType/InstallShieldCAB.cs @@ -6,9 +6,10 @@ using UnshieldSharp; namespace BurnOutSharp.FileType { - internal class InstallShieldCAB + internal class InstallShieldCAB : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x49, 0x53, 0x63 })) return true; @@ -16,8 +17,21 @@ namespace BurnOutSharp.FileType return false; } + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + // TODO: Add stream opening support - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // Get the name of the first cabinet file or header string directory = Path.GetDirectoryName(file); diff --git a/BurnOutSharp/FileType/MPQ.cs b/BurnOutSharp/FileType/MPQ.cs index 846ca338..e63ca659 100644 --- a/BurnOutSharp/FileType/MPQ.cs +++ b/BurnOutSharp/FileType/MPQ.cs @@ -5,9 +5,10 @@ using StormLibSharp; namespace BurnOutSharp.FileType { - internal class MPQ + internal class MPQ : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x4d, 0x50, 0x51, 0x1a })) return true; @@ -15,8 +16,21 @@ namespace BurnOutSharp.FileType return false; } + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + // TODO: Add stream opening support - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the mpq file itself fails try diff --git a/BurnOutSharp/FileType/MSI.cs b/BurnOutSharp/FileType/MSI.cs index 1a690dbb..9c129e2f 100644 --- a/BurnOutSharp/FileType/MSI.cs +++ b/BurnOutSharp/FileType/MSI.cs @@ -7,9 +7,10 @@ using Microsoft.Deployment.WindowsInstaller; namespace BurnOutSharp.FileType { - internal class MSI + internal class MSI : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { #if NET_FRAMEWORK if (magic.StartsWith(new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 })) @@ -19,8 +20,21 @@ namespace BurnOutSharp.FileType return false; } + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + // TODO: Add stream opening support - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { #if NET_FRAMEWORK // If the MSI file itself fails diff --git a/BurnOutSharp/FileType/MicrosoftCAB.cs b/BurnOutSharp/FileType/MicrosoftCAB.cs index 80fe8b79..15af2669 100644 --- a/BurnOutSharp/FileType/MicrosoftCAB.cs +++ b/BurnOutSharp/FileType/MicrosoftCAB.cs @@ -8,9 +8,10 @@ using LibMSPackN; namespace BurnOutSharp.FileType { // Specification available at http://download.microsoft.com/download/5/0/1/501ED102-E53F-4CE0-AA6B-B0F93629DDC6/Exchange/%5BMS-CAB%5D.pdf - internal class MicrosoftCAB + internal class MicrosoftCAB : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { #if NET_FRAMEWORK if (magic.StartsWith(new byte[] { 0x4d, 0x53, 0x43, 0x46 })) @@ -20,8 +21,21 @@ namespace BurnOutSharp.FileType return false; } + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + // TODO: Add stream opening support - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { #if NET_FRAMEWORK // If the cab file itself fails diff --git a/BurnOutSharp/FileType/PKZIP.cs b/BurnOutSharp/FileType/PKZIP.cs index 18db5350..a2aba1f7 100644 --- a/BurnOutSharp/FileType/PKZIP.cs +++ b/BurnOutSharp/FileType/PKZIP.cs @@ -6,9 +6,10 @@ using SharpCompress.Archives.Zip; namespace BurnOutSharp.FileType { - internal class PKZIP + internal class PKZIP : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { // PKZIP if (magic.StartsWith(new byte[] { 0x50, 0x4b, 0x03, 0x04 })) @@ -25,7 +26,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the zip file itself fails try diff --git a/BurnOutSharp/FileType/RAR.cs b/BurnOutSharp/FileType/RAR.cs index 319af925..5cf4c5fd 100644 --- a/BurnOutSharp/FileType/RAR.cs +++ b/BurnOutSharp/FileType/RAR.cs @@ -6,9 +6,10 @@ using SharpCompress.Archives.Rar; namespace BurnOutSharp.FileType { - internal class RAR + internal class RAR : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { // RAR archive version 1.50 onwards if (magic.StartsWith(new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 })) @@ -21,7 +22,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the rar file itself fails try diff --git a/BurnOutSharp/FileType/SevenZip.cs b/BurnOutSharp/FileType/SevenZip.cs index 3a172c68..53a4ee0f 100644 --- a/BurnOutSharp/FileType/SevenZip.cs +++ b/BurnOutSharp/FileType/SevenZip.cs @@ -6,9 +6,10 @@ using SharpCompress.Archives.SevenZip; namespace BurnOutSharp.FileType { - internal class SevenZip + internal class SevenZip : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c })) return true; @@ -16,7 +17,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the 7-zip file itself fails try diff --git a/BurnOutSharp/FileType/TapeArchive.cs b/BurnOutSharp/FileType/TapeArchive.cs index d7756566..1ae94f51 100644 --- a/BurnOutSharp/FileType/TapeArchive.cs +++ b/BurnOutSharp/FileType/TapeArchive.cs @@ -6,9 +6,10 @@ using SharpCompress.Archives.Tar; namespace BurnOutSharp.FileType { - internal class TapeArchive + internal class TapeArchive : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0x75, 0x73, 0x74, 0x61, 0x72, 0x00, 0x30, 0x30 })) return true; @@ -19,7 +20,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the tar file itself fails try diff --git a/BurnOutSharp/FileType/Textfile.cs b/BurnOutSharp/FileType/Textfile.cs index 271c8860..9a392419 100644 --- a/BurnOutSharp/FileType/Textfile.cs +++ b/BurnOutSharp/FileType/Textfile.cs @@ -5,9 +5,21 @@ using System.Text; namespace BurnOutSharp.FileType { - internal class Textfile + internal class Textfile : IScannable { - public static bool ShouldScan(byte[] magic, string extension) + /// + public bool ShouldScan(byte[] magic) + { + return ShouldScan(magic, null); + } + + /// + /// Determine if a file signature or extension matches one of the expected values + /// + /// Byte array representing the file header + /// Extension for the file being checked + /// True if the signature is valid, false otherwise + public bool ShouldScan(byte[] magic, string extension) { // Rich Text File if (magic.StartsWith(new byte[] { 0x7b, 0x5c, 0x72, 0x74, 0x66, 0x31 })) @@ -26,15 +38,29 @@ namespace BurnOutSharp.FileType return true; // Generic textfile (no header) - if (string.Equals(extension.TrimStart('.'), "txt", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(extension?.TrimStart('.'), "txt", StringComparison.OrdinalIgnoreCase)) return true; return false; } - public static List Scan(Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) { - List protections = new List(); + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) + { + // Files can be protected in multiple ways + var protections = new Dictionary>(); try { @@ -47,13 +73,13 @@ namespace BurnOutSharp.FileType // CD-Key if (fileContent.Contains("a valid serial number is required")) - protections.Add("CD-Key / Serial"); + Utilities.AppendToDictionary(protections, file, "CD-Key / Serial"); else if (fileContent.Contains("serial number is located")) - protections.Add("CD-Key / Serial"); + Utilities.AppendToDictionary(protections, file, "CD-Key / Serial"); // MediaMax if (fileContent.Contains("MediaMax technology")) - protections.Add("MediaMax CD-3"); + Utilities.AppendToDictionary(protections, file, "MediaMax CD-3"); } catch { diff --git a/BurnOutSharp/FileType/Valve.cs b/BurnOutSharp/FileType/Valve.cs index 02583479..9877b3fd 100644 --- a/BurnOutSharp/FileType/Valve.cs +++ b/BurnOutSharp/FileType/Valve.cs @@ -5,9 +5,10 @@ using HLExtract.Net; namespace BurnOutSharp.FileType { - internal class Valve + internal class Valve : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { // GCF if (magic.StartsWith(new byte[] { 0x01, 0x00, 0x00, 0x00 })) @@ -32,8 +33,21 @@ namespace BurnOutSharp.FileType return false; } + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + // TODO: Add stream opening support - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(tempPath); diff --git a/BurnOutSharp/FileType/XZ.cs b/BurnOutSharp/FileType/XZ.cs index 7d762f7d..a611037a 100644 --- a/BurnOutSharp/FileType/XZ.cs +++ b/BurnOutSharp/FileType/XZ.cs @@ -5,9 +5,10 @@ using SharpCompress.Compressors.Xz; namespace BurnOutSharp.FileType { - internal class XZ + internal class XZ : IScannable { - public static bool ShouldScan(byte[] magic) + /// + public bool ShouldScan(byte[] magic) { if (magic.StartsWith(new byte[] { 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00 })) return true; @@ -15,7 +16,20 @@ namespace BurnOutSharp.FileType return false; } - public static Dictionary> Scan(Scanner scanner, Stream stream) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the xz file itself fails try diff --git a/BurnOutSharp/IScannable.cs b/BurnOutSharp/IScannable.cs new file mode 100644 index 00000000..28359066 --- /dev/null +++ b/BurnOutSharp/IScannable.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.IO; + +namespace BurnOutSharp +{ + public interface IScannable + { + /// + /// Determine if a file signature matches one of the expected values + /// + /// Byte array representing the file header + /// True if the signature is valid, false otherwise + bool ShouldScan(byte[] magic); + + /// + /// 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 + Dictionary> 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 + Dictionary> Scan(Scanner scanner, Stream stream, string filename); + } +} diff --git a/BurnOutSharp/ProtectionType/WiseInstaller.cs b/BurnOutSharp/ProtectionType/WiseInstaller.cs index aba389a3..a03890a4 100644 --- a/BurnOutSharp/ProtectionType/WiseInstaller.cs +++ b/BurnOutSharp/ProtectionType/WiseInstaller.cs @@ -5,35 +5,36 @@ using Wise = WiseUnpacker.WiseUnpacker; namespace BurnOutSharp.ProtectionType { - public class WiseInstaller + public class WiseInstaller : IContentCheck, IScannable { - public static Dictionary> CheckContents(Scanner scanner, string file, byte[] fileContent) + /// + public bool ShouldScan(byte[] magic) => true; + + /// + public string CheckContents(string file, byte[] fileContent, bool includePosition = false) { // WiseMain byte[] check = new byte[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }; if (fileContent.Contains(check, out int position)) - { - Dictionary> protections = new Dictionary>(); - if (scanner.ScanPackers) - protections[file ?? "NO FILENAME"] = new List { "Wise Installation Wizard Module" + (scanner.IncludePosition ? $" (Index {position})" : string.Empty) }; - - if (file == null || !File.Exists(file)) - return protections; - - if (scanner.ScanArchives) - { - var subProtections = Scan(scanner, file); - Utilities.PrependToKeys(subProtections, file); - Utilities.AppendToDictionary(protections, subProtections); - } - - return protections; - } + return "Wise Installation Wizard Module" + (includePosition ? $" (Index {position})" : string.Empty); return null; } - public static Dictionary> Scan(Scanner scanner, string file) + /// + public Dictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.OpenRead(file)) + { + return Scan(scanner, fs, file); + } + } + + /// + public Dictionary> Scan(Scanner scanner, Stream stream, string file) { // If the installer file itself fails try @@ -63,6 +64,5 @@ namespace BurnOutSharp.ProtectionType return null; } - } } diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs index 0b979e92..093a57a8 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -441,17 +441,17 @@ namespace BurnOutSharp #region Non-Archive File Types // Executable - if (ScanAllFiles || Executable.ShouldScan(magic)) + if (ScanAllFiles || new Executable().ShouldScan(magic)) { - var subProtections = Executable.Scan(this, fs, file); + var subProtections = new Executable().Scan(this, fs, file); Utilities.AppendToDictionary(protections, subProtections); } // Text-based files - if (ScanAllFiles || Textfile.ShouldScan(magic, extension)) + if (ScanAllFiles || new Textfile().ShouldScan(magic, extension)) { - var subProtections = Textfile.Scan(fs); - Utilities.AppendToDictionary(protections, file, subProtections); + var subProtections = new Textfile().Scan(this, fs, file); + Utilities.AppendToDictionary(protections, subProtections); } #endregion @@ -462,105 +462,105 @@ namespace BurnOutSharp if (ScanArchives) { // 7-Zip archive - if (SevenZip.ShouldScan(magic)) + if (new SevenZip().ShouldScan(magic)) { - var subProtections = SevenZip.Scan(this, fs); + var subProtections = new SevenZip().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // BFPK archive - if (BFPK.ShouldScan(magic)) + if (new BFPK().ShouldScan(magic)) { - var subProtections = BFPK.Scan(this, fs); + var subProtections = new BFPK().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // BZip2 - if (BZip2.ShouldScan(magic)) + if (new BZip2().ShouldScan(magic)) { - var subProtections = BZip2.Scan(this, fs); + var subProtections = new BZip2().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // GZIP - if (GZIP.ShouldScan(magic)) + if (new GZIP().ShouldScan(magic)) { - var subProtections = GZIP.Scan(this, fs); + var subProtections = new GZIP().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // InstallShield Cabinet - if (file != null && InstallShieldCAB.ShouldScan(magic)) + if (file != null && new InstallShieldCAB().ShouldScan(magic)) { - var subProtections = InstallShieldCAB.Scan(this, file); + var subProtections = new InstallShieldCAB().Scan(this, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // Microsoft Cabinet - if (file != null && MicrosoftCAB.ShouldScan(magic)) + if (file != null && new MicrosoftCAB().ShouldScan(magic)) { - var subProtections = MicrosoftCAB.Scan(this, file); + var subProtections = new MicrosoftCAB().Scan(this, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // MSI - if (file != null && MSI.ShouldScan(magic)) + if (file != null && new MSI().ShouldScan(magic)) { - var subProtections = MSI.Scan(this, file); + var subProtections = new MSI().Scan(this, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // MPQ archive - if (file != null && MPQ.ShouldScan(magic)) + if (file != null && new MPQ().ShouldScan(magic)) { - var subProtections = MPQ.Scan(this, file); + var subProtections = new MPQ().Scan(this, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // PKZIP archive (and derivatives) - if (PKZIP.ShouldScan(magic)) + if (new PKZIP().ShouldScan(magic)) { - var subProtections = PKZIP.Scan(this, fs); + var subProtections = new PKZIP().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // RAR archive - if (RAR.ShouldScan(magic)) + if (new RAR().ShouldScan(magic)) { - var subProtections = RAR.Scan(this, fs); + var subProtections = new RAR().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // Tape Archive - if (TapeArchive.ShouldScan(magic)) + if (new TapeArchive().ShouldScan(magic)) { - var subProtections = TapeArchive.Scan(this, fs); + var subProtections = new TapeArchive().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // Valve archive formats - if (file != null && Valve.ShouldScan(magic)) + if (file != null && new Valve().ShouldScan(magic)) { - var subProtections = Valve.Scan(this, file); + var subProtections = new Valve().Scan(this, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); } // XZ - if (XZ.ShouldScan(magic)) + if (new XZ().ShouldScan(magic)) { - var subProtections = XZ.Scan(this, fs); + var subProtections = new XZ().Scan(this, fs, file); Utilities.PrependToKeys(subProtections, file); Utilities.AppendToDictionary(protections, subProtections); }