mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-04 05:35:49 +00:00
Start rearranging things
This commit is contained in:
@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.Test
|
||||
WrapperType.AACSMediaKeyBlock,
|
||||
WrapperType.BDPlusSVM,
|
||||
//WrapperType.CIA,
|
||||
WrapperType.Executable,
|
||||
//WrapperType.Executable,
|
||||
WrapperType.LDSCRYPT,
|
||||
//WrapperType.N3DS,
|
||||
//WrapperType.Nitro,
|
||||
@@ -63,7 +63,7 @@ namespace BinaryObjectScanner.Test
|
||||
WrapperType.BZip2,
|
||||
WrapperType.CFB,
|
||||
//WrapperType.CIA,
|
||||
WrapperType.Executable,
|
||||
//WrapperType.Executable,
|
||||
WrapperType.GCF,
|
||||
WrapperType.GZip,
|
||||
WrapperType.InstallShieldArchiveV3,
|
||||
|
||||
30
BinaryObjectScanner.Test/FileType/LinearExecutableTests.cs
Normal file
30
BinaryObjectScanner.Test/FileType/LinearExecutableTests.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.FileType;
|
||||
using Xunit;
|
||||
|
||||
namespace BinaryObjectScanner.Test.FileType
|
||||
{
|
||||
public class LinearExecutableTests
|
||||
{
|
||||
[Fact]
|
||||
public void DetectFile_EmptyString_Null()
|
||||
{
|
||||
string file = string.Empty;
|
||||
var detectable = new LinearExecutable();
|
||||
|
||||
string? actual = detectable.Detect(file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectStream_EmptyStream_Null()
|
||||
{
|
||||
Stream? stream = new MemoryStream();
|
||||
string file = string.Empty;
|
||||
var detectable = new LinearExecutable();
|
||||
|
||||
string? actual = detectable.Detect(stream, file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ using Xunit;
|
||||
|
||||
namespace BinaryObjectScanner.Test.FileType
|
||||
{
|
||||
public class ExecutableTests
|
||||
public class MSDOSTests
|
||||
{
|
||||
[Fact]
|
||||
public void DetectFile_EmptyString_Null()
|
||||
{
|
||||
string file = string.Empty;
|
||||
var detectable = new Executable();
|
||||
var detectable = new MSDOS();
|
||||
|
||||
string? actual = detectable.Detect(file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
@@ -21,7 +21,7 @@ namespace BinaryObjectScanner.Test.FileType
|
||||
{
|
||||
Stream? stream = new MemoryStream();
|
||||
string file = string.Empty;
|
||||
var detectable = new Executable();
|
||||
var detectable = new MSDOS();
|
||||
|
||||
string? actual = detectable.Detect(stream, file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
30
BinaryObjectScanner.Test/FileType/NewExecutableTests.cs
Normal file
30
BinaryObjectScanner.Test/FileType/NewExecutableTests.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.FileType;
|
||||
using Xunit;
|
||||
|
||||
namespace BinaryObjectScanner.Test.FileType
|
||||
{
|
||||
public class NewExecutableTests
|
||||
{
|
||||
[Fact]
|
||||
public void DetectFile_EmptyString_Null()
|
||||
{
|
||||
string file = string.Empty;
|
||||
var detectable = new NewExecutable();
|
||||
|
||||
string? actual = detectable.Detect(file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectStream_EmptyStream_Null()
|
||||
{
|
||||
Stream? stream = new MemoryStream();
|
||||
string file = string.Empty;
|
||||
var detectable = new NewExecutable();
|
||||
|
||||
string? actual = detectable.Detect(stream, file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
BinaryObjectScanner.Test/FileType/PortableExecutableTests.cs
Normal file
30
BinaryObjectScanner.Test/FileType/PortableExecutableTests.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.FileType;
|
||||
using Xunit;
|
||||
|
||||
namespace BinaryObjectScanner.Test.FileType
|
||||
{
|
||||
public class PortableExecutableTests
|
||||
{
|
||||
[Fact]
|
||||
public void DetectFile_EmptyString_Null()
|
||||
{
|
||||
string file = string.Empty;
|
||||
var detectable = new PortableExecutable();
|
||||
|
||||
string? actual = detectable.Detect(file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectStream_EmptyStream_Null()
|
||||
{
|
||||
Stream? stream = new MemoryStream();
|
||||
string file = string.Empty;
|
||||
var detectable = new PortableExecutable();
|
||||
|
||||
string? actual = detectable.Detect(stream, file, includeDebug: false);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner
|
||||
@@ -8,18 +8,41 @@ namespace BinaryObjectScanner
|
||||
/// <summary>
|
||||
/// Create an instance of a detectable based on file type
|
||||
/// </summary>
|
||||
public static IDetectable? CreateDetectable(WrapperType fileType)
|
||||
public static Interfaces.IDetectable? CreateDetectable(WrapperType fileType)
|
||||
=> CreateDetectable(fileType, null);
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of a detectable based on file type
|
||||
/// </summary>
|
||||
public static Interfaces.IDetectable? CreateDetectable(WrapperType fileType, IWrapper? wrapper)
|
||||
{
|
||||
// Use the wrapper before the type
|
||||
switch (wrapper)
|
||||
{
|
||||
case AACSMediaKeyBlock: return new FileType.AACSMediaKeyBlock();
|
||||
case BDPlusSVM: return new FileType.BDPlusSVM();
|
||||
// case CIA => new FileType.CIA(),
|
||||
case LinearExecutable: return new FileType.LinearExecutable();
|
||||
case MSDOS: return new FileType.MSDOS();
|
||||
// case N3DS: return new FileType.N3DS();
|
||||
case NewExecutable: return new FileType.NewExecutable();
|
||||
case PlayJAudioFile: return new FileType.PLJ();
|
||||
case PortableExecutable: return new FileType.PortableExecutable();
|
||||
}
|
||||
|
||||
// Fall back on the file type for types not implemented in Serialization
|
||||
return fileType switch
|
||||
{
|
||||
WrapperType.AACSMediaKeyBlock => new FileType.AACSMediaKeyBlock(),
|
||||
WrapperType.BDPlusSVM => new FileType.BDPlusSVM(),
|
||||
//WrapperType.CIA => new FileType.CIA(),
|
||||
WrapperType.Executable => new FileType.Executable(),
|
||||
// WrapperType.CIA => new FileType.CIA(),
|
||||
WrapperType.LDSCRYPT => new FileType.LDSCRYPT(),
|
||||
//WrapperType.N3DS => new FileType.N3DS(),
|
||||
//WrapperType.Nitro => new FileType.Nitro(),
|
||||
// WrapperType.LinearExecutable => new FileType.LinearExecutable(),
|
||||
// WrapperType.MSDOS => new FileType.MSDOS(),
|
||||
// WrapperType.N3DS => new FileType.N3DS(),
|
||||
// WrapperType.NewExecutable => new FileType.NewExecutable(),
|
||||
WrapperType.PlayJAudioFile => new FileType.PLJ(),
|
||||
// WrapperType.PortableExecutable => new FileType.PortableExecutable(),
|
||||
WrapperType.RealArcadeInstaller => new FileType.RealArcadeInstaller(),
|
||||
WrapperType.RealArcadeMezzanine => new FileType.RealArcadeMezzanine(),
|
||||
WrapperType.SFFS => new FileType.SFFS(),
|
||||
@@ -31,33 +54,84 @@ namespace BinaryObjectScanner
|
||||
/// <summary>
|
||||
/// Create an instance of an extractable based on file type
|
||||
/// </summary>
|
||||
public static IExtractable? CreateExtractable(WrapperType fileType)
|
||||
public static Interfaces.IExtractable? CreateExtractable(WrapperType fileType)
|
||||
=> CreateExtractable(fileType, null);
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of an extractable based on file type
|
||||
/// </summary>
|
||||
public static Interfaces.IExtractable? CreateExtractable(WrapperType fileType, IWrapper? wrapper)
|
||||
{
|
||||
// Use the wrapper before the type
|
||||
switch (wrapper)
|
||||
{
|
||||
case BFPK: return new FileType.BFPK();
|
||||
case BSP: return new FileType.BSP();
|
||||
case BZip2: return new FileType.BZip2();
|
||||
case CFB: return new FileType.CFB();
|
||||
// case CIA => new FileType.CIA(),
|
||||
case GCF: return new FileType.GCF();
|
||||
case GZip: return new FileType.GZip();
|
||||
case InstallShieldArchiveV3: return new FileType.InstallShieldArchiveV3();
|
||||
case InstallShieldCabinet: return new FileType.InstallShieldCAB();
|
||||
case LinearExecutable: return new FileType.LinearExecutable();
|
||||
case LZKWAJ: return new FileType.LZKWAJ();
|
||||
case LZQBasic: return new FileType.LZQBasic();
|
||||
case LZSZDD: return new FileType.LZSZDD();
|
||||
case MicrosoftCabinet: return new FileType.MicrosoftCAB();
|
||||
case MoPaQ: return new FileType.MPQ();
|
||||
case MSDOS: return new FileType.MSDOS();
|
||||
// case N3DS: return new FileType.N3DS();
|
||||
// case NCF: return new FileType.NCF();
|
||||
case NewExecutable: return new FileType.NewExecutable();
|
||||
// case Nitro: return new FileType.Nitro();
|
||||
case PAK: return new FileType.PAK();
|
||||
case PFF: return new FileType.PFF();
|
||||
case PKZIP: return new FileType.PKZIP();
|
||||
// case PlayJAudioFile: return new FileType.PLJ();
|
||||
case PortableExecutable: return new FileType.PortableExecutable();
|
||||
case Quantum: return new FileType.Quantum();
|
||||
case RAR: return new FileType.RAR();
|
||||
case SevenZip: return new FileType.SevenZip();
|
||||
case SGA: return new FileType.SGA();
|
||||
case TapeArchive: return new FileType.TapeArchive();
|
||||
case VBSP: return new FileType.VBSP();
|
||||
case VPK: return new FileType.VPK();
|
||||
case WAD3: return new FileType.WAD3();
|
||||
case XZ: return new FileType.XZ();
|
||||
case XZP: return new FileType.XZP();
|
||||
}
|
||||
|
||||
// Fall back on the file type for types not implemented in Serialization
|
||||
return fileType switch
|
||||
{
|
||||
WrapperType.BFPK => new FileType.BFPK(),
|
||||
WrapperType.BSP => new FileType.BSP(),
|
||||
WrapperType.BZip2 => new FileType.BZip2(),
|
||||
WrapperType.CFB => new FileType.CFB(),
|
||||
//WrapperType.CIA => new FileType.CIA(),
|
||||
WrapperType.Executable => new FileType.Executable(),
|
||||
// WrapperType.CIA => new FileType.CIA(),
|
||||
// WrapperType.Executable => new FileType.Executable(),
|
||||
WrapperType.GCF => new FileType.GCF(),
|
||||
WrapperType.GZip => new FileType.GZip(),
|
||||
WrapperType.InstallShieldArchiveV3 => new FileType.InstallShieldArchiveV3(),
|
||||
WrapperType.InstallShieldCAB => new FileType.InstallShieldCAB(),
|
||||
// WrapperType.LinearExecutable => new FileType.LinearExecutable(),
|
||||
WrapperType.LZKWAJ => new FileType.LZKWAJ(),
|
||||
WrapperType.LZQBasic => new FileType.LZQBasic(),
|
||||
WrapperType.LZSZDD => new FileType.LZSZDD(),
|
||||
WrapperType.MicrosoftCAB => new FileType.MicrosoftCAB(),
|
||||
WrapperType.MoPaQ => new FileType.MPQ(),
|
||||
//WrapperType.N3DS => new FileType.N3DS(),
|
||||
//WrapperType.NCF => new FileType.NCF(),
|
||||
//WrapperType.Nitro => new FileType.Nitro(),
|
||||
// WrapperType.MSDOS => new FileType.MSDOS(),
|
||||
// WrapperType.N3DS => new FileType.N3DS(),
|
||||
// WrapperType.NCF => new FileType.NCF(),
|
||||
// WrapperType.NewExecutable => new FileType.NewExecutable(),
|
||||
// WrapperType.Nitro => new FileType.Nitro(),
|
||||
WrapperType.PAK => new FileType.PAK(),
|
||||
WrapperType.PFF => new FileType.PFF(),
|
||||
WrapperType.PKZIP => new FileType.PKZIP(),
|
||||
//WrapperType.PlayJAudioFile => new FileType.PLJ(),
|
||||
//WrapperType.Quantum => new FileType.Quantum(),
|
||||
// WrapperType.PlayJAudioFile => new FileType.PLJ(),
|
||||
// WrapperType.PortableExecutable => new FileType.PortableExecutable(),
|
||||
// WrapperType.Quantum => new FileType.Quantum(),
|
||||
WrapperType.RAR => new FileType.RAR(),
|
||||
WrapperType.SevenZip => new FileType.SevenZip(),
|
||||
WrapperType.SFFS => new FileType.SFFS(),
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <summary>
|
||||
/// AACS media key block
|
||||
/// </summary>
|
||||
public class AACSMediaKeyBlock : IDetectable
|
||||
public class AACSMediaKeyBlock : IDetectable<SabreTools.Serialization.Wrappers.AACSMediaKeyBlock>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? Detect(string file, bool includeDebug)
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <summary>
|
||||
/// BD+ SVM
|
||||
/// </summary>
|
||||
public class BDPlusSVM : IDetectable
|
||||
public class BDPlusSVM : IDetectable<SabreTools.Serialization.Wrappers.BDPlusSVM>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? Detect(string file, bool includeDebug)
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <summary>
|
||||
/// Executable or library
|
||||
/// </summary>
|
||||
public class Executable : IDetectable, IExtractable
|
||||
public abstract class Executable<T> : IDetectable, IExtractable
|
||||
where T : WrapperBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? Detect(string file, bool includeDebug)
|
||||
@@ -24,74 +25,7 @@ namespace BinaryObjectScanner.FileType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Detect(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Try to create a wrapper for the proper executable type
|
||||
SabreTools.Serialization.Interfaces.IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (includeDebug)
|
||||
{
|
||||
var subProtections = RunContentChecks(file, stream, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
}
|
||||
|
||||
if (wrapper is MSDOS mz)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, mz, StaticChecks.MSDOSExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
}
|
||||
else if (wrapper is LinearExecutable lex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, lex, StaticChecks.LinearExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
}
|
||||
else if (wrapper is NewExecutable nex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, nex, StaticChecks.NewExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
}
|
||||
else if (wrapper is PortableExecutable pex)
|
||||
{
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, pex, StaticChecks.PortableExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
}
|
||||
|
||||
// If there are no protections
|
||||
if (protections.Count == 0)
|
||||
return null;
|
||||
|
||||
// Create the internal list
|
||||
var protectionList = new List<string>();
|
||||
foreach (string key in protections.Keys)
|
||||
{
|
||||
protectionList.AddRange(protections[key]);
|
||||
}
|
||||
|
||||
return string.Join(";", [.. protectionList]);
|
||||
}
|
||||
public abstract string? Detect(Stream stream, string file, bool includeDebug);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string file, string outDir, bool includeDebug)
|
||||
@@ -104,41 +38,7 @@ namespace BinaryObjectScanner.FileType
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
|
||||
{
|
||||
// Create the wrapper
|
||||
var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return false;
|
||||
|
||||
// Extract all files
|
||||
bool extractAny = false;
|
||||
Directory.CreateDirectory(outDir);
|
||||
if (wrapper is PortableExecutable pex)
|
||||
{
|
||||
if (new Packer.CExe().CheckExecutable(file, pex, includeDebug) != null)
|
||||
extractAny |= pex.ExtractCExe(outDir, includeDebug);
|
||||
|
||||
if (new Packer.EmbeddedFile().CheckExecutable(file, pex, includeDebug) != null)
|
||||
{
|
||||
extractAny |= pex.ExtractFromOverlay(outDir, includeDebug);
|
||||
extractAny |= pex.ExtractFromResources(outDir, includeDebug);
|
||||
}
|
||||
|
||||
if (new Packer.WiseInstaller().CheckExecutable(file, pex, includeDebug) != null)
|
||||
extractAny |= pex.ExtractWise(outDir, includeDebug);
|
||||
}
|
||||
else if (wrapper is NewExecutable nex)
|
||||
{
|
||||
if (new Packer.EmbeddedFile().CheckExecutable(file, nex, includeDebug) != null)
|
||||
extractAny |= nex.ExtractFromOverlay(outDir, includeDebug);
|
||||
|
||||
if (new Packer.WiseInstaller().CheckExecutable(file, nex, includeDebug) != null)
|
||||
extractAny |= nex.ExtractWise(outDir, includeDebug);
|
||||
}
|
||||
|
||||
return extractAny;
|
||||
}
|
||||
public abstract bool Extract(Stream? stream, string file, string outDir, bool includeDebug);
|
||||
|
||||
#region Check Runners
|
||||
|
||||
@@ -149,7 +49,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <param name="stream">Stream to scan the contents of</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Set of protections in file, empty on error</returns>
|
||||
private static IDictionary<IContentCheck, string> RunContentChecks(string? file, Stream stream, bool includeDebug)
|
||||
protected IDictionary<IContentCheck, string> RunContentChecks(string? file, Stream stream, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new CheckDictionary<IContentCheck>();
|
||||
@@ -202,8 +102,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <param name="scanner">Scanner for handling recursive protections</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Set of protections in file, empty on error</returns>
|
||||
private static IDictionary<U, string> RunExecutableChecks<T, U>(string file, T exe, List<U> checks, bool includeDebug)
|
||||
where T : WrapperBase
|
||||
protected IDictionary<U, string> RunExecutableChecks<U>(string file, T exe, List<U> checks, bool includeDebug)
|
||||
where U : IExecutableCheck<T>
|
||||
{
|
||||
// Create the output dictionary
|
||||
|
||||
67
BinaryObjectScanner/FileType/LinearExecutable.cs
Normal file
67
BinaryObjectScanner/FileType/LinearExecutable.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Data;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
/// <summary>
|
||||
/// Linear executable (LE/LX)
|
||||
/// </summary>
|
||||
public class LinearExecutable : Executable<SabreTools.Serialization.Wrappers.LinearExecutable>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override string? Detect(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Try to create a wrapper for the proper executable type
|
||||
SabreTools.Serialization.Interfaces.IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentProtections = RunContentChecks(file, stream, includeDebug);
|
||||
protections.Append(file, contentProtections.Values);
|
||||
}
|
||||
|
||||
// Only handle LE/LX
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.LinearExecutable lex)
|
||||
return null;
|
||||
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, lex, StaticChecks.LinearExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// If there are no protections
|
||||
if (protections.Count == 0)
|
||||
return null;
|
||||
|
||||
// Create the internal list
|
||||
var protectionList = new List<string>();
|
||||
foreach (string key in protections.Keys)
|
||||
{
|
||||
protectionList.AddRange(protections[key]);
|
||||
}
|
||||
|
||||
return string.Join(";", [.. protectionList]);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Extract(Stream? stream, string file, string outDir, bool includeDebug) => false;
|
||||
}
|
||||
}
|
||||
67
BinaryObjectScanner/FileType/MSDOS.cs
Normal file
67
BinaryObjectScanner/FileType/MSDOS.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Data;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
/// <summary>
|
||||
/// MS-DOS executable (MZ)
|
||||
/// </summary>
|
||||
public class MSDOS : Executable<SabreTools.Serialization.Wrappers.MSDOS>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override string? Detect(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Try to create a wrapper for the proper executable type
|
||||
SabreTools.Serialization.Interfaces.IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentProtections = RunContentChecks(file, stream, includeDebug);
|
||||
protections.Append(file, contentProtections.Values);
|
||||
}
|
||||
|
||||
// Only handle MS-DOS
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.MSDOS mz)
|
||||
return null;
|
||||
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, mz, StaticChecks.MSDOSExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// If there are no protections
|
||||
if (protections.Count == 0)
|
||||
return null;
|
||||
|
||||
// Create the internal list
|
||||
var protectionList = new List<string>();
|
||||
foreach (string key in protections.Keys)
|
||||
{
|
||||
protectionList.AddRange(protections[key]);
|
||||
}
|
||||
|
||||
return string.Join(";", [.. protectionList]);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Extract(Stream? stream, string file, string outDir, bool includeDebug) => false;
|
||||
}
|
||||
}
|
||||
90
BinaryObjectScanner/FileType/NewExecutable.cs
Normal file
90
BinaryObjectScanner/FileType/NewExecutable.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Data;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
/// <summary>
|
||||
/// New executable (NE)
|
||||
/// </summary>
|
||||
public class NewExecutable : Executable<SabreTools.Serialization.Wrappers.NewExecutable>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override string? Detect(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Try to create a wrapper for the proper executable type
|
||||
SabreTools.Serialization.Interfaces.IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentProtections = RunContentChecks(file, stream, includeDebug);
|
||||
protections.Append(file, contentProtections.Values);
|
||||
}
|
||||
|
||||
// Only handle NE
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.NewExecutable nex)
|
||||
return null;
|
||||
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, nex, StaticChecks.NewExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// If there are no protections
|
||||
if (protections.Count == 0)
|
||||
return null;
|
||||
|
||||
// Create the internal list
|
||||
var protectionList = new List<string>();
|
||||
foreach (string key in protections.Keys)
|
||||
{
|
||||
protectionList.AddRange(protections[key]);
|
||||
}
|
||||
|
||||
return string.Join(";", [.. protectionList]);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
|
||||
{
|
||||
// Create the wrapper
|
||||
var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return false;
|
||||
|
||||
// Only handle NE
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.NewExecutable nex)
|
||||
return false;
|
||||
|
||||
// Create the output directory
|
||||
Directory.CreateDirectory(outDir);
|
||||
|
||||
// Extract all files
|
||||
bool extractAny = false;
|
||||
if (new Packer.EmbeddedFile().CheckExecutable(file, nex, includeDebug) != null)
|
||||
extractAny |= nex.ExtractFromOverlay(outDir, includeDebug);
|
||||
|
||||
if (new Packer.WiseInstaller().CheckExecutable(file, nex, includeDebug) != null)
|
||||
extractAny |= nex.ExtractWise(outDir, includeDebug);
|
||||
|
||||
return extractAny;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace BinaryObjectScanner.FileType
|
||||
/// <summary>
|
||||
/// PlayJ audio file
|
||||
/// </summary>
|
||||
public class PLJ : IDetectable
|
||||
public class PLJ : IDetectable<SabreTools.Serialization.Wrappers.PlayJAudioFile>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string? Detect(string file, bool includeDebug)
|
||||
|
||||
96
BinaryObjectScanner/FileType/PortableExecutable.cs
Normal file
96
BinaryObjectScanner/FileType/PortableExecutable.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Data;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.FileType
|
||||
{
|
||||
/// <summary>
|
||||
/// Portable executable (PE)
|
||||
/// </summary>
|
||||
public class PortableExecutable : Executable<SabreTools.Serialization.Wrappers.PortableExecutable>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override string? Detect(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Try to create a wrapper for the proper executable type
|
||||
SabreTools.Serialization.Interfaces.IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentProtections = RunContentChecks(file, stream, includeDebug);
|
||||
protections.Append(file, contentProtections.Values);
|
||||
}
|
||||
|
||||
// Only handle PE
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.PortableExecutable pex)
|
||||
return null;
|
||||
|
||||
// Standard checks
|
||||
var subProtections
|
||||
= RunExecutableChecks(file, pex, StaticChecks.PortableExecutableCheckClasses, includeDebug);
|
||||
protections.Append(file, subProtections.Values);
|
||||
|
||||
// If there are no protections
|
||||
if (protections.Count == 0)
|
||||
return null;
|
||||
|
||||
// Create the internal list
|
||||
var protectionList = new List<string>();
|
||||
foreach (string key in protections.Keys)
|
||||
{
|
||||
protectionList.AddRange(protections[key]);
|
||||
}
|
||||
|
||||
return string.Join(";", [.. protectionList]);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
|
||||
{
|
||||
// Create the wrapper
|
||||
var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return false;
|
||||
|
||||
// Only handle PE
|
||||
if (wrapper is not SabreTools.Serialization.Wrappers.PortableExecutable pex)
|
||||
return false;
|
||||
|
||||
// Create the output directory
|
||||
Directory.CreateDirectory(outDir);
|
||||
|
||||
// Extract all files
|
||||
bool extractAny = false;
|
||||
if (new Packer.CExe().CheckExecutable(file, pex, includeDebug) != null)
|
||||
extractAny |= pex.ExtractCExe(outDir, includeDebug);
|
||||
|
||||
if (new Packer.EmbeddedFile().CheckExecutable(file, pex, includeDebug) != null)
|
||||
{
|
||||
extractAny |= pex.ExtractFromOverlay(outDir, includeDebug);
|
||||
extractAny |= pex.ExtractFromResources(outDir, includeDebug);
|
||||
}
|
||||
|
||||
if (new Packer.WiseInstaller().CheckExecutable(file, pex, includeDebug) != null)
|
||||
extractAny |= pex.ExtractWise(outDir, includeDebug);
|
||||
|
||||
return extractAny;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
BinaryObjectScanner/Interfaces/IDetectableT.cs
Normal file
9
BinaryObjectScanner/Interfaces/IDetectableT.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace BinaryObjectScanner.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark a file type as being able to be detected
|
||||
/// </summary>
|
||||
public interface IDetectable<T> : IDetectable where T : IWrapper { }
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Data;
|
||||
using BinaryObjectScanner.FileType;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -268,10 +267,13 @@ namespace BinaryObjectScanner
|
||||
if (fileType == WrapperType.UNKNOWN)
|
||||
return [];
|
||||
|
||||
// Get the wrapper, if possible
|
||||
var wrapper = WrapperFactory.CreateWrapper(fileType, stream);
|
||||
|
||||
#region Non-Archive File Types
|
||||
|
||||
// Create a detectable for the given file type
|
||||
var detectable = Factory.CreateDetectable(fileType);
|
||||
var detectable = Factory.CreateDetectable(fileType, wrapper);
|
||||
|
||||
// If we're scanning file contents
|
||||
if (detectable != null && _options.ScanContents)
|
||||
@@ -285,10 +287,10 @@ namespace BinaryObjectScanner
|
||||
#region Archive File Types
|
||||
|
||||
// Create an extractable for the given file type
|
||||
var extractable = Factory.CreateExtractable(fileType);
|
||||
var extractable = Factory.CreateExtractable(fileType, wrapper);
|
||||
|
||||
// If we're scanning archives
|
||||
if (extractable != null && (extractable is Executable || _options.ScanArchives))
|
||||
if (extractable != null && _options.ScanArchives)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user