Compare commits

..

16 Commits

Author SHA1 Message Date
Matt Nadareski
1f5c1a8100 Bump version 2024-05-18 22:12:35 -04:00
Matt Nadareski
78cc67f30e Update UnshieldSharp 2024-05-18 22:05:32 -04:00
Matt Nadareski
5b78ba5621 Bump version 2024-05-15 20:30:43 -04:00
Matt Nadareski
c4734cfc3d Update packages 2024-05-15 15:16:41 -04:00
Matt Nadareski
dd45384226 Add secondary check for WinZipSFX NE 2024-05-15 15:15:09 -04:00
Matt Nadareski
3e75d9fa3b Add safety around executable wrapper creation 2024-05-15 13:09:40 -04:00
Matt Nadareski
aa690ab602 Update packages 2024-05-15 12:24:40 -04:00
Matt Nadareski
7432100139 Bump version 2024-05-07 08:57:17 -04:00
Matt Nadareski
29fabb44eb Update IO and Serialization 2024-05-07 05:31:42 -04:00
Matt Nadareski
ad776d4189 Add explicit compatibility notes section 2024-05-06 22:40:39 -04:00
Matt Nadareski
4cf12c76a8 Update IO and Serialization 2024-05-06 22:30:58 -04:00
Matt Nadareski
39185f5ddd Remove now-irrelevant note 2024-05-06 21:59:37 -04:00
Matt Nadareski
03477327c4 Clearer in another place 2024-05-06 21:59:10 -04:00
Matt Nadareski
29fa0d1ac7 Clarify support 2024-05-06 21:54:45 -04:00
Matt Nadareski
7eca23a7f3 Bump version 2024-04-28 19:51:22 -04:00
Matt Nadareski
f0c90bb332 Update packages for critical issues 2024-04-28 19:50:53 -04:00
8 changed files with 162 additions and 51 deletions

View File

@@ -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>

View File

@@ -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)

View File

@@ -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

View File

@@ -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 | |

View File

@@ -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

View File

@@ -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}");

View File

@@ -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

View File

@@ -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>