mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-04 13:45:28 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b78ba5621 | ||
|
|
c4734cfc3d | ||
|
|
dd45384226 | ||
|
|
3e75d9fa3b | ||
|
|
aa690ab602 | ||
|
|
7432100139 | ||
|
|
29fabb44eb | ||
|
|
ad776d4189 | ||
|
|
4cf12c76a8 | ||
|
|
39185f5ddd | ||
|
|
03477327c4 | ||
|
|
29fa0d1ac7 | ||
|
|
7eca23a7f3 | ||
|
|
f0c90bb332 | ||
|
|
0af67e5802 | ||
|
|
6ab9f730f9 | ||
|
|
258238bcc0 | ||
|
|
3936a15ef7 | ||
|
|
f6dbb349c4 | ||
|
|
3c69e02cfc | ||
|
|
531e634e62 | ||
|
|
f9c0c42b26 | ||
|
|
83aebbbfbd | ||
|
|
3847e5e9dc | ||
|
|
a72bb7e332 | ||
|
|
839791f467 | ||
|
|
469356e8c1 |
@@ -10,8 +10,10 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> --> <!-- Can't be enabled because of external code -->
|
||||
<Version>3.1.6</Version>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>3.1.11</Version>
|
||||
<!-- Mostly added due to external libraries -->
|
||||
<WarningsNotAsErrors>CS0162;CS0612;CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8618;CS8625;CS8634;CS8765;IL3000;NU5100</WarningsNotAsErrors>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
@@ -73,7 +75,7 @@
|
||||
<PackageReference Include="OpenMcdf" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
|
||||
<PackageReference Include="SharpCompress" Version="0.37.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.37.2" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
|
||||
@@ -81,14 +83,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.0" />
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.2.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.11" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.5" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.5.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.0" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.4.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.6.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.2" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.4.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner
|
||||
{
|
||||
@@ -8,22 +8,22 @@ namespace BinaryObjectScanner
|
||||
/// <summary>
|
||||
/// Create an instance of a detectable based on file type
|
||||
/// </summary>
|
||||
public static IDetectable? CreateDetectable(SupportedFileType fileType)
|
||||
public static IDetectable? CreateDetectable(WrapperType fileType)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case SupportedFileType.AACSMediaKeyBlock: return new FileType.AACSMediaKeyBlock();
|
||||
case SupportedFileType.BDPlusSVM: return new FileType.BDPlusSVM();
|
||||
//case SupportedFileType.CIA: return new FileType.CIA();
|
||||
case SupportedFileType.Executable: return new FileType.Executable();
|
||||
case SupportedFileType.LDSCRYPT: return new FileType.LDSCRYPT();
|
||||
//case SupportedFileType.N3DS: return new FileType.N3DS();
|
||||
//case SupportedFileType.Nitro: return new FileType.Nitro();
|
||||
case SupportedFileType.PLJ: return new FileType.PLJ();
|
||||
case SupportedFileType.RealArcadeInstaller: return new FileType.RealArcadeInstaller();
|
||||
case SupportedFileType.RealArcadeMezzanine: return new FileType.RealArcadeMezzanine();
|
||||
case SupportedFileType.SFFS: return new FileType.SFFS();
|
||||
case SupportedFileType.Textfile: return new FileType.Textfile();
|
||||
case WrapperType.AACSMediaKeyBlock: return new FileType.AACSMediaKeyBlock();
|
||||
case WrapperType.BDPlusSVM: return new FileType.BDPlusSVM();
|
||||
//case WrapperType.CIA: return new FileType.CIA();
|
||||
case WrapperType.Executable: return new FileType.Executable();
|
||||
case WrapperType.LDSCRYPT: return new FileType.LDSCRYPT();
|
||||
//case WrapperType.N3DS: return new FileType.N3DS();
|
||||
//case WrapperType.Nitro: return new FileType.Nitro();
|
||||
case WrapperType.PlayJAudioFile: return new FileType.PLJ();
|
||||
case WrapperType.RealArcadeInstaller: return new FileType.RealArcadeInstaller();
|
||||
case WrapperType.RealArcadeMezzanine: return new FileType.RealArcadeMezzanine();
|
||||
case WrapperType.SFFS: return new FileType.SFFS();
|
||||
case WrapperType.Textfile: return new FileType.Textfile();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
@@ -31,40 +31,40 @@ namespace BinaryObjectScanner
|
||||
/// <summary>
|
||||
/// Create an instance of an extractable based on file type
|
||||
/// </summary>
|
||||
public static IExtractable? CreateExtractable(SupportedFileType fileType)
|
||||
public static IExtractable? CreateExtractable(WrapperType fileType)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case SupportedFileType.BFPK: return new FileType.BFPK();
|
||||
case SupportedFileType.BSP: return new FileType.BSP();
|
||||
case SupportedFileType.BZip2: return new FileType.BZip2();
|
||||
case SupportedFileType.CFB: return new FileType.CFB();
|
||||
//case SupportedFileType.CIA: return new FileType.CIA();
|
||||
case SupportedFileType.GCF: return new FileType.GCF();
|
||||
case SupportedFileType.GZIP: return new FileType.GZIP();
|
||||
case SupportedFileType.InstallShieldArchiveV3: return new FileType.InstallShieldArchiveV3();
|
||||
case SupportedFileType.InstallShieldCAB: return new FileType.InstallShieldCAB();
|
||||
case SupportedFileType.MicrosoftCAB: return new FileType.MicrosoftCAB();
|
||||
case SupportedFileType.MicrosoftLZ: return new FileType.MicrosoftLZ();
|
||||
case SupportedFileType.MPQ: return new FileType.MPQ();
|
||||
//case SupportedFileType.N3DS: return new FileType.N3DS();
|
||||
//case SupportedFileType.NCF: return new FileType.NCF();
|
||||
//case SupportedFileType.Nitro: return new FileType.Nitro();
|
||||
case SupportedFileType.PAK: return new FileType.PAK();
|
||||
case SupportedFileType.PFF: return new FileType.PFF();
|
||||
case SupportedFileType.PKZIP: return new FileType.PKZIP();
|
||||
//case SupportedFileType.PLJ: return new FileType.PLJ();
|
||||
//case SupportedFileType.Quantum: return new FileType.Quantum();
|
||||
case SupportedFileType.RAR: return new FileType.RAR();
|
||||
case SupportedFileType.SevenZip: return new FileType.SevenZip();
|
||||
case SupportedFileType.SFFS: return new FileType.SFFS();
|
||||
case SupportedFileType.SGA: return new FileType.SGA();
|
||||
case SupportedFileType.TapeArchive: return new FileType.TapeArchive();
|
||||
case SupportedFileType.VBSP: return new FileType.VBSP();
|
||||
case SupportedFileType.VPK: return new FileType.VPK();
|
||||
case SupportedFileType.WAD: return new FileType.WAD();
|
||||
case SupportedFileType.XZ: return new FileType.XZ();
|
||||
case SupportedFileType.XZP: return new FileType.XZP();
|
||||
case WrapperType.BFPK: return new FileType.BFPK();
|
||||
case WrapperType.BSP: return new FileType.BSP();
|
||||
case WrapperType.BZip2: return new FileType.BZip2();
|
||||
case WrapperType.CFB: return new FileType.CFB();
|
||||
//case WrapperType.CIA: return new FileType.CIA();
|
||||
case WrapperType.GCF: return new FileType.GCF();
|
||||
case WrapperType.GZIP: return new FileType.GZIP();
|
||||
case WrapperType.InstallShieldArchiveV3: return new FileType.InstallShieldArchiveV3();
|
||||
case WrapperType.InstallShieldCAB: return new FileType.InstallShieldCAB();
|
||||
case WrapperType.MicrosoftCAB: return new FileType.MicrosoftCAB();
|
||||
case WrapperType.MicrosoftLZ: return new FileType.MicrosoftLZ();
|
||||
case WrapperType.MoPaQ: return new FileType.MPQ();
|
||||
//case WrapperType.N3DS: return new FileType.N3DS();
|
||||
//case WrapperType.NCF: return new FileType.NCF();
|
||||
//case WrapperType.Nitro: return new FileType.Nitro();
|
||||
case WrapperType.PAK: return new FileType.PAK();
|
||||
case WrapperType.PFF: return new FileType.PFF();
|
||||
case WrapperType.PKZIP: return new FileType.PKZIP();
|
||||
//case WrapperType.PlayJAudioFile: return new FileType.PLJ();
|
||||
//case WrapperType.Quantum: return new FileType.Quantum();
|
||||
case WrapperType.RAR: return new FileType.RAR();
|
||||
case WrapperType.SevenZip: return new FileType.SevenZip();
|
||||
case WrapperType.SFFS: return new FileType.SFFS();
|
||||
case WrapperType.SGA: return new FileType.SGA();
|
||||
case WrapperType.TapeArchive: return new FileType.TapeArchive();
|
||||
case WrapperType.VBSP: return new FileType.VBSP();
|
||||
case WrapperType.VPK: return new FileType.VPK();
|
||||
case WrapperType.WAD: return new FileType.WAD();
|
||||
case WrapperType.XZ: return new FileType.XZ();
|
||||
case WrapperType.XZP: return new FileType.XZP();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
@@ -20,10 +20,13 @@ namespace BinaryObjectScanner.Packer
|
||||
if (nex.Model.ResidentNameTable == null)
|
||||
return null;
|
||||
|
||||
// Check for the WinZip name string
|
||||
// Check for the WinZip name strings
|
||||
bool winZipNameFound = nex.Model.ResidentNameTable
|
||||
.Select(rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString))
|
||||
.Any(s => s.Contains("WZ-SE-01"));
|
||||
winZipNameFound |= nex.Model.NonResidentNameTable?
|
||||
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
|
||||
.Any(s => s.Contains("WinZip(R) Self-Extractor")) ?? false;
|
||||
|
||||
// If we didn't find it
|
||||
if (!winZipNameFound)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace System
|
||||
public class Progress<T> : IProgress<T> where T : EventArgs
|
||||
{
|
||||
/// <summary>The synchronization context captured upon construction. This will never be null.</summary>
|
||||
private readonly SynchronizationContext _synchronizationContext;
|
||||
private readonly SynchronizationContext? _synchronizationContext;
|
||||
/// <summary>The handler specified to the constructor. This may be null.</summary>
|
||||
private readonly Action<T>? _handler;
|
||||
/// <summary>A cached delegate used to post invocation to the synchronization context.</summary>
|
||||
@@ -73,7 +73,7 @@ namespace System
|
||||
{
|
||||
// Post the processing to the sync context.
|
||||
// (If T is a value type, it will get boxed here.)
|
||||
_synchronizationContext.Post(_invokeHandlers, value);
|
||||
_synchronizationContext?.Post(_invokeHandlers, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,14 @@ using System.Linq;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using System.Text;
|
||||
#endif
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using BinaryObjectScanner.FileType;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Dictionary;
|
||||
|
||||
@@ -133,11 +137,7 @@ namespace BinaryObjectScanner
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
// Enumerate all files at first for easier access
|
||||
#if NET20 || NET35
|
||||
var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories).ToList();
|
||||
#else
|
||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).ToList();
|
||||
#endif
|
||||
var files = IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories).ToList();
|
||||
|
||||
// Scan for path-detectable protections
|
||||
if (ScanPaths)
|
||||
@@ -330,12 +330,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Get the file type either from magic number or extension
|
||||
SupportedFileType fileType = FileTypes.GetFileType(magic);
|
||||
if (fileType == SupportedFileType.UNKNOWN)
|
||||
fileType = FileTypes.GetFileType(extension);
|
||||
|
||||
// If we still got unknown, just return null
|
||||
if (fileType == SupportedFileType.UNKNOWN)
|
||||
WrapperType fileType = WrapperFactory.GetFileType(magic, extension);
|
||||
if (fileType == WrapperType.UNKNOWN)
|
||||
return null;
|
||||
|
||||
#region Non-Archive File Types
|
||||
@@ -430,9 +426,18 @@ namespace BinaryObjectScanner
|
||||
#endif
|
||||
{
|
||||
// Try to create a wrapper for the proper executable type
|
||||
var wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
IWrapper? wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = WrapperFactory.CreateExecutableWrapper(stream);
|
||||
if (wrapper == null)
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (IncludeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
namespace BinaryObjectScanner.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Subset of file types that are supported by the library
|
||||
/// </summary>
|
||||
public enum SupportedFileType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown or unsupported
|
||||
/// </summary>
|
||||
UNKNOWN,
|
||||
|
||||
/// <summary>
|
||||
/// AACS media key block
|
||||
/// </summary>
|
||||
AACSMediaKeyBlock,
|
||||
|
||||
/// <summary>
|
||||
/// BD+ SVM
|
||||
/// </summary>
|
||||
BDPlusSVM,
|
||||
|
||||
/// <summary>
|
||||
/// BFPK custom archive
|
||||
/// </summary>
|
||||
BFPK,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life Level
|
||||
/// </summary>
|
||||
BSP,
|
||||
|
||||
/// <summary>
|
||||
/// bzip2 archive
|
||||
/// </summary>
|
||||
BZip2,
|
||||
|
||||
/// <summary>
|
||||
/// Compound File Binary
|
||||
/// </summary>
|
||||
CFB,
|
||||
|
||||
/// <summary>
|
||||
/// CTR Importable Archive
|
||||
/// </summary>
|
||||
CIA,
|
||||
|
||||
/// <summary>
|
||||
/// Executable or library
|
||||
/// </summary>
|
||||
Executable,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life Game Cache File
|
||||
/// </summary>
|
||||
GCF,
|
||||
|
||||
/// <summary>
|
||||
/// gzip archive
|
||||
/// </summary>
|
||||
GZIP,
|
||||
|
||||
/// <summary>
|
||||
/// Key-value pair INI file
|
||||
/// </summary>
|
||||
IniFile,
|
||||
|
||||
/// <summary>
|
||||
/// InstallShield archive v3
|
||||
/// </summary>
|
||||
InstallShieldArchiveV3,
|
||||
|
||||
/// <summary>
|
||||
/// InstallShield cabinet file
|
||||
/// </summary>
|
||||
InstallShieldCAB,
|
||||
|
||||
/// <summary>
|
||||
/// Link Data Security encrypted file
|
||||
/// </summary>
|
||||
LDSCRYPT,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft cabinet file
|
||||
/// </summary>
|
||||
MicrosoftCAB,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft LZ-compressed file
|
||||
/// </summary>
|
||||
MicrosoftLZ,
|
||||
|
||||
/// <summary>
|
||||
/// MPQ game data archive
|
||||
/// </summary>
|
||||
MPQ,
|
||||
|
||||
/// <summary>
|
||||
/// Nintendo 3DS cart image
|
||||
/// </summary>
|
||||
N3DS,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life No Cache File
|
||||
/// </summary>
|
||||
NCF,
|
||||
|
||||
/// <summary>
|
||||
/// Nintendo DS/DSi cart image
|
||||
/// </summary>
|
||||
Nitro,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life Package File
|
||||
/// </summary>
|
||||
PAK,
|
||||
|
||||
/// <summary>
|
||||
/// NovaLogic Game Archive Format
|
||||
/// </summary>
|
||||
PFF,
|
||||
|
||||
/// <summary>
|
||||
/// PKWARE ZIP archive and derivatives
|
||||
/// </summary>
|
||||
PKZIP,
|
||||
|
||||
/// <summary>
|
||||
/// PlayJ audio file
|
||||
/// </summary>
|
||||
PLJ,
|
||||
|
||||
/// <summary>
|
||||
/// Quantum archive
|
||||
/// </summary>
|
||||
Quantum,
|
||||
|
||||
/// <summary>
|
||||
/// RAR archive
|
||||
/// </summary>
|
||||
RAR,
|
||||
|
||||
/// <summary>
|
||||
/// RealArcade Installer
|
||||
/// </summary>
|
||||
RealArcadeInstaller,
|
||||
|
||||
/// <summary>
|
||||
/// RealArcade Mezzanine
|
||||
/// </summary>
|
||||
RealArcadeMezzanine,
|
||||
|
||||
/// <summary>
|
||||
/// 7-zip archive
|
||||
/// </summary>
|
||||
SevenZip,
|
||||
|
||||
/// <summary>
|
||||
/// StarForce FileSystem file
|
||||
/// </summary>
|
||||
SFFS,
|
||||
|
||||
/// <summary>
|
||||
/// SGA
|
||||
/// </summary>
|
||||
SGA,
|
||||
|
||||
/// <summary>
|
||||
/// Tape archive
|
||||
/// </summary>
|
||||
TapeArchive,
|
||||
|
||||
/// <summary>
|
||||
/// Various generic textfile formats
|
||||
/// </summary>
|
||||
Textfile,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life 2 Level
|
||||
/// </summary>
|
||||
VBSP,
|
||||
|
||||
/// <summary>
|
||||
/// Valve Package File
|
||||
/// </summary>
|
||||
VPK,
|
||||
|
||||
/// <summary>
|
||||
/// Half-Life Texture Package File
|
||||
/// </summary>
|
||||
WAD,
|
||||
|
||||
/// <summary>
|
||||
/// xz archive
|
||||
/// </summary>
|
||||
XZ,
|
||||
|
||||
/// <summary>
|
||||
/// Xbox Package File
|
||||
/// </summary>
|
||||
XZP,
|
||||
}
|
||||
}
|
||||
@@ -1,812 +0,0 @@
|
||||
using System;
|
||||
using SabreTools.Matching;
|
||||
|
||||
namespace BinaryObjectScanner.Utilities
|
||||
{
|
||||
public static class FileTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the supported file type for a magic string
|
||||
/// </summary>
|
||||
/// <remarks>Recommend sending in 16 bytes to check</remarks>
|
||||
public static SupportedFileType GetFileType(byte[] magic)
|
||||
{
|
||||
// If we have an invalid magic byte array
|
||||
if (magic == null || magic.Length == 0)
|
||||
return SupportedFileType.UNKNOWN;
|
||||
|
||||
// TODO: For all modelled types, use the constants instead of hardcoded values here
|
||||
#region AACSMediaKeyBlock
|
||||
|
||||
// Block starting with verify media key record
|
||||
if (magic.StartsWith(new byte?[] { 0x81, 0x00, 0x00, 0x14 }))
|
||||
return SupportedFileType.AACSMediaKeyBlock;
|
||||
|
||||
// Block starting with type and version record
|
||||
if (magic.StartsWith(new byte?[] { 0x10, 0x00, 0x00, 0x0C }))
|
||||
return SupportedFileType.AACSMediaKeyBlock;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BDPlusSVM
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x42, 0x44, 0x53, 0x56, 0x4D, 0x5F, 0x43, 0x43 }))
|
||||
return SupportedFileType.BDPlusSVM;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BFPK
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x42, 0x46, 0x50, 0x4b }))
|
||||
return SupportedFileType.BFPK;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BSP
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x1e, 0x00, 0x00, 0x00 }))
|
||||
return SupportedFileType.BSP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BZip2
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x42, 0x52, 0x68 }))
|
||||
return SupportedFileType.BZip2;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CFB
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CIA
|
||||
|
||||
// No magic checks for CIA
|
||||
|
||||
#endregion
|
||||
|
||||
#region Executable
|
||||
|
||||
// DOS MZ executable file format (and descendants)
|
||||
if (magic.StartsWith(new byte?[] { 0x4d, 0x5a }))
|
||||
return SupportedFileType.Executable;
|
||||
|
||||
/*
|
||||
// None of the following are supported in scans yet
|
||||
|
||||
// Executable and Linkable Format
|
||||
if (magic.StartsWith(new byte?[] { 0x7f, 0x45, 0x4c, 0x46 }))
|
||||
return FileTypes.Executable;
|
||||
|
||||
// Mach-O binary (32-bit)
|
||||
if (magic.StartsWith(new byte?[] { 0xfe, 0xed, 0xfa, 0xce }))
|
||||
return FileTypes.Executable;
|
||||
|
||||
// Mach-O binary (32-bit, reverse byte ordering scheme)
|
||||
if (magic.StartsWith(new byte?[] { 0xce, 0xfa, 0xed, 0xfe }))
|
||||
return FileTypes.Executable;
|
||||
|
||||
// Mach-O binary (64-bit)
|
||||
if (magic.StartsWith(new byte?[] { 0xfe, 0xed, 0xfa, 0xcf }))
|
||||
return FileTypes.Executable;
|
||||
|
||||
// Mach-O binary (64-bit, reverse byte ordering scheme)
|
||||
if (magic.StartsWith(new byte?[] { 0xcf, 0xfa, 0xed, 0xfe }))
|
||||
return FileTypes.Executable;
|
||||
|
||||
// Prefrred Executable File Format
|
||||
if (magic.StartsWith(new byte?[] { 0x4a, 0x6f, 0x79, 0x21, 0x70, 0x65, 0x66, 0x66 }))
|
||||
return FileTypes.Executable;
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region GCF
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }))
|
||||
return SupportedFileType.GCF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GZIP
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x1f, 0x8b }))
|
||||
return SupportedFileType.GZIP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region IniFile
|
||||
|
||||
// No magic checks for IniFile
|
||||
|
||||
#endregion
|
||||
|
||||
#region InstallShieldArchiveV3
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x13, 0x5D, 0x65, 0x8C }))
|
||||
return SupportedFileType.InstallShieldArchiveV3;
|
||||
|
||||
#endregion
|
||||
|
||||
#region InstallShieldCAB
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x49, 0x53, 0x63 }))
|
||||
return SupportedFileType.InstallShieldCAB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region LDSCRYPT
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x4C, 0x44, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54 }))
|
||||
return SupportedFileType.LDSCRYPT;
|
||||
|
||||
#endregion
|
||||
|
||||
#region MicrosoftCAB
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x4d, 0x53, 0x43, 0x46 }))
|
||||
return SupportedFileType.MicrosoftCAB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region MicrosoftLZ
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33 }))
|
||||
return SupportedFileType.MicrosoftLZ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region MPQ
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x4d, 0x50, 0x51, 0x1a }))
|
||||
return SupportedFileType.MPQ;
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x4d, 0x50, 0x51, 0x1b }))
|
||||
return SupportedFileType.MPQ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region N3DS
|
||||
|
||||
// No magic checks for N3DS
|
||||
|
||||
#endregion
|
||||
|
||||
#region NCF
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }))
|
||||
return SupportedFileType.NCF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nitro
|
||||
|
||||
// No magic checks for Nitro
|
||||
|
||||
#endregion
|
||||
|
||||
#region PAK
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x41, 0x43, 0x4B }))
|
||||
return SupportedFileType.PAK;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PFF
|
||||
|
||||
// Version 2
|
||||
if (magic.StartsWith(new byte?[] { 0x14, 0x00, 0x00, 0x00, 0x50, 0x46, 0x46, 0x32 }))
|
||||
return SupportedFileType.PFF;
|
||||
|
||||
// Version 3
|
||||
if (magic.StartsWith(new byte?[] { 0x14, 0x00, 0x00, 0x00, 0x50, 0x46, 0x46, 0x33 }))
|
||||
return SupportedFileType.PFF;
|
||||
|
||||
// Version 4
|
||||
if (magic.StartsWith(new byte?[] { 0x14, 0x00, 0x00, 0x00, 0x50, 0x46, 0x46, 0x34 }))
|
||||
return SupportedFileType.PFF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PKZIP
|
||||
|
||||
// PKZIP (Unknown)
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x00, 0x00 }))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// PKZIP
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x03, 0x04 }))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// PKZIP (Empty Archive)
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x05, 0x06 }))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// PKZIP (Spanned Archive)
|
||||
if (magic.StartsWith(new byte?[] { 0x50, 0x4b, 0x07, 0x08 }))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PLJ
|
||||
|
||||
// https://www.iana.org/assignments/media-types/audio/vnd.everad.plj
|
||||
if (magic.StartsWith(new byte?[] { 0xFF, 0x9D, 0x53, 0x4B }))
|
||||
return SupportedFileType.PLJ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Quantum
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x44, 0x53 }))
|
||||
return SupportedFileType.Quantum;
|
||||
|
||||
#endregion
|
||||
|
||||
#region RAR
|
||||
|
||||
// RAR archive version 1.50 onwards
|
||||
if (magic.StartsWith(new byte?[] { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }))
|
||||
return SupportedFileType.RAR;
|
||||
|
||||
// RAR archive version 5.0 onwards
|
||||
if (magic.StartsWith(new byte?[] { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00 }))
|
||||
return SupportedFileType.RAR;
|
||||
|
||||
#endregion
|
||||
|
||||
#region RealArcade
|
||||
|
||||
// RASGI2.0
|
||||
// Found in the ".rgs files in IA item "Nova_RealArcadeCD_USA".
|
||||
if (magic.StartsWith(new byte?[] { 0x52, 0x41, 0x53, 0x47, 0x49, 0x32, 0x2E, 0x30 }))
|
||||
return SupportedFileType.RealArcadeInstaller;
|
||||
|
||||
// XZip2.0
|
||||
// Found in the ".mez" files in IA item "Nova_RealArcadeCD_USA".
|
||||
if (magic.StartsWith(new byte?[] { 0x58, 0x5A, 0x69, 0x70, 0x32, 0x2E, 0x30 }))
|
||||
return SupportedFileType.RealArcadeMezzanine;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SevenZip
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c }))
|
||||
return SupportedFileType.SevenZip;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SFFS
|
||||
|
||||
// Found in Redump entry 81756, confirmed to be "StarForce Filesystem" by PiD.
|
||||
if (magic.StartsWith(new byte?[] { 0x53, 0x46, 0x46, 0x53 }))
|
||||
return SupportedFileType.SFFS;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SGA
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x5F, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45 }))
|
||||
return SupportedFileType.SGA;
|
||||
|
||||
#endregion
|
||||
|
||||
#region TapeArchive
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x75, 0x73, 0x74, 0x61, 0x72, 0x00, 0x30, 0x30 }))
|
||||
return SupportedFileType.TapeArchive;
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x75, 0x73, 0x74, 0x61, 0x72, 0x20, 0x20, 0x00 }))
|
||||
return SupportedFileType.TapeArchive;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Textfile
|
||||
|
||||
// Not all textfiles can be determined through magic number
|
||||
|
||||
// HTML
|
||||
if (magic.StartsWith(new byte?[] { 0x3c, 0x68, 0x74, 0x6d, 0x6c }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// HTML and XML
|
||||
if (magic.StartsWith(new byte?[] { 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45 }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// InstallShield Compiled Rules
|
||||
if (magic.StartsWith(new byte?[] { 0x61, 0x4C, 0x75, 0x5A }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Microsoft Office File (old)
|
||||
if (magic.StartsWith(new byte?[] { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Rich Text File
|
||||
if (magic.StartsWith(new byte?[] { 0x7b, 0x5c, 0x72, 0x74, 0x66, 0x31 }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Windows Help File
|
||||
if (magic.StartsWith(new byte?[] { 0x3F, 0x5F, 0x03, 0x00 }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// XML
|
||||
// "<?xml"
|
||||
if (magic.StartsWith(new byte?[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C }))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
#endregion
|
||||
|
||||
#region VBSP
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x56, 0x42, 0x53, 0x50 }))
|
||||
return SupportedFileType.VBSP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region VPK
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x34, 0x12, 0xaa, 0x55 }))
|
||||
return SupportedFileType.VPK;
|
||||
|
||||
#endregion
|
||||
|
||||
#region WAD
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x57, 0x41, 0x44, 0x33 }))
|
||||
return SupportedFileType.WAD;
|
||||
|
||||
#endregion
|
||||
|
||||
#region XZ
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00 }))
|
||||
return SupportedFileType.XZ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region XZP
|
||||
|
||||
if (magic.StartsWith(new byte?[] { 0x70, 0x69, 0x5A, 0x78 }))
|
||||
return SupportedFileType.XZP;
|
||||
|
||||
#endregion
|
||||
|
||||
// We couldn't find a supported match
|
||||
return SupportedFileType.UNKNOWN;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the supported file type for an extension
|
||||
/// </summary>
|
||||
/// <remarks>This is less accurate than a magic string match</remarks>
|
||||
public static SupportedFileType GetFileType(string extension)
|
||||
{
|
||||
// If we have an invalid extension
|
||||
if (string.IsNullOrEmpty(extension))
|
||||
return SupportedFileType.UNKNOWN;
|
||||
|
||||
// Normalize the extension
|
||||
extension = extension.TrimStart('.').Trim();
|
||||
|
||||
#region AACSMediaKeyBlock
|
||||
|
||||
// Shares an extension with INF setup information so it can't be used accurately
|
||||
// Blu-ray
|
||||
// if (extension.Equals("inf", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.AACSMediaKeyBlock;
|
||||
|
||||
// HD-DVD
|
||||
if (extension.Equals("aacs", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.AACSMediaKeyBlock;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BDPlusSVM
|
||||
|
||||
if (extension.Equals("svm", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.BDPlusSVM;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BFPK
|
||||
|
||||
// No extensions registered for BFPK
|
||||
|
||||
#endregion
|
||||
|
||||
#region BSP
|
||||
|
||||
// Shares an extension with VBSP so it can't be used accurately
|
||||
// if (extension.Equals("bsp", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.BSP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BZip2
|
||||
|
||||
if (extension.Equals("bz2", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.BZip2;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CFB
|
||||
|
||||
// Installer package
|
||||
if (extension.Equals("msi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Merge module
|
||||
else if (extension.Equals("msm", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Patch Package
|
||||
else if (extension.Equals("msp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Transform
|
||||
else if (extension.Equals("mst", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
// Patch Creation Properties
|
||||
else if (extension.Equals("pcp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CFB;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CIA
|
||||
|
||||
if (extension.Equals("cia", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.CIA;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Executable
|
||||
|
||||
// DOS MZ executable file format (and descendants)
|
||||
if (extension.Equals("exe", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Executable;
|
||||
|
||||
// DOS MZ library file format (and descendants)
|
||||
if (extension.Equals("dll", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Executable;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GCF
|
||||
|
||||
if (extension.Equals("gcf", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.GCF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GZIP
|
||||
|
||||
if (extension.Equals("gz", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.GZIP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region IniFile
|
||||
|
||||
if (extension.Equals("ini", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.IniFile;
|
||||
|
||||
#endregion
|
||||
|
||||
#region InstallShieldArchiveV3
|
||||
|
||||
if (extension.Equals("z", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.InstallShieldArchiveV3;
|
||||
|
||||
#endregion
|
||||
|
||||
#region InstallShieldCAB
|
||||
|
||||
// No extensions registered for InstallShieldCAB
|
||||
// Both InstallShieldCAB and MicrosoftCAB share the same extension
|
||||
|
||||
#endregion
|
||||
|
||||
#region MicrosoftCAB
|
||||
|
||||
// No extensions registered for InstallShieldCAB
|
||||
// Both InstallShieldCAB and MicrosoftCAB share the same extension
|
||||
|
||||
#endregion
|
||||
|
||||
#region MPQ
|
||||
|
||||
if (extension.Equals("mpq", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.MPQ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region N3DS
|
||||
|
||||
// 3DS cart image
|
||||
if (extension.Equals("3ds", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.N3DS;
|
||||
|
||||
// CIA package -- Not currently supported
|
||||
// else if (extension.Equals("cia", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.N3DS;
|
||||
|
||||
#endregion
|
||||
|
||||
#region NCF
|
||||
|
||||
if (extension.Equals("ncf", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.NCF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nitro
|
||||
|
||||
// DS cart image
|
||||
if (extension.Equals("nds", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Nitro;
|
||||
|
||||
// DS development cart image
|
||||
else if (extension.Equals("srl", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Nitro;
|
||||
|
||||
// DSi cart image
|
||||
else if (extension.Equals("dsi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Nitro;
|
||||
|
||||
// iQue DS cart image
|
||||
else if (extension.Equals("ids", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Nitro;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PAK
|
||||
|
||||
// No extensions registered for PAK
|
||||
// Both PAK and Quantum share one extension
|
||||
// if (extension.Equals("pak", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.PAK;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PFF
|
||||
|
||||
if (extension.Equals("pff", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PFF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PKZIP
|
||||
|
||||
// PKZIP
|
||||
if (extension.Equals("zip", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Android package
|
||||
if (extension.Equals("apk", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Java archive
|
||||
if (extension.Equals("jar", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Google Earth saved working session file
|
||||
if (extension.Equals("kmz", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// KWord document
|
||||
if (extension.Equals("kwd", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Microsoft Office Open XML Format (OOXML) Document
|
||||
if (extension.Equals("docx", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Microsoft Office Open XML Format (OOXML) Presentation
|
||||
if (extension.Equals("pptx", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Microsoft Office Open XML Format (OOXML) Spreadsheet
|
||||
if (extension.Equals("xlsx", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenDocument text document
|
||||
if (extension.Equals("odt", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenDocument presentation
|
||||
if (extension.Equals("odp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenDocument text document template
|
||||
if (extension.Equals("ott", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Microsoft Open XML paper specification file
|
||||
if (extension.Equals("oxps", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenOffice spreadsheet
|
||||
if (extension.Equals("sxc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenOffice drawing
|
||||
if (extension.Equals("sxd", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenOffice presentation
|
||||
if (extension.Equals("sxi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// OpenOffice word processing
|
||||
if (extension.Equals("sxw", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// StarOffice spreadsheet
|
||||
if (extension.Equals("sxc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Windows Media compressed skin file
|
||||
if (extension.Equals("wmz", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// Mozilla Browser Archive
|
||||
if (extension.Equals("xpi", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// XML paper specification file
|
||||
if (extension.Equals("xps", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
// eXact Packager Models
|
||||
if (extension.Equals("xpt", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PKZIP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PLJ
|
||||
|
||||
// https://www.iana.org/assignments/media-types/audio/vnd.everad.plj
|
||||
if (extension.Equals("plj", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.PLJ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Quantum
|
||||
|
||||
if (extension.Equals("q", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Quantum;
|
||||
|
||||
// Both PAK and Quantum share one extension
|
||||
// if (extension.Equals("pak", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.Quantum;
|
||||
|
||||
#endregion
|
||||
|
||||
#region RAR
|
||||
|
||||
if (extension.Equals("rar", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.RAR;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SevenZip
|
||||
|
||||
if (extension.Equals("7z", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.SevenZip;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SGA
|
||||
|
||||
if (extension.Equals("sga", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.SGA;
|
||||
|
||||
#endregion
|
||||
|
||||
#region TapeArchive
|
||||
|
||||
if (extension.Equals("tar", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.SevenZip;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Textfile
|
||||
|
||||
// "Description in Zip"
|
||||
if (extension.Equals("diz", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Generic textfile (no header)
|
||||
if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// HTML
|
||||
if (extension.Equals("htm", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
if (extension.Equals("html", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// InstallShield Script
|
||||
if (extension.Equals("ins", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Microsoft Office File (old)
|
||||
if (extension.Equals("doc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Property list
|
||||
if (extension.Equals("plist", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Rich Text File
|
||||
if (extension.Equals("rtf", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Setup information
|
||||
if (extension.Equals("inf", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// Windows Help File
|
||||
if (extension.Equals("hlp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// WZC
|
||||
if (extension.Equals("wzc", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
// XML
|
||||
if (extension.Equals("xml", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.Textfile;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region VBSP
|
||||
|
||||
// Shares an extension with BSP so it can't be used accurately
|
||||
// if (extension.Equals("bsp", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.VBSP;
|
||||
|
||||
#endregion
|
||||
|
||||
#region VPK
|
||||
|
||||
// Common extension so this cannot be used accurately
|
||||
// if (extension.Equals("vpk", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.VPK;
|
||||
|
||||
#endregion
|
||||
|
||||
#region WAD
|
||||
|
||||
// Common extension so this cannot be used accurately
|
||||
// if (extension.Equals("wad", StringComparison.OrdinalIgnoreCase))
|
||||
// return SupportedFileType.WAD;
|
||||
|
||||
#endregion
|
||||
|
||||
#region XZ
|
||||
|
||||
if (extension.Equals("xz", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.XZ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region XZP
|
||||
|
||||
if (extension.Equals("xzp", StringComparison.OrdinalIgnoreCase))
|
||||
return SupportedFileType.XZP;
|
||||
|
||||
#endregion
|
||||
|
||||
// We couldn't find a supported match
|
||||
return SupportedFileType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Utilities
|
||||
{
|
||||
public static class WrapperFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an instance of a wrapper based on file type
|
||||
/// </summary>
|
||||
public static IWrapper? CreateWrapper(SupportedFileType fileType, Stream? data)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case SupportedFileType.AACSMediaKeyBlock: return AACSMediaKeyBlock.Create(data);
|
||||
case SupportedFileType.BDPlusSVM: return BDPlusSVM.Create(data);
|
||||
case SupportedFileType.BFPK: return BFPK.Create(data);
|
||||
case SupportedFileType.BSP: return BSP.Create(data);
|
||||
//case SupportedFileType.BZip2: return BZip2.Create(data);
|
||||
case SupportedFileType.CFB: return CFB.Create(data);
|
||||
case SupportedFileType.CIA: return CIA.Create(data);
|
||||
case SupportedFileType.Executable: return CreateExecutableWrapper(data);
|
||||
case SupportedFileType.GCF: return GCF.Create(data);
|
||||
//case SupportedFileType.GZIP: return GZIP.Create(data);
|
||||
//case SupportedFileType.IniFile: return IniFile.Create(data);
|
||||
//case SupportedFileType.InstallShieldArchiveV3: return InstallShieldArchiveV3.Create(data);
|
||||
case SupportedFileType.InstallShieldCAB: return InstallShieldCabinet.Create(data);
|
||||
//case SupportedFileType.LDSCRYPT: return LDSCRYPT.Create(data);
|
||||
case SupportedFileType.MicrosoftCAB: return MicrosoftCabinet.Create(data);
|
||||
//case SupportedFileType.MicrosoftLZ: return MicrosoftLZ.Create(data);
|
||||
case SupportedFileType.MPQ: return MoPaQ.Create(data);
|
||||
case SupportedFileType.N3DS: return N3DS.Create(data);
|
||||
case SupportedFileType.NCF: return NCF.Create(data);
|
||||
case SupportedFileType.Nitro: return Nitro.Create(data);
|
||||
case SupportedFileType.PAK: return PAK.Create(data);
|
||||
case SupportedFileType.PFF: return PFF.Create(data);
|
||||
//case SupportedFileType.PIC: return PIC.Create(data);
|
||||
//case SupportedFileType.PKZIP: return PKZIP.Create(data);
|
||||
case SupportedFileType.PLJ: return PlayJAudioFile.Create(data);
|
||||
//case SupportedFileType.PLJPlaylist: return PlayJPlaylist.Create(data);
|
||||
case SupportedFileType.Quantum: return Quantum.Create(data);
|
||||
//case SupportedFileType.RAR: return RAR.Create(data);
|
||||
//case SupportedFileType.SevenZip: return SevenZip.Create(data);
|
||||
//case SupportedFileType.SFFS: return SFFS.Create(data);
|
||||
case SupportedFileType.SGA: return SGA.Create(data);
|
||||
//case SupportedFileType.TapeArchive: return TapeArchive.Create(data);
|
||||
//case SupportedFileType.Textfile: return Textfile.Create(data);
|
||||
case SupportedFileType.VBSP: return VBSP.Create(data);
|
||||
case SupportedFileType.VPK: return VPK.Create(data);
|
||||
case SupportedFileType.WAD: return WAD.Create(data);
|
||||
//case SupportedFileType.XZ: return XZ.Create(data);
|
||||
case SupportedFileType.XZP: return XZP.Create(data);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of a wrapper based on the executable type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream data to parse</param>
|
||||
/// <returns>IWrapper representing the executable, null on error</returns>
|
||||
public static IWrapper? CreateExecutableWrapper(Stream? stream)
|
||||
{
|
||||
// If we have no stream
|
||||
if (stream == null)
|
||||
return null;
|
||||
|
||||
// Try to get an MS-DOS wrapper first
|
||||
var wrapper = MSDOS.Create(stream);
|
||||
if (wrapper == null || !(wrapper is MSDOS msdos))
|
||||
return null;
|
||||
|
||||
// Check for a valid new executable address
|
||||
if (msdos.Model.Header?.NewExeHeaderAddr == null || msdos.Model.Header.NewExeHeaderAddr >= stream.Length)
|
||||
return wrapper;
|
||||
|
||||
// Try to read the executable info
|
||||
stream.Seek(msdos.Model.Header.NewExeHeaderAddr, SeekOrigin.Begin);
|
||||
var magic = stream.ReadBytes(4);
|
||||
|
||||
// If we didn't get valid data at the offset
|
||||
if (magic == null)
|
||||
{
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
// New Executable
|
||||
else if (magic.StartsWith(SabreTools.Models.NewExecutable.Constants.SignatureBytes))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return NewExecutable.Create(stream);
|
||||
}
|
||||
|
||||
// Linear Executable
|
||||
else if (magic.StartsWith(SabreTools.Models.LinearExecutable.Constants.LESignatureBytes)
|
||||
|| magic.StartsWith(SabreTools.Models.LinearExecutable.Constants.LXSignatureBytes))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return LinearExecutable.Create(stream);
|
||||
}
|
||||
|
||||
// Portable Executable
|
||||
else if (magic.StartsWith(SabreTools.Models.PortableExecutable.Constants.SignatureBytes))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return PortableExecutable.Create(stream);
|
||||
}
|
||||
|
||||
// Everything else fails
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
README.md
27
README.md
@@ -9,16 +9,16 @@ C# protection, packer, and archive scanning library. This currently compiles as
|
||||
The following non-project libraries (or ports thereof) are used for file handling:
|
||||
|
||||
- [LessIO](https://github.com/activescott/LessIO) - Used by libmspack4n for IO handling
|
||||
- [libmspack4n](https://github.com/activescott/libmspack4n) MS-CAB extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
|
||||
- [openmcdf](https://github.com/ironfede/openmcdf) - MSI extraction
|
||||
- [libmspack4n](https://github.com/activescott/libmspack4n) MS-CAB extraction [Unused in .NET Frawework 2.0/3.5/4.0, non-Windows, and non-x86 builds due to Windows-specific libraries]
|
||||
- [OpenMcdf](https://github.com/ironfede/openmcdf) - MSI extraction
|
||||
- [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction
|
||||
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
|
||||
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Frawework 2.0/3.5/4.0, non-Windows, and non-x86 builds due to Windows-specific libraries]
|
||||
- [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp) - InstallShield CAB extraction
|
||||
- [WiseUnpacker](https://github.com/mnadareski/WiseUnpacker) - Wise Installer extraction
|
||||
|
||||
The following projects have influenced this library:
|
||||
|
||||
- [BurnOut](http://burnout.sourceforge.net/) - Project that this library was initially based on. The only thing left from that original port is in the name of the library. This project is fully unaffiliated with the original BurnOut and its authors.
|
||||
- [BurnOut](http://burnout.sourceforge.net/) - Project that this library was initially based on. This project is fully unaffiliated with the original BurnOut and its authors.
|
||||
- [HLLibSharp](https://github.com/mnadareski/HLLibSharp) - Documentation around Valve package handling, including extraction.
|
||||
- [libbdplus](https://www.videolan.org/developers/libbdplus.html) - Documentation around the BD+ SVM files.
|
||||
- [libmspack](https://github.com/kyz/libmspack) - Documentation around the MS-CAB format and associated compression methods.
|
||||
@@ -26,6 +26,21 @@ The following projects have influenced this library:
|
||||
|
||||
Please visit our sibling project, [DRML](https://github.com/TheRogueArchivist/DRML), the DRM Library for a more in-depth look at some of the protections detected.
|
||||
|
||||
## Compatibility Notes
|
||||
|
||||
Binary Object Scanner strives to have both full compatibility for scanning across .NET versions as well as across OSes. Unfortunately, this is not always the case. Please see the below list for known compatibility issues.
|
||||
|
||||
- **7-zip archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
- **bzip2 archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
- **gzip archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
- **MS-CAB** - Extraction is only supported in Windows x86 builds running .NET Framework 4.5.2 and higher due to native DLL requirements
|
||||
- **MSI** - Extraction is only supported on .NET Framework 4.0 and higher due to `OpenMcdf` support limitations
|
||||
- **MoPaQ** - Extraction is only supported in Windows x86 builds running .NET Framework 4.5.2 and higher due to native DLL requirements
|
||||
- **PKZIP and derived files (ZIP, etc.)** - Extraction is only supported on .NET Framework 4.6.2 and higher
|
||||
- **RAR archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
- **Tape archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
- **xz archive** - Extraction is only supported on .NET Framework 4.6.2 and higher due to `SharpCompress` support limitations
|
||||
|
||||
## Protections Detected
|
||||
|
||||
Below is a list of protections detected by BinaryObjectScanner. The two columns explain what sort of checks are performed to determine how the protection is detected. Generally speaking, it's better to have a content check than a path check.
|
||||
@@ -187,9 +202,9 @@ Below is a list of container formats that are supported in some way:
|
||||
| InstallShield CAB | Yes | Yes | Yes | Via `UnshieldSharp` |
|
||||
| Linear Executable | No | No | No | Skeleton only |
|
||||
| Link Data Security encrypted file | No | Yes | No | |
|
||||
| Microsoft cabinet file | Yes | Yes | Yes | |
|
||||
| Microsoft cabinet file | Yes | Yes | Yes* | Via `libmspack4n`, Windows x86 only, .NET Framework 4.5.2 and above |
|
||||
| Microsoft LZ-compressed files | No | Yes | Yes | |
|
||||
| MoPaQ game data archive (MPQ) | No | Yes | Yes | Via `StormLibSharp` |
|
||||
| MoPaQ game data archive (MPQ) | No | Yes | Yes* | Via `StormLibSharp`, Windows x86 only, .NET Framework 4.5.2 and above |
|
||||
| MS-DOS Executable | Yes | Yes | No | Incomplete |
|
||||
| New Exectuable | Yes | Yes | No | Incomplete |
|
||||
| Nintendo 3DS cart image | Yes | Yes | No | |
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.IO;
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
using System.Text;
|
||||
#endif
|
||||
using BinaryObjectScanner.Utilities;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using OpenMcdf;
|
||||
#endif
|
||||
@@ -24,14 +23,43 @@ using UnshieldSharp.Archive;
|
||||
|
||||
namespace Test
|
||||
{
|
||||
internal static class Extractor
|
||||
internal class Extractor
|
||||
{
|
||||
#region Options
|
||||
|
||||
/// <inheritdoc cref="BinaryObjectScanner.Options.IncludeDebug"/>
|
||||
public bool IncludeDebug => _options?.IncludeDebug ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Options object for configuration
|
||||
/// </summary>
|
||||
private readonly BinaryObjectScanner.Options _options;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="includeDebug">Enable including debug information</param>
|
||||
public Extractor(bool includeDebug)
|
||||
{
|
||||
this._options = new BinaryObjectScanner.Options
|
||||
{
|
||||
IncludeDebug = includeDebug,
|
||||
};
|
||||
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
// Register the codepages
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper to extract data for a single path
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="outputDirectory">Output directory path</param>
|
||||
public static void ExtractPath(string path, string outputDirectory)
|
||||
public void ExtractPath(string path, string outputDirectory)
|
||||
{
|
||||
Console.WriteLine($"Checking possible path: {path}");
|
||||
|
||||
@@ -42,11 +70,7 @@ namespace Test
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
#if NET20 || NET35
|
||||
foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
|
||||
#else
|
||||
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
#endif
|
||||
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
ExtractFile(file, outputDirectory);
|
||||
}
|
||||
@@ -60,23 +84,36 @@ namespace Test
|
||||
/// <summary>
|
||||
/// Print information for a single file, if possible
|
||||
/// </summary>
|
||||
private static void ExtractFile(string file, string outputDirectory)
|
||||
private void ExtractFile(string file, string outputDirectory)
|
||||
{
|
||||
Console.WriteLine($"Attempting to extract all files from {file}");
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Read the first 8 bytes
|
||||
byte[]? magic = stream.ReadBytes(8);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
// Get the extension for certain checks
|
||||
string extension = Path.GetExtension(file).ToLower().TrimStart('.');
|
||||
|
||||
// Get the first 16 bytes for matching
|
||||
byte[] magic = new byte[16];
|
||||
try
|
||||
{
|
||||
stream.Read(magic, 0, 16);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (IncludeDebug) Console.WriteLine(ex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the file type
|
||||
SupportedFileType ft = FileTypes.GetFileType(magic ?? []);
|
||||
WrapperType ft = WrapperFactory.GetFileType(magic, extension);
|
||||
|
||||
// Executables technically can be "extracted", but let's ignore that
|
||||
// TODO: Support executables that include other stuff
|
||||
|
||||
// 7-zip
|
||||
if (ft == SupportedFileType.SevenZip)
|
||||
if (ft == WrapperType.SevenZip)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting 7-zip contents");
|
||||
@@ -122,7 +159,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// BFPK archive
|
||||
else if (ft == SupportedFileType.BFPK)
|
||||
else if (ft == WrapperType.BFPK)
|
||||
{
|
||||
// Build the BFPK information
|
||||
Console.WriteLine("Extracting BFPK contents");
|
||||
@@ -149,7 +186,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// BSP
|
||||
else if (ft == SupportedFileType.BSP)
|
||||
else if (ft == WrapperType.BSP)
|
||||
{
|
||||
// Build the BSP information
|
||||
Console.WriteLine("Extracting BSP contents");
|
||||
@@ -177,7 +214,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// bzip2
|
||||
else if (ft == SupportedFileType.BZip2)
|
||||
else if (ft == WrapperType.BZip2)
|
||||
{
|
||||
// Build the bzip2 information
|
||||
Console.WriteLine("Extracting bzip2 contents");
|
||||
@@ -205,7 +242,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// CFB
|
||||
else if (ft == SupportedFileType.CFB)
|
||||
else if (ft == WrapperType.CFB)
|
||||
{
|
||||
// Build the installer information
|
||||
Console.WriteLine("Extracting CFB contents");
|
||||
@@ -255,7 +292,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// GCF
|
||||
else if (ft == SupportedFileType.GCF)
|
||||
else if (ft == WrapperType.GCF)
|
||||
{
|
||||
// Build the GCF information
|
||||
Console.WriteLine("Extracting GCF contents");
|
||||
@@ -282,7 +319,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// gzip
|
||||
else if (ft == SupportedFileType.GZIP)
|
||||
else if (ft == WrapperType.GZIP)
|
||||
{
|
||||
// Build the gzip information
|
||||
Console.WriteLine("Extracting gzip contents");
|
||||
@@ -320,7 +357,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// InstallShield Archive V3 (Z)
|
||||
else if (ft == SupportedFileType.InstallShieldArchiveV3)
|
||||
else if (ft == WrapperType.InstallShieldArchiveV3)
|
||||
{
|
||||
// Build the InstallShield Archive V3 information
|
||||
Console.WriteLine("Extracting InstallShield Archive V3 contents");
|
||||
@@ -365,7 +402,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// IS-CAB archive
|
||||
else if (ft == SupportedFileType.InstallShieldCAB)
|
||||
else if (ft == WrapperType.InstallShieldCAB)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting IS-CAB contents");
|
||||
@@ -416,7 +453,7 @@ namespace Test
|
||||
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
// Microsoft Cabinet archive
|
||||
else if (ft == SupportedFileType.MicrosoftCAB)
|
||||
else if (ft == WrapperType.MicrosoftCAB)
|
||||
{
|
||||
// Build the cabinet information
|
||||
Console.WriteLine("Extracting MS-CAB contents");
|
||||
@@ -460,7 +497,7 @@ namespace Test
|
||||
#endif
|
||||
|
||||
// Microsoft LZ / LZ32
|
||||
else if (ft == SupportedFileType.MicrosoftLZ)
|
||||
else if (ft == WrapperType.MicrosoftLZ)
|
||||
{
|
||||
// Build the Microsoft LZ / LZ32 information
|
||||
Console.WriteLine("Extracting Microsoft LZ / LZ32 contents");
|
||||
@@ -501,7 +538,7 @@ namespace Test
|
||||
|
||||
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
|
||||
// MoPaQ (MPQ) archive
|
||||
else if (ft == SupportedFileType.MPQ)
|
||||
else if (ft == WrapperType.MoPaQ)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting MoPaQ contents");
|
||||
@@ -561,7 +598,7 @@ namespace Test
|
||||
#endif
|
||||
|
||||
// PAK
|
||||
else if (ft == SupportedFileType.PAK)
|
||||
else if (ft == WrapperType.PAK)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting PAK contents");
|
||||
@@ -588,7 +625,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// PFF
|
||||
else if (ft == SupportedFileType.PFF)
|
||||
else if (ft == WrapperType.PFF)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting PFF contents");
|
||||
@@ -615,7 +652,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// PKZIP
|
||||
else if (ft == SupportedFileType.PKZIP)
|
||||
else if (ft == WrapperType.PKZIP)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting PKZIP contents");
|
||||
@@ -664,7 +701,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// Quantum
|
||||
else if (ft == SupportedFileType.Quantum)
|
||||
else if (ft == WrapperType.Quantum)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting Quantum contents");
|
||||
@@ -691,7 +728,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// RAR
|
||||
else if (ft == SupportedFileType.RAR)
|
||||
else if (ft == WrapperType.RAR)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting RAR contents");
|
||||
@@ -737,7 +774,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// SGA
|
||||
else if (ft == SupportedFileType.SGA)
|
||||
else if (ft == WrapperType.SGA)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting SGA contents");
|
||||
@@ -764,7 +801,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// Tape Archive
|
||||
else if (ft == SupportedFileType.RAR)
|
||||
else if (ft == WrapperType.RAR)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting Tape Archive contents");
|
||||
@@ -810,7 +847,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// VBSP
|
||||
else if (ft == SupportedFileType.VBSP)
|
||||
else if (ft == WrapperType.VBSP)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting VBSP contents");
|
||||
@@ -837,7 +874,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// VPK
|
||||
else if (ft == SupportedFileType.VPK)
|
||||
else if (ft == WrapperType.VPK)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting VPK contents");
|
||||
@@ -864,7 +901,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// WAD
|
||||
else if (ft == SupportedFileType.WAD)
|
||||
else if (ft == WrapperType.WAD)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting WAD contents");
|
||||
@@ -891,7 +928,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// xz
|
||||
else if (ft == SupportedFileType.RAR)
|
||||
else if (ft == WrapperType.RAR)
|
||||
{
|
||||
// Build the xz information
|
||||
Console.WriteLine("Extracting xz contents");
|
||||
@@ -918,7 +955,7 @@ namespace Test
|
||||
}
|
||||
|
||||
// XZP
|
||||
else if (ft == SupportedFileType.XZP)
|
||||
else if (ft == WrapperType.XZP)
|
||||
{
|
||||
// Build the archive information
|
||||
Console.WriteLine("Extracting XZP contents");
|
||||
|
||||
@@ -1,20 +1,50 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
using System.Text;
|
||||
#endif
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Printing;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using SPrinter = SabreTools.Serialization.Printer;
|
||||
|
||||
namespace Test
|
||||
{
|
||||
internal static class Printer
|
||||
internal class Printer
|
||||
{
|
||||
#region Options
|
||||
|
||||
/// <inheritdoc cref="BinaryObjectScanner.Options.IncludeDebug"/>
|
||||
public bool IncludeDebug => _options?.IncludeDebug ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper to print information for a single path
|
||||
/// Options object for configuration
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="json">Enable JSON output, if supported</param>
|
||||
/// <param name="debug">Enable debug output</param>
|
||||
public static void PrintPathInfo(string path, bool json, bool debug)
|
||||
private readonly BinaryObjectScanner.Options _options;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="includeDebug">Enable including debug information</param>
|
||||
public Printer(bool includeDebug)
|
||||
{
|
||||
this._options = new BinaryObjectScanner.Options
|
||||
{
|
||||
IncludeDebug = includeDebug,
|
||||
};
|
||||
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
// Register the codepages
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
}/// <summary>
|
||||
/// Wrapper to print information for a single path
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="json">Enable JSON output, if supported</param>
|
||||
/// <param name="debug">Enable debug output</param>
|
||||
public void PrintPathInfo(string path, bool json, bool debug)
|
||||
{
|
||||
Console.WriteLine($"Checking possible path: {path}");
|
||||
|
||||
@@ -25,11 +55,7 @@ namespace Test
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
#if NET20 || NET35
|
||||
foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
|
||||
#else
|
||||
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
#endif
|
||||
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
PrintFileInfo(file, json, debug);
|
||||
}
|
||||
@@ -43,7 +69,7 @@ namespace Test
|
||||
/// <summary>
|
||||
/// Print information for a single file, if possible
|
||||
/// </summary>
|
||||
private static void PrintFileInfo(string file, bool json, bool debug)
|
||||
private void PrintFileInfo(string file, bool json, bool debug)
|
||||
{
|
||||
Console.WriteLine($"Attempting to print info for {file}");
|
||||
|
||||
@@ -51,17 +77,25 @@ namespace Test
|
||||
{
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Read the first 8 bytes
|
||||
byte[]? magic = stream.ReadBytes(8);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
// Get the extension for certain checks
|
||||
string extension = Path.GetExtension(file).ToLower().TrimStart('.');
|
||||
|
||||
// Get the first 16 bytes for matching
|
||||
byte[] magic = new byte[16];
|
||||
try
|
||||
{
|
||||
stream.Read(magic, 0, 16);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (IncludeDebug) Console.WriteLine(ex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the file type
|
||||
SupportedFileType ft = FileTypes.GetFileType(magic ?? []);
|
||||
if (ft == SupportedFileType.UNKNOWN)
|
||||
{
|
||||
string extension = Path.GetExtension(file).TrimStart('.');
|
||||
ft = FileTypes.GetFileType(extension);
|
||||
}
|
||||
WrapperType ft = WrapperFactory.GetFileType(magic, extension);
|
||||
|
||||
// Print out the file format
|
||||
Console.WriteLine($"File format found: {ft}");
|
||||
@@ -95,7 +129,7 @@ namespace Test
|
||||
#endif
|
||||
|
||||
// Create the output data
|
||||
var builder = wrapper.ExportStringBuilder();
|
||||
var builder = SPrinter.ExportStringBuilder(wrapper);
|
||||
if (builder == null)
|
||||
{
|
||||
Console.WriteLine("No item information could be generated");
|
||||
|
||||
@@ -28,6 +28,12 @@ namespace Test
|
||||
return;
|
||||
}
|
||||
|
||||
// Create extractor for all paths
|
||||
var extractor = new Extractor(options.Debug);
|
||||
|
||||
// Create printer for all paths
|
||||
var printer = new Printer(options.Debug);
|
||||
|
||||
// Create scanner for all paths
|
||||
var scanner = new Scanner(
|
||||
options.ScanArchives,
|
||||
@@ -43,14 +49,14 @@ namespace Test
|
||||
{
|
||||
// Extraction
|
||||
if (options.EnableExtraction)
|
||||
Extractor.ExtractPath(inputPath, options.OutputPath);
|
||||
extractor.ExtractPath(inputPath, options.OutputPath);
|
||||
|
||||
// Information printing
|
||||
if (options.EnableInformation)
|
||||
#if NETFRAMEWORK
|
||||
Printer.PrintPathInfo(inputPath, false, options.Debug);
|
||||
printer.PrintPathInfo(inputPath, false, options.Debug);
|
||||
#else
|
||||
Printer.PrintPathInfo(inputPath, options.Json, options.Debug);
|
||||
printer.PrintPathInfo(inputPath, options.Json, options.Debug);
|
||||
#endif
|
||||
|
||||
// Scanning
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.0" />
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.1" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.11" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.5" />
|
||||
<PackageReference Include="SabreTools.Printing" Version="1.3.8" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.5.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.6.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user