mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-02-05 05:37:34 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f5c1a8100 | ||
|
|
78cc67f30e | ||
|
|
5b78ba5621 | ||
|
|
c4734cfc3d | ||
|
|
dd45384226 | ||
|
|
3e75d9fa3b | ||
|
|
aa690ab602 | ||
|
|
7432100139 | ||
|
|
29fabb44eb | ||
|
|
ad776d4189 | ||
|
|
4cf12c76a8 | ||
|
|
39185f5ddd | ||
|
|
03477327c4 | ||
|
|
29fa0d1ac7 | ||
|
|
7eca23a7f3 | ||
|
|
f0c90bb332 |
@@ -11,7 +11,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>3.1.8</Version>
|
||||
<Version>3.1.12</Version>
|
||||
<!-- Mostly added due to external libraries -->
|
||||
<WarningsNotAsErrors>CS0162;CS0612;CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8618;CS8625;CS8634;CS8765;IL3000;NU5100</WarningsNotAsErrors>
|
||||
|
||||
@@ -75,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`))">
|
||||
@@ -85,11 +85,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.2.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.5" />
|
||||
<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.6.0" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.2" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.6.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.3" />
|
||||
<PackageReference Include="WiseUnpacker" Version="1.4.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -8,11 +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;
|
||||
|
||||
@@ -327,11 +330,7 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Get the file type either from magic number or extension
|
||||
WrapperType fileType = WrapperFactory.GetFileType(magic);
|
||||
if (fileType == WrapperType.UNKNOWN)
|
||||
fileType = WrapperFactory.GetFileType(extension);
|
||||
|
||||
// If we still got unknown, just return null
|
||||
WrapperType fileType = WrapperFactory.GetFileType(magic, extension);
|
||||
if (fileType == WrapperType.UNKNOWN)
|
||||
return null;
|
||||
|
||||
@@ -427,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
|
||||
|
||||
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}");
|
||||
|
||||
@@ -56,17 +84,30 @@ 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
|
||||
WrapperType ft = WrapperFactory.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
|
||||
|
||||
@@ -1,20 +1,50 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
using System.Text;
|
||||
#endif
|
||||
using SabreTools.IO.Extensions;
|
||||
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}");
|
||||
|
||||
@@ -39,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}");
|
||||
|
||||
@@ -47,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
|
||||
WrapperType ft = WrapperFactory.GetFileType(magic ?? []);
|
||||
if (ft == WrapperType.UNKNOWN)
|
||||
{
|
||||
string extension = Path.GetExtension(file).TrimStart('.');
|
||||
ft = WrapperFactory.GetFileType(extension);
|
||||
}
|
||||
WrapperType ft = WrapperFactory.GetFileType(magic, extension);
|
||||
|
||||
// Print out the file format
|
||||
Console.WriteLine($"File format found: {ft}");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Compression" Version="0.5.1" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.5" />
|
||||
<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.6.0" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.2" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.6.5" />
|
||||
<PackageReference Include="UnshieldSharp" Version="1.8.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user