Compare commits

...

40 Commits
3.1.3 ... 3.1.7

Author SHA1 Message Date
Matt Nadareski
3936a15ef7 Bump version 2024-04-24 17:08:16 -04:00
Matt Nadareski
f6dbb349c4 Update packages 2024-04-24 17:06:51 -04:00
Matt Nadareski
3c69e02cfc Update SabreTools.Serialization 2024-04-24 16:29:58 -04:00
Matt Nadareski
531e634e62 Version-gate a using statement 2024-04-24 14:43:28 -04:00
Matt Nadareski
f9c0c42b26 One Nuget packing error 2024-04-24 12:13:56 -04:00
Matt Nadareski
83aebbbfbd Maybe the last one? 2024-04-24 12:11:05 -04:00
Matt Nadareski
3847e5e9dc Even more warnings 2024-04-24 11:55:27 -04:00
Matt Nadareski
a72bb7e332 Yet more, plus an XML comment 2024-04-24 11:45:20 -04:00
Matt Nadareski
839791f467 Add a couple more for external 2024-04-24 11:43:09 -04:00
Matt Nadareski
469356e8c1 Suppress some "necessary" warnings 2024-04-24 11:35:09 -04:00
Matt Nadareski
66e8eb985c Bump version 2024-04-24 11:23:33 -04:00
Matt Nadareski
90223e6c94 Handle some warnings and messages 2024-04-24 11:16:03 -04:00
Matt Nadareski
2f2cf76d7b Update SabreTools.Printing 2024-04-24 11:15:51 -04:00
Matt Nadareski
558fee2200 Clean up using statements 2024-04-24 11:03:09 -04:00
Matt Nadareski
a82abc05ec Update packages 2024-04-24 11:01:10 -04:00
Matt Nadareski
74df37597a Slight cleanup to Scanner 2024-04-22 11:34:04 -04:00
Matt Nadareski
1581023c01 Update WiseUnpacker 2024-04-18 13:04:49 -04:00
Matt Nadareski
c0d1260656 Update UnshieldSharp 2024-04-18 12:58:32 -04:00
Matt Nadareski
969d103c2c Update packages 2024-04-18 12:48:44 -04:00
TheRogueArchivist
e5e3f3e3ef Add check for StarForce driver removal tool (#301) 2024-04-17 19:30:57 -04:00
Matt Nadareski
c1ee399262 Usings cleanup 2024-04-17 13:46:38 -04:00
Matt Nadareski
74ee9932a7 Update WrapperFactory a bit 2024-04-17 13:44:33 -04:00
Matt Nadareski
e70f8d7220 Reduce unncessary printing code 2024-04-17 13:41:00 -04:00
Matt Nadareski
ceba351372 Update packages 2024-04-17 13:38:14 -04:00
Matt Nadareski
ad4082c531 Forgot the name for playlist 2024-04-17 12:16:57 -04:00
Matt Nadareski
115ea02822 Update libraries 2024-04-17 12:12:01 -04:00
TheRogueArchivist
f876a4e4a6 Add RealArcade detection (#300) 2024-04-16 19:30:48 -04:00
TheRogueArchivist
be114f60d3 Fix WinZip SFX folders not being scanned (#299)
* Fix WinZip SFX folders not being scanned

Use PKZIP extraction to fix WinZip SFX extraction not extracting folders.

* Remove unneeded null check

* Add checks for incomplete zip entries
2024-04-15 00:18:00 -04:00
Matt Nadareski
b2594f8148 Update WiseUnpacker 2024-04-11 12:33:00 -04:00
TheRogueArchivist
f58ada3dde Fix Steam overmatch (#298) 2024-04-11 12:23:46 -04:00
TheRogueArchivist
bc4f07970d Minor Rainbow Sentinel improvements (#295) 2024-04-07 19:15:30 -04:00
Matt Nadareski
25d6822283 Bump version 2024-04-05 15:42:43 -04:00
Silent
3b22262c21 Update SecuROM v7 detection to correctly handle a partly stripped header (#297) 2024-04-04 15:00:09 -04:00
Matt Nadareski
314fc1e3fc Update SabreTools.Printing 2024-04-04 13:48:00 -04:00
Matt Nadareski
5742749dec Update packages 2024-04-04 12:12:52 -04:00
Silent
c55fffeb7b Fix a crash when a sharing violation occurs during --info (#296)
Prints an exception the same way GetInternalProtections
does.
2024-04-03 12:52:12 -07:00
TheRogueArchivist
e469dc38bf Fix Roxxe false positive (#294) 2024-04-02 21:57:23 -07:00
Matt Nadareski
553703c30e Bump version 2024-04-02 17:03:49 -04:00
Matt Nadareski
3fd093f9b4 Update packages 2024-04-02 16:37:02 -04:00
TheRogueArchivist
4946d4e7ff Add Roxxe detection (#293)
* Add Roxxe detection

* Fix Roxxe PR review comments
2024-04-01 09:14:13 -07:00
35 changed files with 572 additions and 525 deletions

View File

@@ -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.3</Version>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.7</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.36.0" />
<PackageReference Include="SharpCompress" Version="0.37.0" />
<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.4.0" />
<PackageReference Include="SabreTools.Compression" Version="0.5.0" />
<PackageReference Include="SabreTools.Hashing" Version="1.2.0" />
<PackageReference Include="SabreTools.IO" Version="1.3.2" />
<PackageReference Include="SabreTools.IO" Version="1.4.0" />
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
<PackageReference Include="SabreTools.Models" Version="1.4.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.4.1" />
<PackageReference Include="UnshieldSharp" Version="1.7.3" />
<PackageReference Include="WiseUnpacker" Version="1.3.1" />
<PackageReference Include="SabreTools.Models" Version="1.4.5" />
<PackageReference Include="SabreTools.Serialization" Version="1.5.6" />
<PackageReference Include="UnshieldSharp" Version="1.8.1" />
<PackageReference Include="WiseUnpacker" Version="1.4.1" />
</ItemGroup>
</Project>

View File

@@ -20,6 +20,8 @@ namespace BinaryObjectScanner
//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();
default: return null;

View File

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

View File

@@ -42,10 +42,14 @@ namespace BinaryObjectScanner.FileType
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -1,8 +1,6 @@
using System;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using UnshieldSharp.Archive;
namespace BinaryObjectScanner.FileType
{
@@ -31,16 +29,16 @@ namespace BinaryObjectScanner.FileType
Directory.CreateDirectory(tempPath);
UnshieldSharp.Archive.InstallShieldArchiveV3 archive = new UnshieldSharp.Archive.InstallShieldArchiveV3(file);
foreach (CompressedFile cfile in archive.Files.Select(kvp => kvp.Value))
foreach (var cfile in archive.Files)
{
try
{
string tempFile = Path.Combine(tempPath, cfile.FullPath!);
string tempFile = Path.Combine(tempPath, cfile.Key);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
(byte[]? fileContents, string? error) = archive.Extract(cfile.FullPath!);
(byte[]? fileContents, string? error) = archive.Extract(cfile.Key);
if (fileContents == null || !string.IsNullOrEmpty(error))
continue;

View File

@@ -59,21 +59,21 @@ namespace BinaryObjectScanner.FileType
Directory.CreateDirectory(tempPath);
var cabfile = InstallShieldCabinet.Open(file);
if (cabfile == null)
if (cabfile?.HeaderList == null)
return null;
for (int i = 0; i < cabfile.FileCount; i++)
for (int i = 0; i < cabfile.HeaderList.FileCount; i++)
{
try
{
// Check if the file is valid first
if (!cabfile.FileIsValid(i))
if (!cabfile.HeaderList.FileIsValid(i))
continue;
string tempFile;
try
{
string? filename = cabfile.FileName(i);
string? filename = cabfile.HeaderList.GetFileName(i);
tempFile = Path.Combine(tempPath, filename ?? string.Empty);
}
catch

View File

@@ -42,10 +42,18 @@ namespace BinaryObjectScanner.FileType
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
// If the entry is partial due to an incomplete multi-part archive, skip it
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))

View File

@@ -42,10 +42,14 @@ namespace BinaryObjectScanner.FileType
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -0,0 +1,48 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// RealArcade Installer. Known to use the ".rgs" file extension.
///
/// TODO: Add further parsing, game ID and name should be possible to parse.
/// </summary>
public class RealArcadeInstaller : IDetectable
{
/// <inheritdoc/>
public string? Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string? Detect(Stream stream, string file, bool includeDebug)
{
try
{
byte[] magic = new byte[16];
stream.Read(magic, 0, 16);
// 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 "RealArcade Installer";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// RealArcade Mezzanine files, which contain metadata. Known to use the ".mez" file extension.
///
/// TODO: Add further parsing, game ID should be possible to parse.
/// </summary>
public class RealArcadeMezzanine : IDetectable
{
/// <inheritdoc/>
public string? Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}
}
/// <inheritdoc/>
public string? Detect(Stream stream, string file, bool includeDebug)
{
try
{
byte[] magic = new byte[16];
stream.Read(magic, 0, 16);
// 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 "RealArcade Mezzanine";
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
return null;
}
}
}

View File

@@ -26,6 +26,9 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
if (stream == null)
return null;
#if NET462_OR_GREATER || NETCOREAPP
try
{
@@ -39,10 +42,14 @@ namespace BinaryObjectScanner.FileType
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -42,10 +42,14 @@ namespace BinaryObjectScanner.FileType
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -107,6 +107,11 @@ namespace BinaryObjectScanner.FileType
// Found in "SENTW95.HLP" and "SENTINEL.HLP" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Rainbow Sentinel Driver Help"))
protections.Add("Rainbow Sentinel");
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files\SNTNLUSB.INF" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
if (fileContent.Contains("SNTNLUSB.SvcDesc=\"Rainbow Security Device\""))
protections.Add("Rainbow Sentinel USB Driver");
if (fileContent.Contains("SntUsb95.SvcDesc=\"Rainbow Security Device\""))
protections.Add("Rainbow Sentinel USB Driver");
// Found in "OEMSETUP.INF" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Sentinel Driver Disk"))

View File

@@ -2,7 +2,7 @@ using System;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.IO;
using SabreTools.IO.Extensions;
namespace BinaryObjectScanner.FileType
{

View File

@@ -33,6 +33,10 @@ namespace BinaryObjectScanner.Packer
{
try
{
// If there are no resources
if (pex.ResourceData == null)
return null;
// Get the resources that have an executable signature
var resources = pex.ResourceData
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
@@ -57,11 +61,8 @@ namespace BinaryObjectScanner.Packer
tempFile = Path.Combine(tempPath, tempFile);
// Write the resource data to a temp file
using (var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
if (tempStream != null)
tempStream.Write(data, 0, data.Length);
}
using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
tempStream?.Write(data, 0, data.Length);
}
catch (Exception ex)
{

View File

@@ -51,10 +51,14 @@ namespace BinaryObjectScanner.Packer
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -73,29 +73,38 @@ namespace BinaryObjectScanner.Packer
/// <summary>
/// Handle common extraction between executable types
/// </summary>
private static string? Extract(string file, bool includeDebug)
/// <inheritdoc/>
public static string? Extract(string file, bool includeDebug)
{
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Should be using stream instead of file, but stream fails to extract anything. My guess is that the executable portion of the archive is causing stream to fail, but not file.
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (ZipArchive zipFile = ZipArchive.Open(file))
{
if (!zipFile.IsComplete)
return null;
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
foreach (var entry in zipFile.Entries)
{
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
// If we have a partial entry due to an incomplete multi-part archive, skip it
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(tempPath, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
entry.WriteToFile(tempFile);
}
catch (Exception ex)
@@ -103,9 +112,9 @@ namespace BinaryObjectScanner.Packer
if (includeDebug) Console.WriteLine(ex);
}
}
return tempPath;
}
return tempPath;
}
catch (Exception ex)
{

View File

@@ -3,10 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;
using Wise = WiseUnpacker.WiseUnpacker;
using WiseUnpacker;
using WiseUnpacker.EWISE;
namespace BinaryObjectScanner.Packer
{
@@ -81,8 +82,7 @@ namespace BinaryObjectScanner.Packer
try
{
// TODO: Try to find where the file data lives and how to get it
var unpacker = new Wise();
if (!unpacker.ExtractTo(file, tempPath))
if (!Extractor.ExtractTo(file, tempPath))
{
try
{
@@ -151,14 +151,14 @@ namespace BinaryObjectScanner.Packer
// Ensure that we have an archive end
if (format.ArchiveEnd > 0)
{
overlayOffset = dataStart + format.ArchiveEnd;
overlayOffset = (int)(dataStart + format.ArchiveEnd);
int archiveEndLoaded = overlayData.ReadInt32(ref overlayOffset);
if (archiveEndLoaded != 0)
format.ArchiveEnd = archiveEndLoaded;
}
// Skip to the start of the archive
overlayOffset = dataStart + format.ArchiveStart;
overlayOffset = (int)(dataStart + format.ArchiveStart);
// Skip over the initialization text, if we expect it
if (format.InitText)
@@ -190,8 +190,7 @@ namespace BinaryObjectScanner.Packer
// If we have DEFLATE -- TODO: Port implementation here or use DeflateStream
else
{
Wise unpacker = new Wise();
if (!unpacker.ExtractTo(file, tempPath))
if (!Extractor.ExtractTo(file, tempPath))
{
try
{
@@ -316,47 +315,5 @@ namespace BinaryObjectScanner.Packer
return null;
}
/// <summary>
/// Class representing the properties of each recognized Wise installer format
/// </summary>
/// TODO: Requires all fields to be writable in package before replacement
private class FormatProperty
{
/// <summary>
/// Offset to the executable data
/// </summary>
public int ExecutableOffset { get; set; }
/// <summary>
/// Indicates if this format includes a DLL at the start or not
/// </summary>
public bool Dll { get; set; }
/// <summary>
/// Offset within the data where the archive starts
/// </summary>
public int ArchiveStart { get; set; }
/// <summary>
/// Position in the archive head of the archive end
/// </summary>
public int ArchiveEnd { get; set; }
/// <summary>
/// Format includes initialization text
/// </summary>
public bool InitText { get; set; }
/// <summary>
/// Position of the filename within the data
/// </summary>
public int FilenamePosition { get; set; }
/// <summary>
/// Format does not include a CRC
/// </summary>
public bool NoCrc { get; set; }
}
}
}

View File

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

View File

@@ -7,7 +7,7 @@ using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Utilities;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;

View File

@@ -21,10 +21,11 @@ namespace BinaryObjectScanner.Protection
/// TODO: Investigate "sntnlusb.sys" (https://www.rainbow.com.my/document/endusertroubleshooting.pdf).
///
/// Versions:
/// Rainbow Sentinel PD-5.1: IA items "pcwkcd-1296" and "CHIPTRMart97".
/// Rainbow Sentinel PD-5.1: IA items "pcwkcd-1296, "CHIPTRMart97", and "bugcd199801".
/// Rainbow Sentinel PD-5.1e (Beta): IA item "CHIPTRMart97".
/// Rainbow Sentinel PD-5.37: File "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
/// Rainbow Sentinel PD-5.39: IA item "chip-cds-2001-08".
/// Rainbow Sentinel PD-15: IA items "ASMEsMechanicalEngineeringToolkit1997December" and "aplicaciones-windows".
/// Rainbow Sentinel PD-15: IA items "ASMEsMechanicalEngineeringToolkit1997December", "aplicaciones-windows", and "ASMEsMechanicalEngineeringToolkit1997December".
/// Rainbow Sentinel PD-17: IA item "czchip199707cd".
/// Rainbow Sentinel PD-30: BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
/// Rainbow Sentinel PD-31: BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
@@ -172,6 +173,11 @@ namespace BinaryObjectScanner.Protection
if (name?.Equals("NetSentinel Server for WIN 32", StringComparison.OrdinalIgnoreCase) == true)
return "Rainbow NetSentinel Server for Win32";
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files\SNTNLUSB.SYS" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
// TODO: Check if the version included with this is useful.
if (name?.Equals("Rainbow Technologies Sentinel Device Driver", StringComparison.OrdinalIgnoreCase) == true)
return "Rainbow Sentinel Driver";
name = pex.ProductName;
// Found in multiple files in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", including "RNBOVTMP.DLL", "SENTTEMP.DLL", and "SNTI386.DLL".
@@ -194,6 +200,11 @@ namespace BinaryObjectScanner.Protection
if (name?.Equals("Sentinel System Driver", StringComparison.OrdinalIgnoreCase) == true)
return $"Rainbow Sentinel {pex.ProductVersion}";
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files\SNTNLUSB.SYS" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
// TODO: Check if the version included with this is useful.
if (name?.Equals("Rainbow Technologies USB Security Device Driver", StringComparison.OrdinalIgnoreCase) == true)
return "Rainbow Sentinel Driver";
// Get the .data/DATA section strings, if they exist
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
@@ -330,6 +341,15 @@ namespace BinaryObjectScanner.Protection
new(new FilePathMatch("NSRVOM.EXE"), "Rainbow NetSentinel Server for OS/2"),
new(new FilePathMatch("NSRVGX.EXE"), "Rainbow NetSentinel Server for Win32"),
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
// TODO: Add text file checks for these IFX files.
new(new FilePathMatch("SNTNLUSB.IFX"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTNLUSB.INF"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTNLUSB.SYS"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.IFX"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.INF"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.SYS"), "Rainbow Sentinel USB Driver"),
// Found in IA item "czchip199707cd".
new(new List<PathMatch>
{
@@ -422,6 +442,15 @@ namespace BinaryObjectScanner.Protection
new(new FilePathMatch("SNTMIPS.DLL"), "Rainbow Sentinel Windows NT MIPS Platform Driver"),
new(new FilePathMatch("SNTPPC.DLL"), "Rainbow Sentinel Windows NT PowerPC Platform Driver"),
// Found in "\disc4\cad\sdcc_200.zip\DISK1\_USER1.HDR\Language_Independent_Intel_32_Files" in "CICA 32 For Windows CD-ROM (Walnut Creek) (October 1999) (Disc 4).iso" in IA item "CICA_32_For_Windows_CD-ROM_Walnut_Creek_October_1999".
// TODO: Add text file checks for these IFX files.
new(new FilePathMatch("SNTNLUSB.IFX"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTNLUSB.INF"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTNLUSB.SYS"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.IFX"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.INF"), "Rainbow Sentinel USB Driver"),
new(new FilePathMatch("SNTUSB95.SYS"), "Rainbow Sentinel USB Driver"),
// Found in IA item "chip-cds-2001-08".
// File names for Rainbow Sentinel files sometimes found in ".cab" files.
new(new FilePathMatch("F194_rnbovdd.dll.B391C188_6953_11D4_82CB_00D0B72E1DB9"), "Rainbow Sentinel"),

View File

@@ -0,0 +1,75 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;
namespace BinaryObjectScanner.Protection
{
/// <summary>
/// RealArcade was a game platform that allowed users to play timed demos of games, and then prompted them to purchase the game in order to play the game without a limit.
/// Although the servers are long dead, there is a community project actively being developed to allow users to properly download and play these games.
/// Links:
/// https://github.com/lightbulbatelier/RealArcade-DGA
/// https://archive.org/details/realrcade-games-preservation-project
/// </summary>
public class RealArcade : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data section strings, if they exist
var strs = pex.GetFirstSectionStrings(".data");
if (strs != null)
{
// Found in "rebound.exe" in the installation directory for "Rebound" in IA item "Nova_RealArcadeCD_USA".
if (strs.Any(s => s.Contains("RngInterstitialDLL")))
return "RealArcade";
}
// Found in "RngInterstitial.dll" in the RealArcade installation directory in IA item "Nova_RealArcadeCD_USA".
var name = pex.FileDescription;
if (name?.Contains("RngInterstitial") == true)
return "RealArcade";
return null;
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
// ".rgs" and ".mez" files are also associated with RealArcade.
new(new FilePathMatch("RngInterstitial.dll"), "RealArcade"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
public string? CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// ".rgs" and ".mez" files are also associated with RealArcade.
new(new FilePathMatch("RngInterstitial.dll"), "RealArcade"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;
namespace BinaryObjectScanner.Protection
{
/// <summary>
/// Roxxe was a Czech DRM. It appears to have been a simple disc check that also relied on unusual disc manufacturing and dummy files to attempt to prevent copying.
///
/// DRML: https://github.com/TheRogueArchivist/DRML/blob/main/entries/Roxxe/Roxxe.md
/// </summary>
public class Roxxe : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the code/CODE section strings, if they exist
var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
if (strs != null)
{
// Found in "Owar.exe" in IA item "game4u-22-cd".
if (strs.Any(s => s.Contains("TRCHANGER.INI")))
return "Roxxe";
}
// Get the .rsrc section strings, if they exist
// TODO: Check for these strings specifically within the application-defined resource that they're found in, not just the generic resource section.
strs = pex.GetFirstSectionStrings(".rsrc");
if (strs != null)
{
// Found in "Owar.exe" in IA items "game4u-22-cd" and "original-war".
// These checks are less reliable, as they are still found in a version of the game that appears to have patched out Roxxe (the version present in IA item "original-war").
if (strs.Any(s => s.Contains("PRRT01")))
return "Roxxe (Possibly remnants)";
if (strs.Any(s => s.Contains("CommonPRRT")))
return "Roxxe (Possibly remnants)";
// Currently overmatches, will likely be a viable check when better Delphi executable parsing is available.
// if (strs.Any(s => s.Contains("roxe")))
// return "Roxxe (Possibly remnants)";
}
return null;
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
// Files such as "TRCHANGER.INI" may be present, but haven't been found yet.
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
public string? CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// Files such as "TRCHANGER.INI" may be present, but haven't been found yet.
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -226,31 +226,40 @@ namespace BinaryObjectScanner.Protection
// These live in the MS-DOS stub, for some reason
private static string GetV7Version(PortableExecutable pex)
{
int index = 172; // 64 bytes for DOS stub, 236 bytes in total
try
{
int index = 172; // 64 bytes for DOS stub, 236 bytes in total
#if NETFRAMEWORK
byte[] bytes = new byte[4];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 4);
byte[] bytes = new byte[4];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 4);
#else
byte[] bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 4).ToArray();
byte[] bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 4).ToArray();
#endif
//SecuROM 7 new and 8
if (bytes[3] == 0x5C) // if (bytes[0] == 0xED && bytes[3] == 0x5C {
{
return $"{bytes[0] ^ 0xEA}.{bytes[1] ^ 0x2C:00}.{bytes[2] ^ 0x8:0000}";
//SecuROM 7 new and 8
if (bytes[3] == 0x5C) // if (bytes[0] == 0xED && bytes[3] == 0x5C {
{
return $"{bytes[0] ^ 0xEA}.{bytes[1] ^ 0x2C:00}.{bytes[2] ^ 0x8:0000}";
}
// SecuROM 7 old
else
{
index = 58; // 64 bytes for DOS stub, 122 bytes in total
#if NETFRAMEWORK
bytes = new byte[2];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 2);
#else
bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 2).ToArray();
#endif
return $"7.{bytes[0] ^ 0x10:00}.{bytes[1] ^ 0x10:0000}"; //return "7.01-7.10"
}
}
// SecuROM 7 old
else
catch (ArgumentException)
{
index = 58; // 64 bytes for DOS stub, 122 bytes in total
#if NETFRAMEWORK
bytes = new byte[2];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 2);
#else
bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 2).ToArray();
#endif
return $"7.{bytes[0] ^ 0x10:00}.{bytes[1] ^ 0x10:0000}"; //return "7.01-7.10"
// If SecuROM is stripped, the MS-DOS stub might be shorter.
// We then know that SecuROM -was- there, but we don't know what exact version.
return "7 remnants";
}
}

View File

@@ -27,7 +27,35 @@ namespace BinaryObjectScanner.Protection
if (sections == null)
return null;
var name = pex.LegalCopyright;
// TODO: Find what fvinfo field actually maps to this
var name = pex.FileDescription;
// There are some File Description checks that are currently too generic to use.
// "Host Library" - Found in "protect.dll" in Redump entry 81756.
// "User Interface Application" - Found in "protect.exe" in Redump entry 81756.
// "Helper Application" - Found in "protect.x64" and "protect.x86" in Redump entry 81756.
// Found in "sfdrvrem.exe" in Redump entry 102677.
if (name?.Contains("FrontLine Drivers Removal Tool") == true)
return $"StarForce FrontLine Driver Removal Tool";
// Found in "protect.exe" in Redump entry 94805.
if (name?.Contains("FrontLine Protection GUI Application") == true)
return $"StarForce {pex.GetInternalVersion()}";
// Found in "protect.dll" in Redump entry 94805.
if (name?.Contains("FrontLine Protection Library") == true)
return $"StarForce {pex.GetInternalVersion()}";
// Found in "protect.x64" and "protect.x86" in Redump entry 94805.
if (name?.Contains("FrontLine Helper") == true)
return $"StarForce {pex.GetInternalVersion()}";
// TODO: Find a sample of this check.
if (name?.Contains("Protected Module") == true)
return $"StarForce 5";
name = pex.LegalCopyright;
if (name?.StartsWith("(c) Protection Technology") == true) // (c) Protection Technology (StarForce)?
return $"StarForce {pex.GetInternalVersion()}";
else if (name?.Contains("Protection Technology") == true) // Protection Technology (StarForce)?
@@ -61,30 +89,6 @@ namespace BinaryObjectScanner.Protection
return $"StarForce {pex.GetInternalVersion()}";
}
// TODO: Find what fvinfo field actually maps to this
name = pex.FileDescription;
// There are some File Description checks that are currently too generic to use.
// "Host Library" - Found in "protect.dll" in Redump entry 81756.
// "User Interface Application" - Found in "protect.exe" in Redump entry 81756.
// "Helper Application" - Found in "protect.x64" and "protect.x86" in Redump entry 81756.
// Found in "protect.exe" in Redump entry 94805.
if (name?.Contains("FrontLine Protection GUI Application") == true)
return $"StarForce {pex.GetInternalVersion()}";
// Found in "protect.dll" in Redump entry 94805.
if (name?.Contains("FrontLine Protection Library") == true)
return $"StarForce {pex.GetInternalVersion()}";
// Found in "protect.x64" and "protect.x86" in Redump entry 94805.
if (name?.Contains("FrontLine Helper") == true)
return $"StarForce {pex.GetInternalVersion()}";
// TODO: Find a sample of this check.
if (name?.Contains("Protected Module") == true)
return $"StarForce 5";
// TODO: Check to see if there are any missing checks
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/StarForce.2.sg

View File

@@ -55,7 +55,8 @@ namespace BinaryObjectScanner.Protection
new(new List<PathMatch>
{
// TODO: Identify based on "Steam(TM)" being present in "Description" but not in "File Description".
new FilePathMatch("steam.exe"),
// Overmatches on some files, such as IA item "ASMEsMechanicalEngineeringToolkit1997December".
// new FilePathMatch("steam.exe"),
new FilePathMatch("steam.ini"),

View File

@@ -5,7 +5,9 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
#if NET462_OR_GREATER || NETCOREAPP
using System.Text;
#endif
using System.Threading.Tasks;
using BinaryObjectScanner.FileType;
using BinaryObjectScanner.Interfaces;
@@ -92,7 +94,7 @@ namespace BinaryObjectScanner
public ConcurrentDictionary<string, ConcurrentQueue<string>>? GetProtections(string path)
#endif
{
return GetProtections(new List<string> { path });
return GetProtections([path]);
}
/// <summary>

View File

@@ -140,6 +140,16 @@
/// </summary>
RAR,
/// <summary>
/// RealArcade Installer
/// </summary>
RealArcadeInstaller,
/// <summary>
/// RealArcade Mezzanine
/// </summary>
RealArcadeMezzanine,
/// <summary>
/// 7-zip archive
/// </summary>

View File

@@ -259,6 +259,20 @@ namespace BinaryObjectScanner.Utilities
#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 }))

View File

@@ -1,5 +1,5 @@
using System.IO;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Matching;
using SabreTools.Serialization.Interfaces;
using SabreTools.Serialization.Wrappers;
@@ -31,14 +31,16 @@ namespace BinaryObjectScanner.Utilities
//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.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);
@@ -67,7 +69,7 @@ namespace BinaryObjectScanner.Utilities
return null;
// Try to get an MS-DOS wrapper first
IWrapper? wrapper = MSDOS.Create(stream);
var wrapper = MSDOS.Create(stream);
if (wrapper == null || !(wrapper is MSDOS msdos))
return null;

View File

@@ -1,4 +1,4 @@
# BinaryObjectScanner
# Binary Object Scanner
[![Build status](https://ci.appveyor.com/api/projects/status/gmdft5bk1h8a1c31?svg=true)](https://ci.appveyor.com/project/mnadareski/BinaryObjectScanner)
[![Build Test](https://github.com/SabreTools/BinaryObjectScanner/actions/workflows/build_test.yml/badge.svg)](https://github.com/SabreTools/BinaryObjectScanner/actions/workflows/build_test.yml)
@@ -92,8 +92,10 @@ Below is a list of protections detected by BinaryObjectScanner. The two columns
| Protect DVD-Video | False | True | Unconfirmed¹ |
| PlayStation Anti-modchip | True | False | En/Jp, not "Red Hand"; PSX executables only |
| Rainbow Sentinel | True | True | |
| RealArcade | True | True | |
| Ring PROTECH / ProRing | True | True | Partially unconfirmed² |
| RipGuard | True | True | Partially unconfirmed² |
| Roxxe | True | False | |
| SafeDisc / SafeCast | True | True | Can't distinguish between some versions of SafeDisc and SafeCast |
| SafeLock | False | True | |
| SecuROM | True | True | v8.x and White Label detected partially² |

View File

@@ -1,12 +1,13 @@
using System;
using System.IO;
using System.Linq;
#if NET452_OR_GREATER || NETCOREAPP
using System.Text;
#endif
using BinaryObjectScanner.Utilities;
#if NET40_OR_GREATER || NETCOREAPP
using OpenMcdf;
#endif
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Serialization.Wrappers;
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
@@ -20,7 +21,6 @@ using SharpCompress.Compressors.BZip2;
using SharpCompress.Compressors.Xz;
#endif
using UnshieldSharp.Archive;
using UnshieldSharp.Cabinet;
namespace Test
{
@@ -95,10 +95,14 @@ namespace Test
// If an individual entry fails
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(outputDirectory, entry.Key);
entry.WriteToFile(tempFile);
}
@@ -294,10 +298,14 @@ namespace Test
// If an individual entry fails
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(outputDirectory, entry.Key);
entry.WriteToFile(tempFile);
}
@@ -322,17 +330,17 @@ namespace Test
try
{
var archive = new InstallShieldArchiveV3(file);
foreach (var cfile in archive.Files.Select(kvp => kvp.Value))
foreach (var cfile in archive.Files)
{
// If an individual entry fails
try
{
string tempFile = Path.Combine(outputDirectory, cfile.FullPath ?? string.Empty);
string tempFile = Path.Combine(outputDirectory, cfile.Key);
string? directoryName = Path.GetDirectoryName(tempFile);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
(byte[]? fileContents, string? error) = archive.Extract(cfile.FullPath ?? string.Empty);
(byte[]? fileContents, string? error) = archive.Extract(cfile.Key);
if (!string.IsNullOrEmpty(error))
continue;
@@ -344,7 +352,7 @@ namespace Test
}
catch (Exception ex)
{
Console.WriteLine($"Something went wrong extracting InstallShield Archive V3 entry {cfile.Name}: {ex}");
Console.WriteLine($"Something went wrong extracting InstallShield Archive V3 entry {cfile.Value.Name}: {ex}");
Console.WriteLine();
}
}
@@ -367,12 +375,19 @@ namespace Test
try
{
var cabfile = UnshieldSharp.Cabinet.InstallShieldCabinet.Open(file);
for (int i = 0; i < (cabfile?.FileCount ?? 0); i++)
if (cabfile?.HeaderList == null)
{
Console.WriteLine("Something went wrong parsing IS-CAB archive");
Console.WriteLine();
return;
}
for (int i = 0; i < cabfile!.HeaderList.FileCount; i++)
{
// If an individual entry fails
try
{
string? filename = cabfile?.FileName(i);
string? filename = cabfile.HeaderList.GetFileName(i);
string tempFile;
try
{
@@ -619,10 +634,14 @@ namespace Test
// If an individual entry fails
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(outputDirectory, entry.Key);
string? directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null)
@@ -691,10 +710,14 @@ namespace Test
// If an individual entry fails
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(outputDirectory, entry.Key);
entry.WriteToFile(tempFile);
}
@@ -760,10 +783,14 @@ namespace Test
// If an individual entry fails
try
{
// If we have a directory, skip it
// If the entry is a directory
if (entry.IsDirectory)
continue;
// If the entry has an invalid key
if (entry.Key == null)
continue;
string tempFile = Path.Combine(outputDirectory, entry.Key);
entry.WriteToFile(tempFile);
}

View File

@@ -1,10 +1,8 @@
using System;
using System.IO;
using System.Text;
using BinaryObjectScanner.Utilities;
using SabreTools.IO;
using SabreTools.Serialization.Interfaces;
using SabreTools.Serialization.Wrappers;
using SabreTools.IO.Extensions;
using SabreTools.Printing;
namespace Test
{
@@ -49,39 +47,38 @@ namespace Test
{
Console.WriteLine($"Attempting to print info for {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 file type
SupportedFileType ft = FileTypes.GetFileType(magic ?? []);
if (ft == SupportedFileType.UNKNOWN)
try
{
string extension = Path.GetExtension(file).TrimStart('.');
ft = FileTypes.GetFileType(extension);
}
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Print out the file format
Console.WriteLine($"File format found: {ft}");
// Read the first 8 bytes
byte[]? magic = stream.ReadBytes(8);
stream.Seek(0, SeekOrigin.Begin);
// Setup the wrapper to print
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// Get the file type
SupportedFileType ft = FileTypes.GetFileType(magic ?? []);
if (ft == SupportedFileType.UNKNOWN)
{
string extension = Path.GetExtension(file).TrimStart('.');
ft = FileTypes.GetFileType(extension);
}
// If we don't have a wrapper
if (wrapper == null)
{
Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!");
Console.WriteLine();
return;
}
// Print out the file format
Console.WriteLine($"File format found: {ft}");
// Print the wrapper name
Console.WriteLine($"{wrapper.Description()} wrapper created successfully!");
// Setup the wrapper to print
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// Get the base info output name
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
// If we don't have a wrapper
if (wrapper == null)
{
Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!");
Console.WriteLine();
return;
}
// Get the base info output name
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
#if NET6_0_OR_GREATER
// If we have the JSON flag
@@ -96,336 +93,25 @@ namespace Test
jsw.WriteLine(serializedData);
}
#endif
// Create the output data
var builder = wrapper.PrettyPrint();
Console.WriteLine(builder);
// Write the output data
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
sw.WriteLine(builder.ToString());
}
// Create the output data
var builder = wrapper.ExportStringBuilder();
if (builder == null)
{
Console.WriteLine("No item information could be generated");
return;
}
#region Printing Implementations
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this IWrapper wrapper)
{
return wrapper switch
// Write the output data
Console.WriteLine(builder);
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
sw.WriteLine(builder.ToString());
}
catch (Exception ex)
{
AACSMediaKeyBlock item => item.PrettyPrint(),
BDPlusSVM item => item.PrettyPrint(),
BFPK item => item.PrettyPrint(),
BSP item => item.PrettyPrint(),
CFB item => item.PrettyPrint(),
CIA item => item.PrettyPrint(),
GCF item => item.PrettyPrint(),
InstallShieldCabinet item => item.PrettyPrint(),
IRD item => item.PrettyPrint(),
LinearExecutable item => item.PrettyPrint(),
MicrosoftCabinet item => item.PrettyPrint(),
MSDOS item => item.PrettyPrint(),
N3DS item => item.PrettyPrint(),
NCF item => item.PrettyPrint(),
NewExecutable item => item.PrettyPrint(),
Nitro item => item.PrettyPrint(),
PAK item => item.PrettyPrint(),
PFF item => item.PrettyPrint(),
PlayJAudioFile item => item.PrettyPrint(),
PortableExecutable item => item.PrettyPrint(),
Quantum item => item.PrettyPrint(),
SGA item => item.PrettyPrint(),
VBSP item => item.PrettyPrint(),
VPK item => item.PrettyPrint(),
WAD item => item.PrettyPrint(),
XeMID item => item.PrettyPrint(),
XMID item => item.PrettyPrint(),
XZP item => item.PrettyPrint(),
_ => new StringBuilder(),
};
Console.WriteLine(debug ? ex : "[Exception opening file, please try again]");
Console.WriteLine();
}
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this AACSMediaKeyBlock item)
{
var builder = new StringBuilder();
SabreTools.Printing.AACSMediaKeyBlock.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this BDPlusSVM item)
{
var builder = new StringBuilder();
SabreTools.Printing.BDPlusSVM.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this BFPK item)
{
var builder = new StringBuilder();
SabreTools.Printing.BFPK.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this BSP item)
{
var builder = new StringBuilder();
SabreTools.Printing.BSP.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this CFB item)
{
var builder = new StringBuilder();
SabreTools.Printing.CFB.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this CIA item)
{
var builder = new StringBuilder();
SabreTools.Printing.CIA.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this GCF item)
{
var builder = new StringBuilder();
SabreTools.Printing.GCF.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this InstallShieldCabinet item)
{
var builder = new StringBuilder();
SabreTools.Printing.InstallShieldCabinet.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this IRD item)
{
var builder = new StringBuilder();
SabreTools.Printing.IRD.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this LinearExecutable item)
{
var builder = new StringBuilder();
SabreTools.Printing.LinearExecutable.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this MicrosoftCabinet item)
{
var builder = new StringBuilder();
SabreTools.Printing.MicrosoftCabinet.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this MSDOS item)
{
var builder = new StringBuilder();
SabreTools.Printing.MSDOS.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this N3DS item)
{
var builder = new StringBuilder();
SabreTools.Printing.N3DS.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this NCF item)
{
var builder = new StringBuilder();
SabreTools.Printing.NCF.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this NewExecutable item)
{
var builder = new StringBuilder();
SabreTools.Printing.NewExecutable.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this Nitro item)
{
var builder = new StringBuilder();
SabreTools.Printing.Nitro.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this PAK item)
{
var builder = new StringBuilder();
SabreTools.Printing.PAK.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this PFF item)
{
var builder = new StringBuilder();
SabreTools.Printing.PFF.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this PlayJAudioFile item)
{
var builder = new StringBuilder();
SabreTools.Printing.PlayJAudioFile.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this PortableExecutable item)
{
var builder = new StringBuilder();
SabreTools.Printing.PortableExecutable.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this Quantum item)
{
var builder = new StringBuilder();
SabreTools.Printing.Quantum.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this SGA item)
{
var builder = new StringBuilder();
SabreTools.Printing.SGA.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this VBSP item)
{
var builder = new StringBuilder();
SabreTools.Printing.VBSP.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this VPK item)
{
var builder = new StringBuilder();
SabreTools.Printing.VPK.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this WAD item)
{
var builder = new StringBuilder();
SabreTools.Printing.WAD.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this XeMID item)
{
var builder = new StringBuilder();
SabreTools.Printing.XeMID.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this XMID item)
{
var builder = new StringBuilder();
SabreTools.Printing.XMID.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this XZP item)
{
var builder = new StringBuilder();
SabreTools.Printing.XZP.Print(builder, item.Model);
return builder;
}
#endregion
}
}

View File

@@ -7,7 +7,6 @@ using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using BinaryObjectScanner;
using BinaryObjectScanner.Utilities;
namespace Test
{

View File

@@ -27,13 +27,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Compression" Version="0.4.0" />
<PackageReference Include="SabreTools.IO" Version="1.3.2" />
<PackageReference Include="SabreTools.Compression" Version="0.5.0" />
<PackageReference Include="SabreTools.IO" Version="1.4.0" />
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
<PackageReference Include="SabreTools.Models" Version="1.4.0" />
<PackageReference Include="SabreTools.Printing" Version="1.3.3" />
<PackageReference Include="SabreTools.Serialization" Version="1.4.1" />
<PackageReference Include="UnshieldSharp" Version="1.7.3" />
<PackageReference Include="SabreTools.Models" Version="1.4.5" />
<PackageReference Include="SabreTools.Printing" Version="1.3.9" />
<PackageReference Include="SabreTools.Serialization" Version="1.5.6" />
<PackageReference Include="UnshieldSharp" Version="1.8.1" />
</ItemGroup>
</Project>