Compare commits

...

37 Commits
3.0.2 ... 3.1.0

Author SHA1 Message Date
Matt Nadareski
5cdf269a3e Bump version 2024-02-26 12:14:30 -05:00
TheRogueArchivist
b9d90ec35d Remove GetVersionFromSHA1Hash from SafeDisc (#284)
* Remove GetVersionFromSHA1Hash from SafeDisc.
* Minor SafeDisc comment cleanup.
2024-02-23 10:58:58 -08:00
Matt Nadareski
5fc1d3254d Remove outdated comments in build scripts 2024-02-21 19:24:33 -05:00
Matt Nadareski
d61bae8e61 Don't use the auto git hash 2024-02-21 00:04:16 -05:00
Matt Nadareski
f8f53869ae Fix build scripts, again 2024-02-20 23:22:10 -05:00
Matt Nadareski
f5146a6e35 osx-arm64 is such a pain 2024-02-20 22:48:12 -05:00
Matt Nadareski
faf96b9375 Wrong array 2024-02-20 22:10:51 -05:00
Matt Nadareski
2228e344f6 Or, not And 2024-02-20 21:53:52 -05:00
Matt Nadareski
9955bdcab1 Not all DLLs, oops 2024-02-20 21:47:59 -05:00
Matt Nadareski
4586d49a3f Use DLL filtering in publish scripts 2024-02-20 21:45:18 -05:00
Matt Nadareski
1f4e24452a Add non-DLL lists, not hooked up 2024-02-20 21:33:14 -05:00
Matt Nadareski
090bac4d59 Remove unbuildable runtime 2024-02-20 21:12:21 -05:00
Matt Nadareski
59bedf5fce Fix DLL bundling 2024-02-20 21:07:29 -05:00
Matt Nadareski
1bbc541957 Limit packing to just BOS library 2024-02-20 21:04:39 -05:00
Matt Nadareski
1bb0107ceb Remove net6.0 from AppVeyor, add win-x86 2024-02-20 21:03:28 -05:00
Matt Nadareski
10dad356cd Expand default and extended publish targets 2024-02-20 20:59:28 -05:00
Matt Nadareski
22b6971e51 Tabs lose this battle 2024-02-20 20:54:28 -05:00
Matt Nadareski
3203b56ef6 Update publish scripts 2024-02-20 20:51:59 -05:00
Matt Nadareski
d6db84152f Limit to MS-CAB to x86 until IntPtr issue resolved 2024-02-20 20:14:38 -05:00
Matt Nadareski
b7afad5a4a Enable MS-CAB extraction on at least x86 2024-02-20 19:59:43 -05:00
Matt Nadareski
9d6c53f631 Update build after submodule update 2024-02-20 18:45:37 -05:00
Matt Nadareski
aa7b02dfc3 Add libmspack4n and LessIO as submodlues 2024-02-20 18:44:51 -05:00
TheRogueArchivist
379ffaf61a Add more empty file checks for SafeDisc (#283) 2024-02-20 06:47:20 -08:00
TheRogueArchivist
1bdfccddbc Fix Hexalock false positive (#281) 2024-02-08 10:09:11 -08:00
Matt Nadareski
c83cdd590c Update libraries 2024-02-06 10:48:59 -05:00
Matt Nadareski
f4770374a7 Update copyright date 2024-02-06 10:44:36 -05:00
TheRogueArchivist
72880e93bc Add new Denuvo Anti-Cheat detections (#279) 2024-02-01 20:27:49 -08:00
TheRogueArchivist
6c9cd72948 Add CD-X notes (#278)
* Add CD-X notes

* Add additional note
2024-01-26 06:40:09 -08:00
TheRogueArchivist
2e71ef4635 Update CopyKiller detection and notes (WIP) (#277)
* Update CopyKiller detection and notes

* Cleanup Copykiller
2024-01-25 21:19:16 -08:00
TheRogueArchivist
04cd1098ea Improve CrypKey detection (#275)
* Improve CrypKey detection

* Add CrypKey file detections.
* Add new CrypKey executable detections.

* Fix CrypKey version parsing

* Address PR reviews

* Check for both "code" and "CODE" sections
2023-12-28 20:35:57 -08:00
TheRogueArchivist
e76ce64568 Update known versions for the first SafeDisc splash-screen (#274) 2023-12-25 17:31:09 -08:00
Matt Nadareski
8fe84abef3 Use more lenient file reading 2023-12-13 15:52:03 -05:00
TheRogueArchivist
1b1fa53547 Add small note about ProtectDISC using CSS (#272) 2023-12-01 21:28:21 -08:00
TheRogueArchivist
5019407f35 Add additional SafeDisc for Mac detections and notes (#271)
* Add additional SafeDisc for Mac detections and notes

* Slightly update notes

* Minor additions

* Update earliest known SafeDisc splash-screen version
2023-12-01 17:42:03 -08:00
Matt Nadareski
83ba19eccb Fix ancient .NET dictionary extensions 2023-11-29 13:13:27 -05:00
Matt Nadareski
936bf38521 Slight cleanup 2023-11-25 22:25:44 -05:00
TheRogueArchivist
f54b0d2bbb Add SafeDisc Splash-Screen detection and notes (#269)
* Add initial SafeDisc splash-screen scanning and notes

So far only SafeDisc 1 has been added.

* Further update SafeDisc splash screen notes

This gets part of the way through SafeDisc 2 at least

* Update SafeDisc splash-screen notes and detection up through SafeDisc 2

* Update splash-screen notes through SafeDisc 3

* Starting adding SafeDisc 4 splash-screen notes

* Finish adding SafeDisc 4 splash-screen support

* Update SafeDisc splash-screen notes

* oops

* oops again
2023-11-25 19:21:59 -08:00
85 changed files with 906 additions and 286 deletions

6
.gitmodules vendored
View File

@@ -1,3 +1,9 @@
[submodule "BinaryObjectScanner/_EXTERNAL/stormlibsharp"]
path = BinaryObjectScanner/_EXTERNAL/stormlibsharp
url = https://github.com/robpaveza/stormlibsharp.git
[submodule "BinaryObjectScanner/_EXTERNAL/libmspack4n"]
path = BinaryObjectScanner/_EXTERNAL/libmspack4n
url = https://github.com/activescott/libmspack4n.git
[submodule "BinaryObjectScanner/_EXTERNAL/LessIO"]
path = BinaryObjectScanner/_EXTERNAL/LessIO
url = https://github.com/activescott/LessIO.git

View File

@@ -12,7 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Developer Guide.md = Developer Guide.md
LICENSE = LICENSE
publish-nix.sh = publish-nix.sh
publish-win.bat = publish-win.bat
publish-win.ps1 = publish-win.ps1
README.md = README.md
EndProjectSection
EndProject

View File

@@ -3,19 +3,20 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> --> <!-- Can't be enabled because of external code -->
<Version>3.0.2</Version>
<Version>3.1.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Description>Protection scanning library</Description>
<Copyright>Copyright (c)2018-2023 Matt Nadareski</Copyright>
<Copyright>Copyright (c)2018-2024 Matt Nadareski</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<RepositoryUrl>https://github.com/SabreTools/BinaryObjectScanner</RepositoryUrl>
<RepositoryType>git</RepositoryType>
@@ -23,26 +24,34 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<!-- Set a build flag for Windows specifically -->
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
</PropertyGroup>
<!-- Exclude certain parts of external modules for .NET Framework 4.5.2 and above -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<PropertyGroup>
<DefaultItemExcludes>
$(DefaultItemExcludes);
**\AssemblyInfo.cs;
_EXTERNAL\LessIO\src\LessIO.Tests\**;
_EXTERNAL\libmspack4n\lib\**;
_EXTERNAL\libmspack4n\libmspack4ntest\**;
_EXTERNAL\stormlibsharp\lib\**;
_EXTERNAL\stormlibsharp\src\TestConsole\**
</DefaultItemExcludes>
</PropertyGroup>
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, .NET Framework 4.0, .NET Core and modern .NET -->
<PropertyGroup Condition="!$(TargetFramework.StartsWith(`net4`)) OR $(TargetFramework.StartsWith(`net40`))">
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, .NET Framework 4.0 or non-Windows builds -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`)) OR !$(RuntimeIdentifier.StartsWith(`win-`))">
<DefaultItemExcludes>
$(DefaultItemExcludes);
_EXTERNAL\**;
_EXTERNAL\**
</DefaultItemExcludes>
</PropertyGroup>
<!-- These are needed for dealing with native Windows DLLs -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`))">
<Content Include="*.dll">
<Pack>true</Pack>
<PackagePath>contentFiles;content</PackagePath>
@@ -57,15 +66,15 @@
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="MinThreadingBridge" Version="0.11.2" />
<PackageReference Include="MinTasksExtensionsBridge" Version="0.3.2" />
<PackageReference Include="MinThreadingBridge" Version="0.11.4" />
<PackageReference Include="MinTasksExtensionsBridge" Version="0.3.4" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="OpenMcdf" Version="2.3.0" />
<PackageReference Include="UnshieldSharp" Version="1.7.1" />
<PackageReference Include="UnshieldSharp" Version="1.7.2" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="SharpCompress" Version="0.34.2" />
<PackageReference Include="SharpCompress" Version="0.36.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
@@ -78,7 +87,7 @@
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
<PackageReference Include="SabreTools.Matching" Version="1.3.0" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.3.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.3.2" />
<PackageReference Include="WiseUnpacker" Version="1.3.0" />
</ItemGroup>

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -132,7 +132,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Detect(fs, file, includeDebug);
}

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NETFRAMEWORK && !NET20 && !NET35 && !NET40
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
using StormLibSharp;
#endif
@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}
@@ -26,8 +26,9 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35 || NET40 || NETCOREAPP || NET5_0_OR_GREATER
// Not supported for .NET Core and modern .NET due to Windows DLL requirements
#if NET20 || NET35 || NET40 || !WIN
// Not supported for old .NET due to feature requirements
// Not supported in non-Windows builds due to DLL requirements
return null;
#else
try

View File

@@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
using LibMSPackN;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -18,16 +21,50 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Extract(fs, file, includeDebug);
}
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35 || NET40 || !WIN
// Not supported for old .NET due to feature requirements
// Not supported in non-Windows builds due to DLL requirements
return null;
#else
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (var cabArchive = new MSCabinet(file))
{
// Loop over each entry
foreach (var compressedFile in cabArchive.GetFiles())
{
try
{
string tempFile = Path.Combine(tempPath, compressedFile.Filename);
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
compressedFile.ExtractTo(tempFile);
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
}
}
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
#endif
}
}
}

View File

@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Detect(fs, file, includeDebug);
}
@@ -48,7 +48,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -20,7 +20,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Detect(fs, file, includeDebug);
}
@@ -54,6 +54,20 @@ namespace BinaryObjectScanner.FileType
else if (fileContent.Contains("Please enter a valid registration number"))
protections.Add("CD-Key / Serial");
// CopyKiller
// Found in "autorun.dat" in CopyKiller versions 3.62 and 3.64.
if (fileContent.Contains("CopyKiller CD-Protection V3.6x"))
protections.Add("CopyKiller V3.62-V3.64");
// Found in "autorun.dat" in CopyKiller versions 3.99 and 3.99a.
else if (fileContent.Contains("CopyKiller V4 CD / DVD-Protection"))
protections.Add("CopyKiller V3.99+");
// Found in "engine.wzc" in CopyKiller versions 3.62 and 3.64.
else if (fileContent.Contains("CopyKiller V3.6x Protection Engine"))
protections.Add("CopyKiller V3.62-V3.64");
// Found in "engine.wzc" in CopyKiller versions 3.99 and 3.99a.
else if (fileContent.Contains("CopyKiller V3.99x Protection Engine"))
protections.Add("CopyKiller V3.99+");
// Freelock
// Found in "FILE_ID.DIZ" distributed with Freelock.
if (fileContent.Contains("FREELOCK 1.0"))
@@ -98,6 +112,28 @@ namespace BinaryObjectScanner.FileType
if (fileContent.Contains("Sentinel Driver Disk"))
protections.Add("Rainbow Sentinel");
// SafeDisc
// TODO: Add better version parsing.
// Found in "Info.plist" in Redump entries 23983, 42762, 72713, 73070, and 89603.
if (fileContent.Contains("<string>com.europevisionmacro.SafeDiscDVD</string>"))
{
if (fileContent.Contains("<string>2.90.032</string>"))
protections.Add("SafeDiscDVD for Macintosh 2.90.032");
else
protections.Add("SafeDiscDVD for Macintosh (Unknown Version - Please report to us on GitHub)");
}
// Found in "Info.plist" in Redump entry 89649.
if (fileContent.Contains("<string>com.macrovisioneurope.SafeDiscLT</string>"))
{
// TODO: Investigate why "CFBundleGetInfoString" and "CFBundleShortVersionString" say version 2.70.020, but "CFBundleVersion" says version 2.70.010.
if (fileContent.Contains("<string>2.70.020</string"))
protections.Add("SafeDiscLT for Macintosh 2.70.020");
else
protections.Add("SafeDiscLT for Macintosh (Unknown Version - Please report to us on GitHub)");
}
// The full line from a sample is as follows:
//
// The files securom_v7_01.dat and securom_v7_01.bak have been created during the installation of a SecuROM protected application.

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -17,7 +17,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}
@@ -124,7 +124,7 @@ namespace BinaryObjectScanner.FileType
try
{
// Open the archive
archiveStream = File.OpenRead(archiveFileName);
archiveStream = File.Open(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Seek to the data
archiveStream.Seek(directoryItem.DirectoryEntry.EntryOffset, SeekOrigin.Begin);

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -56,7 +56,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -35,7 +35,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -47,7 +47,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -39,7 +39,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -57,7 +57,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -80,7 +80,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -37,7 +37,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -59,7 +59,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -36,7 +36,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -39,7 +39,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -53,7 +53,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -43,7 +43,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -47,7 +47,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -30,7 +30,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -44,7 +44,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -51,7 +51,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -69,7 +69,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -68,7 +68,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}

View File

@@ -78,7 +78,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Packer
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}

View File

@@ -7,6 +7,10 @@ using SabreTools.Matching;
namespace BinaryObjectScanner.Protection
{
// Nothing is currently known about this DRM. One program may possibly have included it, as it has been listed as including these files in the installion directory (https://www.advanceduninstaller.com/Visit-Gallery-2-90896afd3151ed9660dddc23b892863f-application.htm).
// Unfortunately, this program and developer are so obscure, I'm not able to find any relevant further information on them whatsoever.
// The only source of valuable information currently known is a forum post about a user attempting to crack this DRM (https://forum.p30world.com/showthread.php?t=413264).
// Every attachment, upload, or photo from the forum thread are offline and unarchived.
public class CDX : IPathCheck
{
/// <inheritdoc/>

View File

@@ -1,32 +1,61 @@
#if NET40_OR_GREATER || NETCOREAPP
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;
namespace BinaryObjectScanner.Protection
{
public class CopyKiller : IContentCheck, IPathCheck
/// <summary>
/// CopyKiller was a program made by Webstylerzone that allowed you to copyprotect your own discs.
/// It appears to have used 3 different main forms of copy protection:
///
/// First, its core copy protection is applied by adding a folder from the program's installation directory to the disc as you burn it.
/// The files in this folder appear to only be text files identifying the software used, and seemingly random file contents.
/// How this protects the disc is currently not confirmed, and the data itself isn't corrupted or copied incorrectly on purpose.
/// A personal guess is that it intended to use the same effect as SafeDisc's "weak sectors" to rely on the drive writing the disc incorrectly and making an "uncopyable" disc.
/// This is backed up by an official description of how CopyKillers works, saying how it "uses a firmware error to make the cd copy protected." (https://web.archive.org/web/20061109151642/http://www.webtoolmaster.com/copykiller.htm)
///
/// Second, an optional autorun feature can be used by adding the appropriate contents of the "Autorun" folder from the program's installation directory to the disc as you burn it.
/// This relies on Window running the autorun automatically, causing a window to warning to popup that tells the user that this is a pirated copy, with seemingly nothing else happening.
/// I believe that it simply checks for the presence of the other protection files due to the complete lack of any ability to customize the DRM.
///
/// Last, there is a locked option to learn how to use it to protect audio CDs, but unfortunately this is only available with a registered version.
/// This means that the mechanics of how this was done are currently unknown, but may have simply been to write the same folder's data in, whether as raw audio data or a separate data track.
///
/// At some point at least as early as 2006 (https://web.archive.org/web/20061109151642/http://www.webtoolmaster.com/copykiller.htm), WTM (WebToolMaster) and Webstylerzone had some sort of partnership.
/// For example, WTM began hosting a link to CopyKiller beginning in 2006, and Webstylerzoning advertising WTM's products (https://web.archive.org/web/20070811202419/http://www.webstylerzone.com/en/download_brenner_copykiller_safedisc_safediscscanner_whatspeed_copyprotection_copy_protection_protect_cd_cds_audiocd_datacd_against_copying.htm).
/// As of October of 2011, WTM announced that CopyKiller was officially no longer being developed (https://web.archive.org/web/20111014233821/http://webtoolmaster.com/copykiller.htm).
///
/// CopyKiller website: https://web.archive.org/web/20030312200712/http://www.webstylerzone.com/CopyKiller/index.htm
/// Version 3.62 Installer: https://web.archive.org/web/20031130192048/http://www.webstylerzone.com/Downloads/Brennertools/CopyKiller-Setup.exe
/// Version 3.64 Installer: https://web.archive.org/web/20060524220845/http://download.webstylerzone.com:80/exe/CopyKiller-Setup.exe
/// Version 3.99 Installer: https://web.archive.org/web/20060524220845/http://download.webstylerzone.com:80/exe/CopyKiller-Setup.exe
/// Version 3.99a Installer: https://web.archive.org/web/20070721070138/http://www.webstylerzone.com/Downloads/exe/CopyKiller-Setup.exe
/// Version 3.99a Portable: https://web.archive.org/web/20070721070214/http://www.webstylerzone.com/Downloads/zip/CopyKiller.zip
///
/// TODO: Add support for the developer's EXE obfuscator, "EXEShield Deluxe". Most, if not all, EXEShield protected files are currently detected as "EXE Stealth" by BOS.
/// Samples include CopyKiller (Versions 3.64 & 3.99a) and SafeDiscScanner (Version 0.16) (https://archive.org/details/safediscscanner-0.16-webstylerzone-from-unofficial-source).
/// </summary>
public class CopyKiller : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
{
var contentMatchSets = new List<ContentMatchSet>
{
// Tom Commander
new(new byte?[]
{
0x54, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x6D, 0x6D,
0x61, 0x6E, 0x64, 0x65, 0x72
}, "CopyKiller"),
};
// TODO: Figure out how to differentiate between V3.99 and V3.99a.
// Get the sections from the executable, if possible
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
}
// TODO: Figure out why this check doesn't work.
// Found in "autorun.exe" in CopyKiller V3.64, V3.99, and V3.99a.
var name = pex.ProductName;
if (name?.StartsWith("CopyKiller", StringComparison.OrdinalIgnoreCase) == true)
return "CopyKiller V3.64+";
return null;
}
@@ -38,11 +67,43 @@ namespace BinaryObjectScanner.Protection
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: The following checks are overly broad and should be refined
// TODO: Look into .PFF files as an indicator. At least one disc has those oversized files
// Previous versions of BOS noted to look at ".PFF" files as possible indicators of CopyKiller, but those files seem unrelated.
// TODO: Figure out why this doesn't work.
var matchers = new List<PathMatchSet>
{
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
new(new FilePathMatch("CopyKillerV3"), "CopyKiller V3.62-3.64"),
new(new FilePathMatch("CopyKillerV4"), "CopyKiller V3.99-3.99a"),
new(new List<PathMatch>
{
new FilePathMatch("ACK3900.ckt"),
new FilePathMatch("ACK3999.ckt"),
new FilePathMatch("CK100.wzc"),
new FilePathMatch("CK2500.ck"),
new FilePathMatch("CK3600.tcwz"),
new FilePathMatch("Engine.wzc"),
new FilePathMatch("P261XP.tcck"),
new FilePathMatch("WZ200.rwzc"),
new FilePathMatch("XCK3900.ck2"),
}, "CopyKiller V3.99+"),
new(new List<PathMatch>
{
new FilePathMatch("ACK3900.ckt"),
new FilePathMatch("CK100.wzc"),
new FilePathMatch("CK2500.ck"),
new FilePathMatch("CK3600.tcwz"),
new FilePathMatch("Engine.wzc"),
new FilePathMatch("P261XP.tcck"),
new FilePathMatch("WZ200.rwzc"),
new FilePathMatch("XCK3900.ck2"),
}, "CopyKiller V3.64+"),
new(new List<PathMatch>
{
new FilePathMatch("CK100.wzc"),
new FilePathMatch("Engine.wzc"),
}, "CopyKiller V3.62+"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -51,11 +112,12 @@ namespace BinaryObjectScanner.Protection
/// <inheritdoc/>
public string? CheckFilePath(string path)
{
// TODO: The following checks are overly broad and should be refined
// TODO: Look into .PFF files as an indicator. At least one disc has those oversized files
// Previous versions of BOS noted to look at ".PFF" files as possible indicators of CopyKiller, but those files seem unrelated.
// TODO: Figure out why this doesn't work.
var matchers = new List<PathMatchSet>
{
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
new(new FilePathMatch("CopyKillerV3"), "CopyKiller V3.62-3.64"),
new(new FilePathMatch("CopyKillerV4"), "CopyKiller V3.99-3.99a"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,10 @@
using BinaryObjectScanner.Interfaces;
#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
@@ -7,7 +13,7 @@ namespace BinaryObjectScanner.Protection
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/CrypKey%20Installer.1.sg
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/CrypKey.2.sg
// https://github.com/wolfram77web/app-peid/blob/master/userdb.txt
public class CrypKey : IPortableExecutableCheck
public class CrypKey : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
@@ -17,6 +23,26 @@ namespace BinaryObjectScanner.Protection
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 "NECRO95.EXE" in IA item "NBECRORV11".
// Full string:
// *CrypKey Instant 2.0 security i(32 - bit) *
// *Copyright(c) 1996 Kenonic Controls Ltd. *
if (strs.Any(s => s.Contains("CrypKey Instant 2.0 security")))
return "CrypKey Instant 2.0";
// Generic check to catch unknown CrypKey Instant versions.
if (strs.Any(s => s.Contains("CrypKey Instant")))
return "CrypKey Instant (Unknown version - Please report to us on GitHub)";
// Generic check to catch unknown CrypKey products.
if (strs.Any(s => s.Contains("CrypKey")))
return "CrypKey (Unknown version - Please report to us on GitHub)";
}
// Get the CrypKey version from the VersionInfo, if it exists
string version = pex.GetVersionInfoString("CrypKey Version") ?? string.Empty;
@@ -24,9 +50,14 @@ namespace BinaryObjectScanner.Protection
var name = pex.CompanyName;
if (name?.StartsWith("CrypKey") == true)
return $"CrypKey {version}".TrimEnd();
name = pex.FileDescription;
// Found in "CKSEC_32.DLL" in IA item "NBECRORV11".
if (name?.StartsWith("CrypKey Instant security library") == true)
return $"CrypKey Instant {pex.GetInternalVersion()}";
// Found in 'cki32k.dll'
name = pex.FileDescription;
if (name?.StartsWith("CrypKey") == true)
return $"CrypKey {version}".TrimEnd();
@@ -43,5 +74,41 @@ namespace BinaryObjectScanner.Protection
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>
{
// Found in IA item "NBECRORV11".
new(new FilePathMatch("CKLICENS.HLP"), "CrypKey"),
new(new FilePathMatch("CKSEC_32.DLL"), "CrypKey"),
new(new FilePathMatch("CRYP95.DLL"), "CrypKey"),
new(new FilePathMatch("CRYP9516.DLL"), "CrypKey"),
new(new FilePathMatch("CRYPKEY.HLP"), "CrypKey"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
public string? CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// Found in IA item "NBECRORV11".
new(new FilePathMatch("CKLICENS.HLP"), "CrypKey"),
new(new FilePathMatch("CKSEC_32.DLL"), "CrypKey"),
new(new FilePathMatch("CRYP95.DLL"), "CrypKey"),
new(new FilePathMatch("CRYP9516.DLL"), "CrypKey"),
new(new FilePathMatch("CRYPKEY.HLP"), "CrypKey"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -51,10 +51,18 @@ namespace BinaryObjectScanner.Protection
if (name?.Equals("Denuvo Anti-Cheat Update Service", StringComparison.OrdinalIgnoreCase) == true)
return $"Denuvo Anti-Cheat";
// Found in "denuvo-anti-cheat-update-service-launcher.dll".
if (name?.Equals("Denuvo Anti-Cheat Update Service Launcher", StringComparison.OrdinalIgnoreCase) == true)
return $"Denuvo Anti-Cheat";
// Found in "denuvo-anti-cheat-runtime.dll".
if (name?.Equals("Denuvo Anti-Cheat Runtime", StringComparison.OrdinalIgnoreCase) == true)
return $"Denuvo Anti-Cheat";
// Found in "denuvo-anti-cheat-crash-report.exe".
if (name?.Equals("Denuvo Anti-Cheat Crash Report Tool", StringComparison.OrdinalIgnoreCase) == true)
return $"Denuvo Anti-Cheat";
// Data sourced from:
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Denuvo%20protector.2.sg
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/_denuvoComplete.2.sg
@@ -274,6 +282,15 @@ namespace BinaryObjectScanner.Protection
// This file is a renamed copy of "denuvo-anti-cheat-update-service.exe" which is only seen in the folder of the main game executable after it has been run, but before Denuvo Anti-Cheat is finished installing.
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
// Found in the Denuvo Anti-Cheat installer on their support website. (https://web.archive.org/web/20240130142033/https://support.codefusion.technology/anti-cheat/?l=ja&s=ac&e=2009)
new(new PathMatch("denuvo-anti-cheat-installer.zip", useEndsWith: true), "Denuvo Anti-Cheat"),
// Found in "denuvo-anti-cheat-installer.zip".
new(new PathMatch("Denuvo-Anti-Cheat_install_run_as_Admin.bat", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-crash-report.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-crash-report.exe.config", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-update-service-launcher.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -293,6 +310,15 @@ namespace BinaryObjectScanner.Protection
// This file is a renamed copy of "denuvo-anti-cheat-update-service.exe" which is only seen in the folder of the main game executable after it has been run, but before Denuvo Anti-Cheat is finished installing.
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
// Found in the Denuvo Anti-Cheat installer on their support website. (https://web.archive.org/web/20240130142033/https://support.codefusion.technology/anti-cheat/?l=ja&s=ac&e=2009)
new(new PathMatch("denuvo-anti-cheat-installer.zip", useEndsWith: true), "Denuvo Anti-Cheat"),
// Found in "denuvo-anti-cheat-installer.zip".
new(new PathMatch("Denuvo-Anti-Cheat_install_run_as_Admin.bat", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-crash-report.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-crash-report.exe.config", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-update-service-launcher.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -113,9 +113,6 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
// Found to be the default name used in HexaLock AutoLock 4.5.
new(new FilePathMatch("Start_Here.exe"), "HexaLock AutoLock 4.5"),
// Found to be contained in HexaLock AutoLock 4.5 and 4.7.
new(new FilePathMatch("MFINT.DLL"), "HexaLock AutoLock"),
new(new FilePathMatch("MFIMP.DLL"), "HexaLock AutoLock"),

View File

@@ -128,6 +128,14 @@ namespace BinaryObjectScanner.Protection
new(".icd", useEndsWith: true),
}, "SafeDisc 1/Lite"),
// Check for the original filename used for the SafeDisc splash-screens, new file names are used in later versions.
new(new List<PathMatch>
{
new FilePathMatch("00000001.TMP"),
new FilePathMatch("SPLSH16.BMP"),
new FilePathMatch("SPLSH256.BMP"),
}, "SafeDisc 1.00.025-1.01.044"),
new(new List<PathMatch>
{
new FilePathMatch("00000001.TMP"),
@@ -154,10 +162,21 @@ namespace BinaryObjectScanner.Protection
new FilePathMatch("secdrv.sys"),
}, "SafeDisc 1.45.011-1.50.020"),
// TODO: Research "splash16.bmp" and "splash256.bmp".
// Search for the splash screen files known to sometimes contain a generic SafeDisc splash-screen.
new(new FilePathMatch("00000000.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000000.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("0000040c.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("0000040c.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000407.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000407.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000409.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000409.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000809.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000809.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00001009.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00001009.256"), GetSafeDiscSplshVersion, "SafeDisc"),
// Found to be present in every version of SafeDisc, possibly every single release.
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
// The file "00000001.TMP" is found in most, if not all, SafeDisc protected programs and is detected within the general Macrovision checks due to being used in other Macrovision DRM.
// Found in many versions of SafeDisc, beginning in 2.05.030 and being used all the way until the final version 4.90.010. It is not always present, even in versions it has been used in. Found in Redump entries 56319 and 72195.
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
@@ -215,8 +234,20 @@ namespace BinaryObjectScanner.Protection
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
// Found on Redump entry 42762.
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
// Found in Redump entries 23983, 42762, 72713, 73070, and 89603.
new(new FilePathMatch(".SafeDiscDVD.bundle"), "SafeDiscDVD for Macintosh"),
new(new FilePathMatch("SafeDiscDVD"), "SafeDiscDVD for Macintosh"),
// Found in Redump entries 42762 and 73070.
// These files, along with "00000001.TMP" as found in the same version of SafeDiscDVD, appear to be likely encrypted game executables and are multiple GB in size.
new(new FilePathMatch("00000001I.TMP"), "SafeDiscDVD for Macintosh"),
new(new FilePathMatch("00000001P.TMP"), "SafeDiscDVD for Macintosh"),
// Found in Redump entry 89649.
new(new FilePathMatch("SafeDiscLT.bundle"), "SafeDiscLT for Macintosh"),
new(new FilePathMatch("SafeDiscLT"), "SafeDiscLT for Macintosh"),
// TODO: Add SafeDisc detection for Redump entry 63769 once Mac executables are supported for scanning. It appears to contain the same "BoG_" string and version detection logic.
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -231,10 +262,25 @@ namespace BinaryObjectScanner.Protection
new(new FilePathMatch("CLCD32.DLL"), GetSafeDiscCLCD32Version, "SafeDisc"),
new(new FilePathMatch("CLOKSPL.EXE"), GetSafeDiscCLOKSPLVersion, "SafeDisc"),
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
// The file "00000001.TMP" is found in most, if not all, SafeDisc protected programs and is detected within the general Macrovision checks due to being used in other Macrovision DRM.
// Found in many versions of SafeDisc, beginning in 2.05.030 and being used all the way until the final version 4.90.010. It is not always present, even in versions it has been used in. Found in Redump entries 56319 and 72195.
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
// TODO: Research "splash16.bmp" and "splash256.bmp".
// Search for the splash screen files known to sometimes contain a generic SafeDisc splash-screen.
new(new FilePathMatch("00000000.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000000.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("0000040c.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("0000040c.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000407.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000407.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000409.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000409.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000809.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00000809.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00001009.016"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("00001009.256"), GetSafeDiscSplshVersion, "SafeDisc"),
new(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
new(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
@@ -292,8 +338,20 @@ namespace BinaryObjectScanner.Protection
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
// Found in Redump entry 42762.
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
// Found in Redump entries 23983, 42762, 72713, 73070, and 89603.
new(new FilePathMatch(".SafeDiscDVD.bundle"), "SafeDiscDVD for Macintosh"),
new(new FilePathMatch("SafeDiscDVD"), "SafeDiscDVD for Macintosh"),
// Found in Redump entries 42762 and 73070.
// These files, along with "00000001.TMP" as found in the same version of SafeDiscDVD, appear to be likely encrypted game executables and are multiple GB in size.
new(new FilePathMatch("00000001I.TMP"), "SafeDiscDVD for Macintosh"),
new(new FilePathMatch("00000001P.TMP"), "SafeDiscDVD for Macintosh"),
// Found in Redump entry 89649.
new(new FilePathMatch("SafeDiscLT.bundle"), "SafeDiscLT for Macintosh"),
new(new FilePathMatch("SafeDiscLT"), "SafeDiscLT for Macintosh"),
// TODO: Add SafeDisc detection for Redump entry 63769 once Mac executables are supported for scanning. It appears to contain the same "BoG_" string and version detection logic.
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -542,7 +600,7 @@ namespace BinaryObjectScanner.Protection
// Found in Redump entries 9718, 12885, and 37523.
156_160 => "1.07.000-1.11.000",
// File size checks for versions 1.2X+ are superceded by executable string checks, which are more accurate. For reference, the previously used file sizes are kept as comments.
// File size checks for versions 1.2X+ are superseded by executable string checks, which are more accurate. For reference, the previously used file sizes are kept as comments.
// 157,184 bytes corresponds to SafeDisc 1.20.000-1.20.001 (Redump entries 21154 and 37920).
// 163,382 bytes corresponds to SafeDisc 1.30.010 (Redump entries 31526 and 55080).
// 165,888 bytes corresponds to SafeDisc 1.35.000 (Redump entries 9617 and 49552).
@@ -552,6 +610,16 @@ namespace BinaryObjectScanner.Protection
// 138,752 bytes corresponds to SafeDisc 1.50.020 (Redump entries 28810 and 62935).
_ => "1",
// Hashes have not been found to be a reliable indicator for these files, and likely differ on a game-to-game basis. Some hashes were previously collected and are collected below:
// Found in Redump entry 41923.
// F7A57F83BDC29040E20FD37CD0C6D7E6B2984180" => "1.00.030",
// Found in Redump entries 3569 and 3570.
// "A8ED1613D47D1B5064300FF070484528EBB20A3B" => "1.11.000",
// It is not known which games these files are from.
// "ED680E9A13F593E7A80A69EE1035D956AB62212B" => "1.3x",
// "66D8589343E00FA3E11BBF462E38C6F502515BEA" => "1.30.010",
// "5751AE2EE805D31227CFE7680F3C8BE4AB8945A3" => "1.40",
};
}
@@ -570,6 +638,9 @@ namespace BinaryObjectScanner.Protection
// Found in Redump entry 102979.
"B858CB282617FB0956D960215C8E84D1CCF909C6" => "(Empty File)",
// Found in Redump entry 63488.
"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" => "(Empty File)",
// Found in Redump entries 29073 and 31149.
"33434590D7DE4EEE2C35FCC98B0BF141F422B26D" => "1.06.000",
@@ -655,7 +726,8 @@ namespace BinaryObjectScanner.Protection
"B824ED257946EEE93F438B25C855E9DDE7A3671A" => "2.90.010-2.90.040",
// Found in Redump entries 13230 and 68204.
"CDA56FD150C9E9A19D7AF484621352122431F029" => "3.10.020",
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
"CDA56FD150C9E9A19D7AF484621352122431F029" => "3.10.020/4+",
// Found in Redump entries 36511 and 74338.
"E5504C4C31561D38C1F626C851A8D06212EA13E0" => "3.15.010",
@@ -701,33 +773,148 @@ namespace BinaryObjectScanner.Protection
};
}
private string? GetVersionFromSHA1Hash(string sha1Hash)
internal static string? GetSafeDiscSplshVersion(string firstMatchedString, IEnumerable<string>? files)
{
return sha1Hash.ToLowerInvariant() switch
// Special thanks to TheMechasaur for combing through known SafeDisc games and cataloging the splash-screens used in them, making these detections possible.
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
var sha1 = GetFileSHA1(firstMatchedString);
switch (sha1)
{
// dplayerx.dll
"f7a57f83bdc29040e20fd37cd0c6d7e6b2984180" => "1.00.030",
"a8ed1613d47d1b5064300ff070484528ebb20a3b" => "1.11.000",
"ed680e9a13f593e7a80a69ee1035d956ab62212b" => "1.3x",
"66d8589343e00fa3e11bbf462e38c6f502515bea" => "1.30.010",
"5751ae2ee805d31227cfe7680f3c8be4ab8945a3" => "1.40",
// Found in Redump entry 63488.
case "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709":
return "(Empty File)";
// secdrv.sys
"b64ad3ec82f2eb9fb854512cb59c25a771322181" => "1.11.000",
"ebf69b0a96adfc903b7e486708474dc864cc0c7c" => "1.40.004",
"f68a1370660f8b94f896bbba8dc6e47644d19092" => "2.30",
"60bc8c3222081bf76466c521474d63714afd43cd" => "2.40",
"08ceca66432278d8c4e0f448436b77583c3c61c8" => "2.50",
"10080eb46bf76ac9cf9ea74372cfa4313727f0ca" => "2.51",
"832d359a6de191c788b0e61e33f3d01f8d793d3c" => "2.70",
"afcfaac945a5b47712719a5e6a7eb69e36a5a6e0" or "cb24fbe8aa23a49e95f3c83fb15123ffb01f43f4" => "2.80",
"0383b69f98d0a9c0383c8130d52d6b431c79ac48" => "2.90",
"d7c9213cc78ff57f2f655b050c4d5ac065661aa9" => "3.20",
"fc6fedacc21a7244975b8f410ff8673285374cc2" => "4.00.002",// Also 4.60.000, might be a fluke
"2d9f54f35f5bacb8959ef3affdc3e4209a4629cb" => "1-4",
// First known generic SafeDisc splash-screen.
// 4-bit (16 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603.
case "D8A8CF761DD7C04F635385E4C4589E5F26C6171E":
return "1.11.000-2.40.011";
// 8-bit (256 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603.
case "0C9E45BF3EBE1382A3593994328C22BCB9A55456":
return "1.11.000-2.40.011";
_ => null,
};
// Second known generic SafeDisc splash-screen.
// 4-bit (16 color), found in Redump entries 46339 and 75897.
case "9B80F524D45041ED8CE1613AD5BDE94BFDBB2814":
return "2.70.030-2.80.010";
// 8-bit (256 color) version, found in Redump entries 46339 and 75897.
case "827AE9A32906CBE9098C9101184E0BE74CEA2744":
return "2.70.030-2.80.010";
// Third known generic SafeDisc splash-screen.
// 4-bit (16 color), found in Redump entries 74338, 75782, 84985, and 91552.
case "814ED63FD619655650E271D1B8B46BBE39C3655A":
return "3.15.010-3.20.022";
// 8-bit (256 color) version, found in Redump entries 31824, 74338, 75782, 84985, 91552, and 104053.
case "40C7ACEDB6C41AB067285090373E886EFB4F4AC4":
return "3.15.010-4.60.000";
default:
return null;
}
// There appear to be a few distinct generations of file names used for SafeDisc splash-screens.
// The first are the files named "SPLSH16.BMP"/"SPLSH256.BMP", which were typically used in SafeDisc versions 1.00.025-1.01.044.
// The next are the files named "000004XX", "000008XX", "00000cXX", and "00001XXX". When one of these is present, they seemingly always come in pairs of 2 with the extensions ".016" and ".256". They're typically present in SafeDisc versions 1.06.000-2.51.021.
// Next come the files simply named "0000000X", which still come in pairs with the extensions ".016" and ".256", starting in SafeDisc version 2.60.052 up until version 4.85.000. After this point, there doesn't seem to be any consistent SafeDisc splash-screen used at all.
// Starting SafeDisc version 4.00.000, the files with the ".016" extension seem to mostly disappear, with the ".256" files still being present.
// Exceptions:
// The files "00000409.016" and "00000409.256" are present in Redump entry 39273, despite it being SafeDisc 2.80.011. This may be because this disc contains some form of SafeDisc Lite as well, which tends to more closely resemble SafeDisc 1.
// Redump entry 51597 contains "00000000.016" and "00000000.256", breaking the trend of SafeDisc 4 not having any files with the ".016" extension. This may be due to this being a rerelease, so the splash-screen may have already been present in the original game files and carried over.
// TODO: Investigate "/409/splash.bmp" and "/0x0409.ini" files in Redump entry 45469.
// Known SafeDisc splash-screen file names (case-insensitive):
// "00000000.016": Found in SafeDisc version 2.60.052-4.00.003 (Redump entries 2064, 9621, 11639, 13230, 32783, 35385, 35512, 39273, 52606, 51597, 63813, 74338, 76775, and 84586).
// "00000000.256": Found in SafeDisc version 2.60.052-4.85.000 (Redump entries 2064, 9621, 11639, 13230, 32783, 34783, 35382, 35385, 35512, 39273, 46765, 52606, 51597, 63813, 68551, 71646, 74338, 74366, 76775, 76813, 79113, 83017, 84586, and 98589).
// "00000001.016": Found in SafeDisc version 2.72.000-3.20.024 (Redump entries 9621, 76775, and 86177).
// "00000001.256": Found in SafeDisc version 2.72.000-4.50.000 (Redump entries 9621, 71646, 76775, 76813, and 86177).
// "00000002.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000002.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000003.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000003.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000004.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000004.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000005.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000005.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000006.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000006.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000007.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000007.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000008.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000008.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000009.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000009.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000010.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000010.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000011.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000011.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000a.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000a.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000b.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000b.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000c.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000c.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000d.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000d.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000e.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000e.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000f.016": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "0000000f.256": Found in SafeDisc version 2.72.000 (Redump entry 9621).
// "00000404.016": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000404.256": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000406.016": Found in SafeDisc versions 1.41.000-2.51.021 (Redump entries 61047 and 66852).
// "00000406.256": Found in SafeDisc versions 1.41.000-2.51.021 (Redump entries 61047 and 66852).
// "00000407.016": Found in SafeDisc versions 1.07.000-2.51.021 (Redump entries 43321, 44350, 46756, 48863, 49552, 66586, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000407.256": Found in SafeDisc versions 1.07.000-2.51.021 (Redump entries 43321, 44350, 46756, 48863, 49552, 66586, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000408.016": Found in SafeDisc version 2.51.021 (Redump entry 38589).
// "00000408.256": Found in SafeDisc version 2.51.021 (Redump entry 38589).
// "00000409.016": Found in SafeDisc versions 1.06.000-2.80.011 (Redump entries 2022, 2595, 9718, 9819, 9846, 12885, 23786, 29073, 30022, 30555, 31526, 31666, 37832, 37920, 37982, 39273, 48863, 49552, 59462, 62935, and 63323).
// "00000409.256": Found in SafeDisc versions 1.06.000-2.80.011 (Redump entries 2022, 2595, 9718, 9819, 9846, 12885, 23786, 29073, 30022, 30555, 31526, 31666, 37982, 37920, 37832, 39273, 48863, 49552, 59462, 62935, and 63323).
// "0000040A.016": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 29073, 43321, 49552, and 66852).
// "0000040A.256": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 29073, 43321, 49552 and 66852).
// "0000040c.016": Found in SafeDisc versions 1.30.010-2.51.021 (Redump entries 43321, 48863, 49552, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "0000040c.256": Found in SafeDisc versions 1.30.010-2.51.021 (Redump entries 43321, 48863, 49552, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "0000040d.016": Found in SafeDisc version 2.51.021 (Redump entry 38589).
// "0000040d.256": Found in SafeDisc version 2.51.021 (Redump entry 38589).
// "0000040f.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "0000040f.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000410.016": Found in SafeDisc versions 1.35.000-2.51.021 (Redump entries 9617, 48863, 49552, 66852, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000410.256": Found in SafeDisc versions 1.35.000-2.51.021 (Redump entries 9617, 48863, 49552, 66852, and 79476, IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000411.016": Found in SafeDisc versions 1.40.004-2.51.031 (Redump entries 38589, 53659 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000411.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 38589, 53659 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000412.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000412.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000413.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 66852 and 72195 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000413.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 66852 and 72195 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000415.016": Found in SafeDisc versions 1.40.004-2.10.030 (Redump entry 38541 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000415.256": Found in SafeDisc versions 1.40.004-2.10.030 (Redump entry 38541 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000416.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000416.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entry 38589 and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000419.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000419.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "0000041d.016": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 55823, 66852, and 72195, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "0000041d.256": Found in SafeDisc versions 1.40.004-2.51.021 (Redump entries 55823, 66852, and 72195, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "0000041e.016": Found in SafeDisc version 1.40.004 (IA item the-sims-thai-english-electronic-arts-2000).
// "0000041e.256": Found in SafeDisc version 1.40.004 (IA item the-sims-thai-english-electronic-arts-2000).
// "00000429.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000429.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000804.016": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000804.256": Found in SafeDisc versions 1.40.004-1.50.020 (IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000809.016": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 9617, 31149, 37478, 37523, 37832, 43321, 48863, 53659, 59462, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000, the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000, and "primal-3d-interactive-series-professional-edition-2002-english" items "Interactive Hand CD", "Interactive Hip CD", and "Interactive Spine CD").
// "00000809.256": Found in SafeDisc versions 1.06.000-2.51.021 (Redump entries 9617, 31149, 37478, 37523, 37832, 43321, 48863, 53659, 59462, 66852, 72195, and 79476, and IA items the-sims-thai-english-electronic-arts-2000, the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000, and "primal-3d-interactive-series-professional-edition-2002-english" items "Interactive Hand CD", "Interactive Hip CD", and "Interactive Spine CD").
// "00000814.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000814.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000816.016": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000816.256": Found in SafeDisc version 1.41.000 (Redump entry 61047).
// "00000c0a.016": Found in SafeDisc versions 1.11.000-2.30.031 (Redump entry 3569, 48863, 55078, 55080, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00000c0a.256": Found in SafeDisc versions 1.11.000-2.30.031 (Redump entry 3569, 48863, 55078, 55080, and 79476, and IA items the-sims-thai-english-electronic-arts-2000 and the-sims-livin-large-expansion-pack-thai-english-electronic-arts-2000).
// "00001009.016": Found in SafeDisc version 2.30.030 (Redump entry 45040).
// "00001009.256": Found in SafeDisc version 2.30.030 (Redump entry 45040).
// "SPLSH16.BMP": Found in SafeDisc versions 1.00.025-1.01.044 (Redump entries 66005 and 81619).
// "SPLSH256.BMP": Found in SafeDisc versions 1.00.025-1.01.044 (Redump entries 66005 and 81619).
}
private string GetSafeDiscDiagExecutableVersion(PortableExecutable pex)

View File

@@ -342,6 +342,9 @@ namespace BinaryObjectScanner.Protection
var fi = new FileInfo(firstMatchedString);
return fi.Length switch
{
// Found in Redump entry 63488.
0 => "(Empty File)",
// Found in Redump entry 102979.
1 => "(Empty File)",
@@ -388,7 +391,8 @@ namespace BinaryObjectScanner.Protection
12_400 => "3.18.000 / SafeDisc 2.90.010-2.90.040",
// Found in Redump entries 13230, 15383, and 36511.
12_528 => "3.19.000 / SafeDisc 3.10.020-3.15.011",
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
12_528 => "3.19.000 / SafeDisc 3.10.020-3.15.011/4+",
// Found in Redump entries 58625 and 84586.
11_973 => "3.22.000 / SafeDisc 3.20.020-3.20.022",
@@ -396,8 +400,8 @@ namespace BinaryObjectScanner.Protection
// Found in Redump entries 15614, 42034, 45686, 56320, 60021, 79729, and 80776.
163_644 => "4.00.060 / SafeDisc 4.00.000-4.70.000",
// Found distributed online, but so far not in a game release. TODO: Discover original source.
// Can be found at https://github.com/ericwj/PsSecDrv/blob/master/tools/SECDRV/SECDRV.sys, and the file is confirmed to be distributed officialy by Microsoft: https://www.virustotal.com/gui/file/34bbb0459c96b3de94ccb0d73461562935c583d7bf93828da4e20a6bc9b7301d/.
// Found distributed online, but so far not in a game release. May be a final driver version never released with a game. TODO: Discover original source.
// Can be found at https://github.com/ericwj/PsSecDrv/blob/master/tools/SECDRV/SECDRV.sys, and the file is confirmed to be distributed officially by Microsoft: https://www.virustotal.com/gui/file/34bbb0459c96b3de94ccb0d73461562935c583d7bf93828da4e20a6bc9b7301d/.
23_040 => "4.03.086 / Product Unknown",
// Found in https://web.archive.org/web/20010417215205/http://www.macrovision.com:80/demos/Trialware.exe.
@@ -405,6 +409,22 @@ namespace BinaryObjectScanner.Protection
// This file is not currently known to be used in versions past 4.70.000.
_ => "/ Product Unknown (Report this to us on GitHub)",
// Hashes have not been found to be a reliable indicator for these files, and likely differ on a game-to-game basis. Some hashes were previously collected and are collected below:
// Found in Redump entries 3569 and 3570.
// "B64AD3EC82F2EB9FB854512CB59C25A771322181" => "1.11.000",
// It is not known which games these files are from.
// "EBF69B0A96ADFC903B7E486708474DC864CC0C7C" => "1.40.004",
// "F68A1370660F8B94F896BBBA8DC6E47644D19092" => "2.30",
// "60BC8C3222081BF76466C521474D63714AFD43CD" => "2.40",
// "08CECA66432278D8C4E0F448436B77583C3C61C8" => "2.50",
// "10080EB46BF76AC9CF9EA74372CFA4313727F0CA" => "2.51",
// "832D359A6DE191C788B0E61E33F3D01F8D793D3C" => "2.70",
// "AFCFAAC945A5B47712719A5E6A7EB69E36A5A6E0" or "CB24FBE8AA23A49E95F3C83FB15123FFB01F43F4" => "2.80",
// "0383B69F98D0A9C0383C8130D52D6B431C79AC48" => "2.90",
// "D7C9213CC78FF57F2F655B050C4D5AC065661AA9" => "3.20",
// "FC6FEDACC21A7244975B8F410FF8673285374CC2" => "4.00.002",// Also 4.60.000, might be a fluke
// "2D9F54F35F5BACB8959EF3AFFDC3E4209A4629CB" => "1-4",
};
}
@@ -427,8 +447,9 @@ namespace BinaryObjectScanner.Protection
"3.18.000" => "3.18.000 / SafeDisc 2.90.010-2.90.040",
// Found in Redump entries 13230, 15383, and 36511.
// SafeDisc 4+ is known to sometimes use old versions of drivers, such as in Redump entry 101261.
// The product version is "3.19.000 Windows NT/2K/XP 2003/03/19".
"3.19.000" => "3.19.000 / SafeDisc 3.10.020-3.15.011",
"3.19.000" => "3.19.000 / SafeDisc 3.10.020-3.15.011/4+",
// Found in Redump entries 58625 and 84586.
// The product version is "SECURITY Driver 3.22.000 2004/01/16".

View File

@@ -8,6 +8,7 @@ using SabreTools.Serialization.Wrappers;
namespace BinaryObjectScanner.Protection
{
// This protection was called VOB ProtectCD / ProtectDVD in versions prior to 6
// ProtectDISC 9/10 checks for the presence of CSS on the disc to run, but don't encrypt any sectors or check for keys. Confirmed in Redump entries 78367 and 110095.
public class ProtectDISC : IPortableExecutableCheck
{
/// <inheritdoc/>

View File

@@ -266,7 +266,7 @@ namespace BinaryObjectScanner
// Open the file and begin scanning
try
{
using FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return GetInternalProtections(file, fs);
}
catch (Exception ex)

View File

@@ -60,7 +60,8 @@ namespace BinaryObjectScanner.Utilities
// Add the key if needed and then append the lists
#if NET20 || NET35
original[key] ??= new Queue<string>();
if (!original.ContainsKey(key))
original[key] = new Queue<string>();
#else
original.TryAdd(key, new ConcurrentQueue<string>());
#endif
@@ -88,7 +89,8 @@ namespace BinaryObjectScanner.Utilities
// Add the key if needed and then append the lists
#if NET20 || NET35
original[key] ??= new Queue<string>();
if (!original.ContainsKey(key))
original[key] = new Queue<string>();
#else
original.TryAdd(key, new ConcurrentQueue<string>());
#endif
@@ -114,7 +116,8 @@ namespace BinaryObjectScanner.Utilities
foreach (string key in addition.Keys)
{
#if NET20 || NET35
original[key] ??= new Queue<string>();
if (!original.ContainsKey(key))
original[key] = new Queue<string>();
#else
original.TryAdd(key, new ConcurrentQueue<string>());
#endif

View File

@@ -319,6 +319,11 @@ namespace BinaryObjectScanner.Utilities
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
@@ -720,6 +725,10 @@ namespace BinaryObjectScanner.Utilities
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;
@@ -732,10 +741,16 @@ namespace BinaryObjectScanner.Utilities
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

View File

@@ -22,7 +22,7 @@ namespace BinaryObjectScanner.Utilities
try
{
var sha1 = SHA1.Create();
using (Stream fileStream = File.OpenRead(path))
using (Stream fileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] buffer = new byte[32768];
while (true)

View File

@@ -4,4 +4,6 @@ This directory contains multiple external libraries. Here is the status of each:
| Directory | Library | Status |
| --------- | ------- | ------ |
| stormlibsharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | External submodule |
| LessIO | [LessIO](https://github.com/activescott/LessIO) | External submodule |
| libmspack4n | [libmspack4n](https://github.com/activescott/libmspack4n) | External submodule |
| stormlibsharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | External submodule |

Binary file not shown.

View File

@@ -6,10 +6,12 @@ C# protection, packer, and archive scanning library. This currently compiles as
The following 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
- [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction
- [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) - zlib-based extraction
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET 6, .NET 7, or .NET 8 builds due to Windows-specific libraries]
- [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]
- [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp) - InstallShield CAB extraction
- [WiseUnpacker](https://github.com/mnadareski/WiseUnpacker) - Wise Installer extraction
@@ -47,9 +49,9 @@ Below is a list of protections detected by BinaryObjectScanner. The two columns
| CDSHiELD SE | True | False | |
| Cenga ProtectDVD | True | True | |
| ChosenBytes CodeLock | True | True | Partially unconfirmed² |
| CopyKiller | True | True | Unconfirmed¹ |
| CopyKiller | True | True | |
| CopyLok/CodeLok | True | False | |
| CrypKey | True | False | |
| CrypKey | True | True | |
| Cucko (EA Custom) | True | False | Does not detect all known cases |
| Denuvo Anti-Cheat/Anti-Tamper| True | True | |
| DigiGuard | True | True | |

View File

@@ -65,7 +65,7 @@ namespace Test
private static 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.Read);
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 8 bytes
byte[]? magic = stream.ReadBytes(8);
@@ -408,6 +408,7 @@ namespace Test
#endif
}
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
// Microsoft Cabinet archive
else if (ft == SupportedFileType.MicrosoftCAB)
{
@@ -415,7 +416,7 @@ namespace Test
Console.WriteLine("Extracting MS-CAB contents");
Console.WriteLine();
var cabinet = MicrosoftCabinet.Create(stream);
var cabinet = new LibMSPackN.MSCabinet(file);
if (cabinet == null)
{
Console.WriteLine("Something went wrong parsing MS-CAB archive");
@@ -425,7 +426,24 @@ namespace Test
try
{
Console.WriteLine("MS-CAB extraction is disabled");
// Extract the MS-CAB contents to the directory
foreach (var compressedFile in cabinet.GetFiles())
{
try
{
string tempFile = Path.Combine(outputDirectory, compressedFile.Filename);
string? directoryName = Path.GetDirectoryName(tempFile);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
compressedFile.ExtractTo(tempFile);
}
catch (Exception ex)
{
Console.WriteLine($"Something went wrong extracting Microsoft Cabinet entry {compressedFile.Filename}: {ex}");
Console.WriteLine();
}
}
}
catch (Exception ex)
{
@@ -433,6 +451,7 @@ namespace Test
Console.WriteLine();
}
}
#endif
// Microsoft LZ / LZ32
else if (ft == SupportedFileType.MicrosoftLZ)
@@ -474,7 +493,7 @@ namespace Test
}
}
#if NETFRAMEWORK && !NET20 && !NET35 && !NET40
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
// MoPaQ (MPQ) archive
else if (ft == SupportedFileType.MPQ)
{
@@ -514,7 +533,10 @@ namespace Test
try
{
string tempFile = Path.Combine(outputDirectory, sub);
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
string? directoryName = Path.GetDirectoryName(tempFile);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
mpqArchive.ExtractFile(sub, tempFile);
}
catch (Exception ex)

View File

@@ -166,7 +166,7 @@ namespace Test
#if NET6_0_OR_GREATER
options.Json = true;
#else
Console.WriteLine("JSON output not available in .NET Framework 4.8");
Console.WriteLine("JSON output not available in .NET Framework");
#endif
break;

View File

@@ -49,7 +49,7 @@ namespace Test
{
Console.WriteLine($"Attempting to print info for {file}");
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 8 bytes
byte[]? magic = stream.ReadBytes(8);

View File

@@ -2,15 +2,21 @@
<PropertyGroup>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<!-- Set a build flag for Windows specifically -->
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BinaryObjectScanner\BinaryObjectScanner.csproj" />
</ItemGroup>
@@ -18,7 +24,7 @@
<!-- Support for old .NET versions -->
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="OpenMcdf" Version="2.3.0" />
<PackageReference Include="UnshieldSharp" Version="1.7.1" />
<PackageReference Include="UnshieldSharp" Version="1.7.2" />
</ItemGroup>
<ItemGroup>
@@ -26,8 +32,8 @@
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
<PackageReference Include="SabreTools.Matching" Version="1.3.0" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
<PackageReference Include="SabreTools.Printing" Version="1.3.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.3.0" />
<PackageReference Include="SabreTools.Printing" Version="1.3.1" />
<PackageReference Include="SabreTools.Serialization" Version="1.3.2" />
</ItemGroup>
</Project>

View File

@@ -18,17 +18,13 @@ build_script:
- dotnet restore
# Debug
- dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net8.0 -r win-x86 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
- dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
# Release
- dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net8.0 -r win-x86 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
- dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugSymbols=false
@@ -38,6 +34,8 @@ build_script:
# post-build script
after_build:
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\win-x86\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x86.zip *
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\Test\bin\Debug\net8.0\linux-x64\publish\
@@ -55,6 +53,8 @@ on_failure:
# artifact linking
artifacts:
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x86.zip
name: BinaryObjectScanner (.NET 8.0, Windows x86)
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_win-x64.zip
name: BinaryObjectScanner (.NET 8.0, Windows x64)
- path: BinaryObjectScanner_%APPVEYOR_REPO_COMMIT%_net8.0_linux-x64.zip

View File

@@ -3,67 +3,123 @@
# This batch file assumes the following:
# - .NET 8.0 (or newer) SDK is installed and in PATH
# - zip is installed and in PATH
# - The relevant commandline programs are already downloaded
# and put into their respective folders
# - Git is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# Optional parameters
USE_ALL=false
NO_BUILD=false
NO_ARCHIVE=false
while getopts "uba" OPTION
do
case $OPTION in
u)
USE_ALL=true
;;
b)
NO_BUILD=true
;;
a)
NO_ARCHIVE=true
;;
*)
echo "Invalid option provided"
exit 1
;;
esac
done
# Set the current directory as a variable
BUILD_FOLDER=$PWD
# Restore Nuget packages for all builds
echo "Restoring Nuget packages"
dotnet restore
# Set the current commit hash
COMMIT=`git log --pretty=%H -1`
# .NET 6.0 Debug
echo "Building .NET 6.0 debug"
dotnet publish Test/Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test/Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test/Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
# Create the build matrix arrays
FRAMEWORKS=("net8.0")
RUNTIMES=("win-x86" "win-x64" "linux-x64" "osx-x64")
# .NET 6.0 Release
echo "Building .NET 6.0 release"
dotnet publish Test/Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test/Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test/Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
# Use expanded lists, if requested
if [ $USE_ALL = true ]
then
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0")
RUNTIMES=("win-x86" "win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64")
fi
# .NET 8.0 Debug
echo "Building .NET 8.0 debug"
dotnet publish Test/Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test/Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test/Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
# Create the filter arrays
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0")
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64")
NON_DLL_FRAMEWORKS=("net20" "net35" "net40")
NON_DLL_RUNTIMES=("win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64")
# .NET 8.0 Release
echo "Building .NET 8.0 release"
dotnet publish Test/Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test/Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test/Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
# Only build if requested
if [ $NO_BUILD = false ]
then
# Restore Nuget packages for all builds
echo "Restoring Nuget packages"
dotnet restore
# Create Test Debug archives
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/win-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_win-x64_debug.zip .
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/linux-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_linux-x64_debug.zip .
cd $BUILD_FOLDER/Test/bin/Debug/net6.0/osx-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_osx-x64_debug.zip .
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/win-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_win-x64_debug.zip .
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/linux-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_linux-x64_debug.zip .
cd $BUILD_FOLDER/Test/bin/Debug/net8.0/osx-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_osx-x64_debug.zip .
# Create Nuget Package
dotnet pack BinaryObjectScanner/BinaryObjectScanner.csproj --output $BUILD_FOLDER
# Create Test Release archives
cd $BUILD_FOLDER/Test/bin/Release/net6.0/win-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_win-x64_release.zip .
cd $BUILD_FOLDER/Test/bin/Release/net6.0/linux-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_linux-x64_release.zip .
cd $BUILD_FOLDER/Test/bin/Release/net6.0/osx-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net6.0_osx-x64_release.zip .
cd $BUILD_FOLDER/Test/bin/Release/net8.0/win-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_win-x64_release.zip .
cd $BUILD_FOLDER/Test/bin/Release/net8.0/linux-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_linux-x64_release.zip .
cd $BUILD_FOLDER/Test/bin/Release/net8.0/osx-x64/publish/
zip -r $BUILD_FOLDER/BinaryObjectScanner_net8.0_osx-x64_release.zip .
# Build Test
for FRAMEWORK in "${FRAMEWORKS[@]}"
do
for RUNTIME in "${RUNTIMES[@]}"
do
# If we have an invalid combination of framework and runtime
if [ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] && [ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
then
continue
fi
# Only .NET 5 and above can publish to a single file
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]
then
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
else
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
dotnet publish Test/Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
fi
done
done
fi
# Only create archives if requested
if [ $NO_ARCHIVE = false ]
then
# Create Test archives
for FRAMEWORK in "${FRAMEWORKS[@]}"
do
for RUNTIME in "${RUNTIMES[@]}"
do
# If we have an invalid combination of framework and runtime
if [ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] && [ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
then
continue
fi
cd $BUILD_FOLDER/Test/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
if [ $(echo ${NON_DLL_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] || [ $(echo ${NON_DLL_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
then
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip . -x 'CascLib.dll' -x 'mspack.dll' -x 'StormLib.dll'
else
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip .
fi
cd $BUILD_FOLDER/Test/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
if [ $(echo ${NON_DLL_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ] || [ $(echo ${NON_DLL_RUNTIMES[@]} | fgrep -w $RUNTIME) ]
then
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip . -x 'CascLib.dll' -x 'mspack.dll' -x 'StormLib.dll'
else
zip -r $BUILD_FOLDER/BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip .
fi
done
done
# Reset the directory
cd $BUILD_FOLDER
fi

View File

@@ -1,63 +0,0 @@
@echo OFF
REM This batch file assumes the following:
REM - .NET 8.0 (or newer) SDK is installed and in PATH
REM - 7-zip commandline (7z.exe) is installed and in PATH
REM - The relevant commandline programs are already downloaded
REM and put into their respective folders
REM
REM If any of these are not satisfied, the operation may fail
REM in an unpredictable way and result in an incomplete output.
REM Set the current directory as a variable
set BUILD_FOLDER=%~dp0
REM Restore Nuget packages for all builds
echo Restoring Nuget packages
dotnet restore
REM Debug
echo Building debug
dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true -p:PublishSingleFile=true
REM Release
echo Building release
dotnet publish Test\Test.csproj -f net6.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test\Test.csproj -f net6.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test\Test.csproj -f net6.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test\Test.csproj -f net8.0 -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test\Test.csproj -f net8.0 -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish Test\Test.csproj -f net8.0 -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
REM Create Test Debug archives
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_linux-x64_debug.zip *
cd %BUILD_FOLDER%\Test\bin\Debug\net6.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_osx-x64_debug.zip *
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_linux-x64_debug.zip *
cd %BUILD_FOLDER%\Test\bin\Debug\net8.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_osx-x64_debug.zip *
REM Create Test Release archives
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_win-x64_release.zip *
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_linux-x64_release.zip *
cd %BUILD_FOLDER%\Test\bin\Release\net6.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net6.0_osx-x64_release.zip *
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_win-x64_release.zip *
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_linux-x64_release.zip *
cd %BUILD_FOLDER%\Test\bin\Release\net8.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\BinaryObjectScanner_net8.0_osx-x64_release.zip *

121
publish-win.ps1 Normal file
View File

@@ -0,0 +1,121 @@
# This batch file assumes the following:
# - .NET 8.0 (or newer) SDK is installed and in PATH
# - 7-zip commandline (7z.exe) is installed and in PATH
# - Git for Windows is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# Optional parameters
param(
[Parameter(Mandatory = $false)]
[Alias("UseAll")]
[switch]$USE_ALL,
[Parameter(Mandatory = $false)]
[Alias("NoBuild")]
[switch]$NO_BUILD,
[Parameter(Mandatory = $false)]
[Alias("NoArchive")]
[switch]$NO_ARCHIVE
)
# Set the current directory as a variable
$BUILD_FOLDER = $PSScriptRoot
# Set the current commit hash
$COMMIT = git log --pretty=format:"%H" -1
# Create the build matrix arrays
$FRAMEWORKS = @('net8.0')
$RUNTIMES = @('win-x86', 'win-x64', 'linux-x64', 'osx-x64')
# Use expanded lists, if requested
if ($USE_ALL.IsPresent)
{
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
$RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
}
# Create the filter arrays
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
$NON_DLL_FRAMEWORKS = @('net20', 'net35', 'net40')
$NON_DLL_RUNTIMES = @('win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
# Only build if requested
if (!$NO_BUILD.IsPresent)
{
# Restore Nuget packages for all builds
Write-Host "Restoring Nuget packages"
dotnet restore
# Create Nuget Package
dotnet pack BinaryObjectScanner\BinaryObjectScanner.csproj --output $BUILD_FOLDER
# Build Test
foreach ($FRAMEWORK in $FRAMEWORKS)
{
foreach ($RUNTIME in $RUNTIMES)
{
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
continue
}
# Only .NET 5 and above can publish to a single file
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
{
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
}
else
{
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
dotnet publish Test\Test.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
}
}
}
}
# Only create archives if requested
if (!$NO_ARCHIVE.IsPresent)
{
# Create Test archives
foreach ($FRAMEWORK in $FRAMEWORKS)
{
foreach ($RUNTIME in $RUNTIMES)
{
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
continue
}
Set-Location -Path $BUILD_FOLDER\Test\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
if ($NON_DLL_FRAMEWORKS -contains $FRAMEWORK -or $NON_DLL_RUNTIMES -contains $RUNTIME)
{
7z a -tzip -x'!CascLib.dll' -x'!mspack.dll' -x'!StormLib.dll' $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
else
{
7z a -tzip $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
Set-Location -Path $BUILD_FOLDER\Test\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
if ($NON_DLL_FRAMEWORKS -contains $FRAMEWORK -or $NON_DLL_RUNTIMES -contains $RUNTIME)
{
7z a -tzip -x'!CascLib.dll' -x'!mspack.dll' -x'!StormLib.dll' $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip *
}
else
{
7z a -tzip $BUILD_FOLDER\BinaryObjectScanner_${FRAMEWORK}_${RUNTIME}_release.zip *
}
}
}
# Reset the directory
Set-Location -Path $PSScriptRoot
}