Compare commits

...

13 Commits
3.0.0 ... 3.0.2

Author SHA1 Message Date
Matt Nadareski
0e32abc76c Bump version 2023-11-22 13:28:56 -05:00
Matt Nadareski
94cb06a3bd Handle some messages 2023-11-22 13:28:13 -05:00
Matt Nadareski
907aea443e Support .NET Framework 2.0 2023-11-22 12:22:01 -05:00
Matt Nadareski
385922723c Upate packages 2023-11-22 10:48:08 -05:00
Matt Nadareski
3061c2f009 Reenable .NET Framework 4.0 2023-11-21 10:59:29 -05:00
Matt Nadareski
5c0ccbde35 Temporarily remove .NET Framework 4.0 2023-11-21 10:19:15 -05:00
Matt Nadareski
7b998de2ca Handle more C# 12 syntax 2023-11-21 10:17:25 -05:00
Matt Nadareski
b0d49f52a5 Bump version 2023-11-20 12:16:53 -05:00
Matt Nadareski
6f9bcc2111 Fix multiple invocation bug
This bug arose when all of the libraries were consoliated into the same library for better packaging. Each set of classes was being instantiated 3 times as a result.
2023-11-18 20:55:32 -05:00
Matt Nadareski
0fb0ecd28a Update ST libraries for bugfixes 2023-11-15 12:54:32 -05:00
Matt Nadareski
6194d88aec Correct the excludes 2023-11-15 11:26:00 -05:00
Matt Nadareski
b02c3121fe Use official package for IProgress 2023-11-15 00:24:47 -05:00
Matt Nadareski
580db0cb65 Minor tweaks to reduce warnings 2023-11-14 23:48:35 -05:00
120 changed files with 3357 additions and 2794 deletions

View File

@@ -2,13 +2,15 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> --> <!-- Can't be enabled because of external code -->
<Version>3.0.0</Version>
<Version>3.0.2</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -21,8 +23,8 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<!-- Exclude certain parts of external modules for .NET Framework -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<!-- Exclude certain parts of external modules for .NET Framework 4.5.2 and above -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<DefaultItemExcludes>
$(DefaultItemExcludes);
**\AssemblyInfo.cs;
@@ -31,7 +33,7 @@
</DefaultItemExcludes>
</PropertyGroup>
<!-- Exclude all external modules for .NET Core and modern .NET -->
<!-- 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`))">
<DefaultItemExcludes>
$(DefaultItemExcludes);
@@ -53,25 +55,31 @@
</Content>
</ItemGroup>
<ItemGroup>
<!-- 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" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="OpenMcdf" Version="2.3.0" />
<PackageReference Include="SabreTools.Compression" Version="0.2.0" />
<PackageReference Include="SabreTools.IO" Version="1.2.0" />
<PackageReference Include="SabreTools.Matching" Version="1.2.0" />
<PackageReference Include="SabreTools.Models" Version="1.2.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.2.0" />
<PackageReference Include="UnshieldSharp" Version="1.7.0" />
<PackageReference Include="WiseUnpacker" Version="1.2.0" />
<PackageReference Include="UnshieldSharp" Version="1.7.1" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="SharpCompress" Version="0.34.1" />
<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="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Compression" Version="0.3.0" />
<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="WiseUnpacker" Version="1.3.0" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Compressors;
using SharpCompress.Compressors.Deflate;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -111,19 +109,19 @@ namespace BinaryObjectScanner.FileType
// Create the output path
string filePath = Path.Combine(outputDirectory, file.Name ?? $"file{index}");
using (FileStream fs = File.OpenWrite(filePath))
{
// Read the data block
var data = item.ReadFromDataSource(offset, compressedSize);
if (data == null)
return false;
using FileStream fs = File.OpenWrite(filePath);
// If we have uncompressed data
if (compressedSize == file.UncompressedSize)
{
fs.Write(data, 0, compressedSize);
}
#if NET462_OR_GREATER
// Read the data block
var data = item.ReadFromDataSource(offset, compressedSize);
if (data == null)
return false;
// If we have uncompressed data
if (compressedSize == file.UncompressedSize)
{
fs.Write(data, 0, compressedSize);
}
#if NET462_OR_GREATER || NETCOREAPP
else
{
MemoryStream ms = new MemoryStream(data);
@@ -131,7 +129,6 @@ namespace BinaryObjectScanner.FileType
zs.CopyTo(fs);
}
#endif
}
return true;
}

View File

@@ -109,7 +109,7 @@ namespace BinaryObjectScanner.FileType
}
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path
@@ -188,7 +188,7 @@ namespace BinaryObjectScanner.FileType
string filename = $"{texture.Name}.bmp";
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Compressors;
using SharpCompress.Compressors.BZip2;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -31,7 +29,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -2,7 +2,9 @@
using System.IO;
using System.Text;
using BinaryObjectScanner.Interfaces;
#if NET40_OR_GREATER || NETCOREAPP
using OpenMcdf;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -17,15 +19,17 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35
// Not supported for .NET Framework 2.0 or .NET Framework 3.5 due to library support
return null;
#else
try
{
// Create a temp output directory
@@ -84,6 +88,7 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#endif
}
/// <remarks>Adapted from LibMSI</remarks>

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -40,9 +42,7 @@ namespace BinaryObjectScanner.FileType
{
get
{
if (contentCheckClasses == null)
contentCheckClasses = InitCheckClasses<IContentCheck>();
contentCheckClasses ??= InitCheckClasses<IContentCheck>();
return contentCheckClasses ?? Enumerable.Empty<IContentCheck>();
}
}
@@ -54,9 +54,7 @@ namespace BinaryObjectScanner.FileType
{
get
{
if (linearExecutableCheckClasses == null)
linearExecutableCheckClasses = InitCheckClasses<ILinearExecutableCheck>();
linearExecutableCheckClasses ??= InitCheckClasses<ILinearExecutableCheck>();
return linearExecutableCheckClasses ?? Enumerable.Empty<ILinearExecutableCheck>();
}
}
@@ -68,9 +66,7 @@ namespace BinaryObjectScanner.FileType
{
get
{
if (msdosExecutableCheckClasses == null)
msdosExecutableCheckClasses = InitCheckClasses<IMSDOSExecutableCheck>();
msdosExecutableCheckClasses ??= InitCheckClasses<IMSDOSExecutableCheck>();
return msdosExecutableCheckClasses ?? Enumerable.Empty<IMSDOSExecutableCheck>();
}
}
@@ -82,9 +78,7 @@ namespace BinaryObjectScanner.FileType
{
get
{
if (newExecutableCheckClasses == null)
newExecutableCheckClasses = InitCheckClasses<INewExecutableCheck>();
newExecutableCheckClasses ??= InitCheckClasses<INewExecutableCheck>();
return newExecutableCheckClasses ?? Enumerable.Empty<INewExecutableCheck>();
}
}
@@ -96,9 +90,7 @@ namespace BinaryObjectScanner.FileType
{
get
{
if (portableExecutableCheckClasses == null)
portableExecutableCheckClasses = InitCheckClasses<IPortableExecutableCheck>();
portableExecutableCheckClasses ??= InitCheckClasses<IPortableExecutableCheck>();
return portableExecutableCheckClasses ?? Enumerable.Empty<IPortableExecutableCheck>();
}
}
@@ -140,10 +132,8 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
return Detect(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -155,7 +145,11 @@ namespace BinaryObjectScanner.FileType
return null;
// Create the internal queue
#if NET20 || NET35
var protections = new Queue<string>();
#else
var protections = new ConcurrentQueue<string>();
#endif
// Only use generic content checks if we're in debug mode
if (includeDebug)
@@ -190,7 +184,7 @@ namespace BinaryObjectScanner.FileType
protections.AddRange(subProtections.Values.ToArray());
}
return string.Join(";", protections);
return string.Join(";", [.. protections]);
}
#region Check Runners
@@ -202,28 +196,30 @@ namespace BinaryObjectScanner.FileType
/// <param name="stream">Stream to scan the contents of</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public Dictionary<IContentCheck, string>? RunContentChecks(string? file, Stream stream, bool includeDebug)
#else
public ConcurrentDictionary<IContentCheck, string>? RunContentChecks(string? file, Stream stream, bool includeDebug)
#endif
{
// If we have an invalid file
if (string.IsNullOrWhiteSpace(file))
if (string.IsNullOrEmpty(file))
return null;
else if (!File.Exists(file))
return null;
// Read the file contents
byte[] fileContent = new byte[0];
byte[] fileContent = [];
try
{
#if NET40
using (BinaryReader br = new BinaryReader(stream, Encoding.Default))
#if NET20 || NET35 || NET40
using var br = new BinaryReader(stream, Encoding.Default);
#else
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
using var br = new BinaryReader(stream, Encoding.Default, true);
#endif
{
fileContent = br.ReadBytes((int)stream.Length);
if (fileContent == null)
return null;
}
fileContent = br.ReadBytes((int)stream.Length);
if (fileContent == null)
return null;
}
catch (Exception ex)
{
@@ -232,26 +228,51 @@ namespace BinaryObjectScanner.FileType
}
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<IContentCheck, string>();
#else
var protections = new ConcurrentDictionary<IContentCheck, string>();
#endif
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in ContentCheckClasses)
#else
Parallel.ForEach(ContentCheckClasses, checkClass =>
#endif
{
// Get the protection for the class, if possible
var protection = checkClass.CheckContents(file!, fileContent, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
#if NET20 || NET35
continue;
#else
return;
#endif
#if NET20 || NET35
protections[checkClass] = protection!;
}
#else
protections.TryAdd(checkClass, protection!);
});
#endif
return protections;
}
@@ -263,29 +284,58 @@ namespace BinaryObjectScanner.FileType
/// <param name="lex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public Dictionary<ILinearExecutableCheck, string> RunLinearExecutableChecks(string file, Stream stream, LinearExecutable lex, bool includeDebug)
#else
public ConcurrentDictionary<ILinearExecutableCheck, string> RunLinearExecutableChecks(string file, Stream stream, LinearExecutable lex, bool includeDebug)
#endif
{
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<ILinearExecutableCheck, string>();
#else
var protections = new ConcurrentDictionary<ILinearExecutableCheck, string>();
#endif
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in LinearExecutableCheckClasses)
#else
Parallel.ForEach(LinearExecutableCheckClasses, checkClass =>
#endif
{
// Get the protection for the class, if possible
var protection = checkClass.CheckLinearExecutable(file, lex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
#if NET20 || NET35
continue;
#else
return;
#endif
#if NET20 || NET35
protections[checkClass] = protection!;
}
#else
protections.TryAdd(checkClass, protection!);
});
#endif
return protections;
}
@@ -297,29 +347,58 @@ namespace BinaryObjectScanner.FileType
/// <param name="mz">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public Dictionary<IMSDOSExecutableCheck, string> RunMSDOSExecutableChecks(string file, Stream stream, MSDOS mz, bool includeDebug)
#else
public ConcurrentDictionary<IMSDOSExecutableCheck, string> RunMSDOSExecutableChecks(string file, Stream stream, MSDOS mz, bool includeDebug)
#endif
{
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<IMSDOSExecutableCheck, string>();
#else
var protections = new ConcurrentDictionary<IMSDOSExecutableCheck, string>();
#endif
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in MSDOSExecutableCheckClasses)
#else
Parallel.ForEach(MSDOSExecutableCheckClasses, checkClass =>
#endif
{
// Get the protection for the class, if possible
var protection = checkClass.CheckMSDOSExecutable(file, mz, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
#if NET20 || NET35
continue;
#else
return;
#endif
#if NET20 || NET35
protections[checkClass] = protection!;
}
#else
protections.TryAdd(checkClass, protection!);
});
#endif
return protections;
}
@@ -331,29 +410,58 @@ namespace BinaryObjectScanner.FileType
/// <param name="nex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public Dictionary<INewExecutableCheck, string> RunNewExecutableChecks(string file, Stream stream, NewExecutable nex, bool includeDebug)
#else
public ConcurrentDictionary<INewExecutableCheck, string> RunNewExecutableChecks(string file, Stream stream, NewExecutable nex, bool includeDebug)
#endif
{
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<INewExecutableCheck, string>();
#else
var protections = new ConcurrentDictionary<INewExecutableCheck, string>();
#endif
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in NewExecutableCheckClasses)
#else
Parallel.ForEach(NewExecutableCheckClasses, checkClass =>
#endif
{
// Get the protection for the class, if possible
var protection = checkClass.CheckNewExecutable(file, nex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
#if NET20 || NET35
continue;
#else
return;
#endif
#if NET20 || NET35
protections[checkClass] = protection!;
}
#else
protections.TryAdd(checkClass, protection!);
});
#endif
return protections;
}
@@ -365,44 +473,71 @@ namespace BinaryObjectScanner.FileType
/// <param name="pex">Executable to scan</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public Dictionary<IPortableExecutableCheck, string> RunPortableExecutableChecks(string file, Stream stream, PortableExecutable pex, bool includeDebug)
#else
public ConcurrentDictionary<IPortableExecutableCheck, string> RunPortableExecutableChecks(string file, Stream stream, PortableExecutable pex, bool includeDebug)
#endif
{
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<IPortableExecutableCheck, string>();
#else
var protections = new ConcurrentDictionary<IPortableExecutableCheck, string>();
#endif
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in PortableExecutableCheckClasses)
#else
Parallel.ForEach(PortableExecutableCheckClasses, checkClass =>
#endif
{
// Get the protection for the class, if possible
var protection = checkClass.CheckPortableExecutable(file, pex, includeDebug);
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on game engines
if (CheckIfGameEngine(checkClass) && !IncludeGameEngines)
#if NET20 || NET35
continue;
#else
return;
#endif
// If we are filtering on packers
if (CheckIfPacker(checkClass) && !IncludePackers)
#if NET20 || NET35
continue;
#else
return;
#endif
#if NET20 || NET35
protections[checkClass] = protection!;
}
#else
protections.TryAdd(checkClass, protection!);
});
#endif
return protections;
}
#endregion
#endregion
#region Initializers
/// <summary>
/// Initialize all implementations of a type
/// </summary>
private static IEnumerable<T>? InitCheckClasses<T>()
=> InitCheckClasses<T>(typeof(GameEngine._DUMMY).Assembly) ?? Enumerable.Empty<T>()
.Concat(InitCheckClasses<T>(typeof(Packer._DUMMY).Assembly) ?? Enumerable.Empty<T>())
.Concat(InitCheckClasses<T>(typeof(Protection._DUMMY).Assembly) ?? Enumerable.Empty<T>());
private static IEnumerable<T>? InitCheckClasses<T>() =>
InitCheckClasses<T>(typeof(Handler).Assembly) ?? Enumerable.Empty<T>();
/// <summary>
/// Initialize all implementations of a type
@@ -412,11 +547,7 @@ namespace BinaryObjectScanner.FileType
return assembly.GetTypes()?
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)?
.Select(t => (T?)Activator.CreateInstance(t))
#if NET40 || NET452
.Cast<T>() ?? [];
#else
.Cast<T>() ?? Array.Empty<T>();
#endif
}
#endregion

View File

@@ -116,7 +116,7 @@ namespace BinaryObjectScanner.FileType
var filename = file.Path;
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -31,7 +29,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -2,7 +2,9 @@
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
#if NET40_OR_GREATER || NETCOREAPP
using UnshieldSharp.Archive;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -17,15 +19,17 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35
// Not supported for .NET Framework 2.0 or .NET Framework 3.5 due to library support
return null;
#else
try
{
// Create a temp output directory
@@ -43,7 +47,7 @@ namespace BinaryObjectScanner.FileType
Directory.CreateDirectory(directoryName);
(byte[]? fileContents, string? error) = archive.Extract(cfile.FullPath!);
if (fileContents == null || !string.IsNullOrWhiteSpace(error))
if (fileContents == null || !string.IsNullOrEmpty(error))
continue;
using (FileStream fs = File.OpenWrite(tempFile))
@@ -64,6 +68,7 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#endif
}
}
}

View File

@@ -2,7 +2,9 @@
using System.IO;
using System.Text.RegularExpressions;
using BinaryObjectScanner.Interfaces;
#if NET40_OR_GREATER || NETCOREAPP
using UnshieldSharp.Cabinet;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -17,15 +19,17 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35
// Not supported for .NET Framework 2.0 or .NET Framework 3.5 due to library support
return null;
#else
// Get the name of the first cabinet file or header
var directory = Path.GetDirectoryName(file);
string noExtension = Path.GetFileNameWithoutExtension(file);
@@ -98,6 +102,7 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#endif
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NETFRAMEWORK && !NET40
#if NETFRAMEWORK && !NET20 && !NET35 && !NET40
using StormLibSharp;
#endif
@@ -18,17 +18,15 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
// TODO: Add stream opening support
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET40 || NETCOREAPP || NET5_0_OR_GREATER
#if NET20 || NET35 || NET40 || NETCOREAPP || NET5_0_OR_GREATER
// Not supported for .NET Core and modern .NET due to Windows DLL requirements
return null;
#else
@@ -38,7 +36,7 @@ namespace BinaryObjectScanner.FileType
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (MpqArchive mpqArchive = new MpqArchive(file, FileAccess.Read))
using (var mpqArchive = new MpqArchive(file, FileAccess.Read))
{
// Try to open the listfile
string? listfile = null;
@@ -49,7 +47,7 @@ namespace BinaryObjectScanner.FileType
return null;
// Read the listfile in for processing
using (StreamReader sr = new StreamReader(listStream))
using (var sr = new StreamReader(listStream))
{
listfile = sr.ReadToEnd();
}

View File

@@ -98,7 +98,7 @@ namespace BinaryObjectScanner.FileType
var filename = directoryItem.ItemName;
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -31,7 +29,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -129,7 +129,7 @@ namespace BinaryObjectScanner.FileType
// string filename = fileDescriptor.FileName;
// // If we have an invalid output directory
// if (string.IsNullOrWhiteSpace(outputDirectory))
// if (string.IsNullOrEmpty(outputDirectory))
// return false;
// // Create the full output path

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -31,7 +29,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using ICSharpCode.SharpZipLib.Zip.Compression;
#endif
@@ -20,10 +20,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -167,7 +165,16 @@ namespace BinaryObjectScanner.FileType
// Reverse and assemble the filename
parentNames.Reverse();
#if NET20 || NET35
var parentNamesArray = parentNames.Cast<string>().ToArray();
filename = parentNamesArray[0];
for (int i = 1; i < parentNamesArray.Length; i++)
{
filename = Path.Combine(filename, parentNamesArray[i]);
}
#else
filename = Path.Combine(parentNames.Cast<string>().ToArray());
#endif
// Get the file offset
long fileOffset;
@@ -224,7 +231,7 @@ namespace BinaryObjectScanner.FileType
else
{
// Decompress the data
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
data = new byte[outputFileSize];
Inflater inflater = new Inflater();
inflater.SetInput(compressedData);
@@ -235,7 +242,7 @@ namespace BinaryObjectScanner.FileType
}
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path
@@ -250,10 +257,8 @@ namespace BinaryObjectScanner.FileType
try
{
// Open the output file for writing
using (Stream fs = File.OpenWrite(filename))
{
fs.Write(data, 0, data.Length);
}
using Stream fs = File.OpenWrite(filename);
fs.Write(data, 0, data.Length);
}
catch
{

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
#endif
@@ -19,16 +19,14 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
#endif
@@ -19,10 +19,8 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -31,7 +29,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -17,10 +17,8 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Detect(fs, file, includeDebug);
}
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
return Detect(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -33,7 +31,7 @@ namespace BinaryObjectScanner.FileType
{
// Load the current file content
var fileContent = string.Empty;
#if NET40
#if NET20 || NET35 || NET40
using (var sr = new StreamReader(stream, Encoding.Default, true, 1024 * 1024))
#else
using (var sr = new StreamReader(stream, Encoding.Default, true, 1024 * 1024, true))
@@ -123,7 +121,7 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
}
return string.Join(";", protections);
return string.Join(";", [.. protections]);
}
}
}

View File

@@ -107,7 +107,7 @@ namespace BinaryObjectScanner.FileType
}
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -112,7 +112,7 @@ namespace BinaryObjectScanner.FileType
// Get the archive filename
string archiveFileName = item.ArchiveFilenames[directoryItem.DirectoryEntry.ArchiveIndex];
if (string.IsNullOrWhiteSpace(archiveFileName))
if (string.IsNullOrEmpty(archiveFileName))
return false;
// If the archive doesn't exist
@@ -152,11 +152,11 @@ namespace BinaryObjectScanner.FileType
// Create the filename
string filename = $"{directoryItem.Name}.{directoryItem.Extension}";
if (!string.IsNullOrWhiteSpace(directoryItem.Path))
if (!string.IsNullOrEmpty(directoryItem.Path))
filename = Path.Combine(directoryItem.Path, filename);
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -98,7 +98,7 @@ namespace BinaryObjectScanner.FileType
string filename = $"{lump.Name}.lmp";
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Compressors.Xz;
#endif
@@ -18,16 +18,14 @@ 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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Create a temp output directory

View File

@@ -108,7 +108,7 @@ namespace BinaryObjectScanner.FileType
var filename = directoryItem.Name;
// If we have an invalid output directory
if (string.IsNullOrWhiteSpace(outputDirectory))
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path

View File

@@ -1,7 +0,0 @@
namespace BinaryObjectScanner.GameEngine
{
/// <summary>
/// This class exists for reflection purposes and should not be used
/// </summary>
public sealed class _DUMMY { }
}

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -22,9 +24,7 @@ namespace BinaryObjectScanner
{
get
{
if (pathCheckClasses == null)
pathCheckClasses = InitCheckClasses<IPathCheck>();
pathCheckClasses ??= InitCheckClasses<IPathCheck>();
return pathCheckClasses;
}
}
@@ -48,21 +48,37 @@ namespace BinaryObjectScanner
/// <param name="path">Path of the file or directory to check</param>
/// <param name="scanner">Scanner object to use for options and scanning</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public static Dictionary<string, Queue<string>> HandlePathChecks(string path, IEnumerable<string>? files)
#else
public static ConcurrentDictionary<string, ConcurrentQueue<string>> HandlePathChecks(string path, IEnumerable<string>? files)
#endif
{
// Create the output dictionary
#if NET20 || NET35
var protections = new Dictionary<string, Queue<string>>();
#else
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
#endif
// Preprocess the list of files
files = files?.Select(f => f.Replace('\\', '/'))?.ToList();
// Iterate through all checks
#if NET20 || NET35
foreach (var checkClass in PathCheckClasses)
#else
Parallel.ForEach(PathCheckClasses, checkClass =>
#endif
{
var subProtections = checkClass?.PerformCheck(path, files);
if (subProtections != null)
AppendToDictionary(protections, path, subProtections);
#if NET20 || NET35
}
#else
});
#endif
return protections;
}
@@ -79,7 +95,11 @@ namespace BinaryObjectScanner
/// <param name="stream">Stream to scan the contents of</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public static Queue<string>? HandleDetectable(IDetectable impl, string fileName, Stream stream, bool includeDebug)
#else
public static ConcurrentQueue<string>? HandleDetectable(IDetectable impl, string fileName, Stream stream, bool includeDebug)
#endif
{
var protection = impl.Detect(stream, fileName, includeDebug);
return ProcessProtectionString(protection);
@@ -93,7 +113,11 @@ namespace BinaryObjectScanner
/// <param name="stream">Stream to scan the contents of</param>
/// <param name="scanner">Scanner object to use on extractable contents</param>
/// <returns>Set of protections in file, null on error</returns>
#if NET20 || NET35
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
#else
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
#endif
{
// If the extractable file itself fails
try
@@ -135,14 +159,22 @@ namespace BinaryObjectScanner
/// <param name="impl">IPathCheck class representing the file type</param>
/// <param name="path">Path of the file or directory to check</param>
/// <returns>Set of protections in path, null on error</returns>
#if NET20 || NET35
private static Queue<string>? PerformCheck(this IPathCheck impl, string? path, IEnumerable<string>? files)
#else
private static ConcurrentQueue<string>? PerformCheck(this IPathCheck impl, string? path, IEnumerable<string>? files)
#endif
{
// If we have an invalid path
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return null;
// Setup the output dictionary
#if NET20 || NET35
var protections = new Queue<string>();
#else
var protections = new ConcurrentQueue<string>();
#endif
// If we have a file path
if (File.Exists(path))
@@ -171,12 +203,8 @@ namespace BinaryObjectScanner
/// <summary>
/// Initialize all implementations of a type
/// </summary>
private static IEnumerable<T?> InitCheckClasses<T>()
{
return InitCheckClasses<T>(typeof(GameEngine._DUMMY).Assembly)
.Concat(InitCheckClasses<T>(typeof(Packer._DUMMY).Assembly))
.Concat(InitCheckClasses<T>(typeof(Protection._DUMMY).Assembly));
}
private static IEnumerable<T?> InitCheckClasses<T>() =>
InitCheckClasses<T>(typeof(Handler).Assembly);
/// <summary>
/// Initialize all implementations of a type
@@ -185,11 +213,7 @@ namespace BinaryObjectScanner
{
return assembly.GetTypes()?
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)?
#if NET40 || NET452
.Select(t => (T?)Activator.CreateInstance(t)) ?? [];
#else
.Select(t => (T?)Activator.CreateInstance(t)) ?? Array.Empty<T>();
#endif
}
#endregion
@@ -201,14 +225,22 @@ namespace BinaryObjectScanner
/// </summary>
/// <param name="protection">Protection string to process</param>
/// <returns>Set of protections parsed, null on error</returns>
#if NET20 || NET35
private static Queue<string>? ProcessProtectionString(string? protection)
#else
private static ConcurrentQueue<string>? ProcessProtectionString(string? protection)
#endif
{
// If we have an invalid protection string
if (string.IsNullOrWhiteSpace(protection))
if (string.IsNullOrEmpty(protection))
return null;
// Setup the output queue
#if NET20 || NET35
var protections = new Queue<string>();
#else
var protections = new ConcurrentQueue<string>();
#endif
// If we have an indicator of multiple protections
if (protection!.Contains(";"))

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
namespace BinaryObjectScanner.Interfaces
@@ -17,7 +19,11 @@ namespace BinaryObjectScanner.Interfaces
/// <param name="path">Path to check for protection indicators</param>
/// <param name="files">Enumerable of strings representing files in a directory</param>
/// <remarks>This can do some limited content checking as well, but it's suggested to use a content check instead, if possible</remarks>
#if NET20 || NET35
Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
#else
ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
#endif
/// <summary>
/// Check a file path for protections based on path name

View File

@@ -1,19 +0,0 @@
#if NET40
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System
{
/// <summary>Defines a provider for progress updates.</summary>
/// <typeparam name="T">The type of progress update value.</typeparam>
/// <see href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/IProgress.cs"/>
public interface IProgress<in T>
{
/// <summary>Reports a progress update.</summary>
/// <param name="value">The value of the updated progress.</param>
void Report(T value);
}
}
#endif

View File

@@ -29,7 +29,7 @@ namespace BinaryObjectScanner.Packer
// {
// var matchers = GenerateMatchers();
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// if (!string.IsNullOrEmpty(match))
// return match;
// }
@@ -42,7 +42,7 @@ namespace BinaryObjectScanner.Packer
{
var matchers = GenerateMatchers();
var match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -78,7 +78,7 @@ namespace BinaryObjectScanner.Packer
{
#region No Wildcards (Long)
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x92, 0x1A, 0x44, 0x00, 0xB8, 0x8C, 0x1A,
@@ -87,7 +87,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0xC4, 0x1D, 0x44,
}, "ASPack 1.00b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
@@ -101,7 +101,7 @@ namespace BinaryObjectScanner.Packer
0x44, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.01b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
@@ -110,7 +110,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x9C, 0x2E, 0x44
}, "ASPack 1.01b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
@@ -124,7 +124,7 @@ namespace BinaryObjectScanner.Packer
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.02b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
@@ -134,7 +134,7 @@ namespace BinaryObjectScanner.Packer
0x15, 0xFE, 0x85, 0x74, 0x7C, 0x43
}, "ASPack 1.02b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x8A, 0x1C, 0x40, 0x00, 0xB9, 0x9E, 0x00,
@@ -142,14 +142,14 @@ namespace BinaryObjectScanner.Packer
0x8B, 0xF7, 0x33
}, "ASPack 1.02b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
0x43, 0x00, 0x03, 0xC5
}, "ASPack 1.02b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xAE, 0x98, 0x43, 0x00, 0xB8, 0xA8, 0x98,
@@ -158,7 +158,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x0E, 0x9D, 0x43
}, "ASPack 1.03b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xCE, 0x3A, 0x44, 0x00, 0xB8, 0xC8, 0x3A,
@@ -167,7 +167,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0xAC, 0x3E, 0x44
}, "ASPack 1.05b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
@@ -181,7 +181,7 @@ namespace BinaryObjectScanner.Packer
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.06.01b (DLL)"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
@@ -191,7 +191,7 @@ namespace BinaryObjectScanner.Packer
0x15, 0xFE, 0x85, 0x6E, 0xAD, 0x43
}, "ASPack 1.06.01b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, 0xD9,
@@ -205,7 +205,7 @@ namespace BinaryObjectScanner.Packer
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.07b (DLL)"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xEB, 0x03, 0x5D, 0xFF, 0xE5, 0xE8, 0xF8,
0xFF, 0xFF, 0xFF, 0x81, 0xED, 0x1B, 0x6A, 0x44,
@@ -213,7 +213,7 @@ namespace BinaryObjectScanner.Packer
0x2B, 0x9D, 0x2A
}, "ASPack 1.08"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
@@ -227,7 +227,7 @@ namespace BinaryObjectScanner.Packer
0x53, 0x50, 0xFF, 0x95, 0x90, 0x51, 0x44, 0x00
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
@@ -236,20 +236,20 @@ namespace BinaryObjectScanner.Packer
0x00, 0x89, 0x9D, 0xBB, 0x4E
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
0x44, 0x00, 0x03, 0xDD
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x33,
0x87, 0xDB, 0x90, 0x00
}, "ASPack 2.00.01"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
@@ -257,34 +257,34 @@ namespace BinaryObjectScanner.Packer
0xFF, 0x03, 0xDD, 0x81, 0xEB
}, "ASPack 2.1"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
0xC3, 0xE9, 0x3D, 0x04, 0x00, 0x00
}, "ASPack 2.11b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
0x5D, 0x55
}, "ASPack 2.11b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
0xC3, 0xE9, 0x59, 0x04, 0x00, 0x00
}, "ASPack 2.11c"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xCD, 0x20,
0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x2B, 0xC9,
0x58, 0x74, 0x02
}, "ASPack 2.11d"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
@@ -294,7 +294,7 @@ namespace BinaryObjectScanner.Packer
#region Wildcards (Long)
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0x3E, 0xD9, 0x43, null, 0xB8, 0x38, null,
@@ -308,7 +308,7 @@ namespace BinaryObjectScanner.Packer
0x43, null, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.00b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0xD2, 0x2A, 0x44, null, 0xB8, 0xCC, 0x2A,
@@ -317,7 +317,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x9C, 0x2E, 0x44
}, "ASPack 1.01b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0xCE, 0x3A, 0x44, null, 0xB8, 0xC8, 0x3A,
@@ -326,7 +326,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0xAC, 0x3E, 0x44
}, "ASPack 1.01b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, null,
@@ -340,13 +340,13 @@ namespace BinaryObjectScanner.Packer
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
}, "ASPack 1.02a -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0x06, null, null, null, 0x64, 0xA0, 0x23
}, "ASPack 1.02a"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0x96, 0x78, 0x43, null, 0xB8, 0x90, 0x78,
@@ -355,7 +355,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x74, 0x7C, 0x43
}, "ASPack 1.02b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0xAE, 0x98, 0x43, null, 0xB8, 0xA8, 0x98,
@@ -364,7 +364,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x0E, 0x9D, 0x43
}, "ASPack 1.03b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, null, null, null, null, 0xE8, 0x0D, null,
@@ -372,7 +372,7 @@ namespace BinaryObjectScanner.Packer
null, null, null, null, null, null, null, 0x58
}, "ASPack 1.03b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, null, null, null, 0x00, 0xB8, null, null,
@@ -381,7 +381,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x08, 0x9D, null, 0x00, 0x00
}, "ASPack 1.04b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, null, null, null, null, 0xB8, null, null,
@@ -390,7 +390,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x08, 0x9D
}, "ASPack 1.04b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, null, null, null, null, 0xB8, null, null,
@@ -399,7 +399,7 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x01, 0xDE
}, "ASPack 1.04b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0xEA, 0xA8, 0x43, null, 0xB8, 0xE4, 0xA8,
@@ -408,28 +408,28 @@ namespace BinaryObjectScanner.Packer
0x80, 0xBD, 0x6E, 0xAD, 0x43
}, "ASPack 1.06.1b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x90, 0x61, 0xBE, null, null, null, null, 0x8D,
0xBE, null, null, null, null, 0x57, 0x83, 0xCD,
0xFF
}, "ASPack 1.06.1b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
null, null, null, null, null, 0xB8, null, null,
null, null, 0x03, 0xC5
}, "ASPack 1.07b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, null, null, null, null, 0x60, 0xE8, 0x2B,
0x03, 0x00, 0x00
}, "ASPack 1.07b"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
@@ -438,7 +438,7 @@ namespace BinaryObjectScanner.Packer
0x2B, 0x9D
}, "ASPack 1.08.01"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
@@ -447,7 +447,7 @@ namespace BinaryObjectScanner.Packer
0x2B, 0x9D
}, "ASPack 1.08.01"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
@@ -456,7 +456,7 @@ namespace BinaryObjectScanner.Packer
0x2B, 0x9D, 0x72
}, "ASPack 1.08.02"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
null, null, null, null, null, 0xBB, null, null,
@@ -465,14 +465,14 @@ namespace BinaryObjectScanner.Packer
0x00, 0x89, 0x9D, 0xBB, 0x4E
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
null, null, null, null, null, 0xBB, null, null,
null, null, 0x03, 0xDD
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x55, 0x57, 0x51, 0x53, 0xE8, null, null, null,
null, 0x5D, 0x8B, 0xC5, 0x81, 0xED, null, null,
@@ -481,27 +481,27 @@ namespace BinaryObjectScanner.Packer
null, 0x0F, 0xB6
}, "ASPack 1.08.03"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE9, null, null, null, null, 0xEF, 0x40,
0x03, 0xA7, 0x07, 0x8F, 0x07, 0x1C, 0x37, 0x5D,
0x43, 0xA7, 0x04, 0xB9, 0x2C, 0x3A
}, "ASPack 1.08.x"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
0xC3, 0xE9, null, 0x04, 0x00, 0x00
}, "ASPack 2.11.x -> Alexey Solodovnikov"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
null, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
}, "ASPack 2.12 (without Poly) -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
@@ -518,7 +518,7 @@ namespace BinaryObjectScanner.Packer
0xFF, 0x95, 0x48, 0x0F
}, "ASPack 2.12b -> Solodovnikov Alexey"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
@@ -567,7 +567,7 @@ namespace BinaryObjectScanner.Packer
0x08
}, "ASPack 2.2 -> Alexey Solodovnikov & StarForce * 2009408"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
@@ -580,7 +580,7 @@ namespace BinaryObjectScanner.Packer
#region 2.xx (Long)
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0xA8, 0x03, 0x00, 0x00, 0x61, 0x75, 0x08, 0xB8,
0x01, 0x00, 0x00, 0x00, 0xC2, 0x0C, 0x00, 0x68,
@@ -589,7 +589,7 @@ namespace BinaryObjectScanner.Packer
0x00, 0x51, 0x50, 0xFF, 0x95
}, "ASPack 2.xx"),
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0xA8, 0x03, null, null, 0x61, 0x75, 0x08, 0xB8,
0x01, null, null, null, 0xC2, 0x0C, null, 0x68,
@@ -602,55 +602,55 @@ namespace BinaryObjectScanner.Packer
#region Short
new ContentMatchSet(new byte?[] { 0x75, 0x00, 0xE9 }, "ASPack 1.05b"),
new(new byte?[] { 0x75, 0x00, 0xE9 }, "ASPack 1.05b"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new(new byte?[] { 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new(new byte?[] { 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new(new byte?[] { 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new(new byte?[] { 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08"),
new(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new(new byte?[] { 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new(new byte?[] { 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new(new byte?[] { 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
new(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
new(new byte?[] { 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x41, 0x06, 0x00, 0x00, 0xEB, 0x41 }, "ASPack 1.08.04"),
new(new byte?[] { 0x60, 0xE8, 0x41, 0x06, 0x00, 0x00, 0xEB, 0x41 }, "ASPack 1.08.04"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, null, null, null, 0xEB }, "ASPack 1.08.04"),
new(new byte?[] { 0x60, 0xE8, null, null, null, null, 0xEB }, "ASPack 1.08.04"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x70, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.00"),
new(new byte?[] { 0x60, 0xE8, 0x70, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.00"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x48, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.00.00"),
new(new byte?[] { 0x60, 0xE8, 0x48, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.00.00"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.01"),
new(new byte?[] { 0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.01"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.x -> Alexey Solodovnikov"),
new(new byte?[] { 0x60, 0xE8, null, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.x -> Alexey Solodovnikov"),
new ContentMatchSet(new byte?[] { 0x60, 0xE9, 0x3D, 0x04, 0x00, 0x00 }, "ASPack 2.11"),
new(new byte?[] { 0x60, 0xE9, 0x3D, 0x04, 0x00, 0x00 }, "ASPack 2.11"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0xF9, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.11"),
new(new byte?[] { 0x60, 0xE8, 0xF9, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.11"),
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"),
new(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"),
#endregion
};

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using ICSharpCode.SharpZipLib.Zip.Compression;
#endif
using SabreTools.Matching;
@@ -32,7 +32,7 @@ namespace BinaryObjectScanner.Packer
{
var matchers = new List<ContentMatchSet>
{
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92,
0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92,
@@ -44,7 +44,7 @@ namespace BinaryObjectScanner.Packer
};
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -57,10 +57,8 @@ namespace BinaryObjectScanner.Packer
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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
@@ -90,7 +88,7 @@ namespace BinaryObjectScanner.Packer
try
{
// Inflate the data into the buffer
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
Inflater inflater = new Inflater();
inflater.SetInput(payload);
data = new byte[payload.Length * 4];

View File

@@ -21,7 +21,7 @@ namespace BinaryObjectScanner.Packer
var contentMatchSets = new List<ContentMatchSet>
{
// ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;??
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B,
0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B,

View File

@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.Packer
if (nex.Model.Stub?.Header?.Reserved2?[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2?[5] == 0x6F6E)
{
string version = GetOldVersion(file, nex);
if (!string.IsNullOrWhiteSpace(version))
if (!string.IsNullOrEmpty(version))
return $"Inno Setup {version}";
return "Inno Setup (Unknown Version)";
@@ -85,7 +85,7 @@ namespace BinaryObjectScanner.Packer
var matchers = new List<ContentMatchSet>
{
// "rDlPtS02" + (char)0x87 + "eVx"
new ContentMatchSet(new byte?[] { 0x72, 0x44, 0x6C, 0x50, 0x74, 0x53, 0x30, 0x32, 0x87, 0x65, 0x56, 0x78 }, "1.2.16 or earlier"),
new(new byte?[] { 0x72, 0x44, 0x6C, 0x50, 0x74, 0x53, 0x30, 0x32, 0x87, 0x65, 0x56, 0x78 }, "1.2.16 or earlier"),
};
return MatchUtil.GetFirstMatch(file, data, matchers, false) ?? "Unknown 1.X";

View File

@@ -69,7 +69,7 @@ namespace BinaryObjectScanner.Packer
{
// Check the internal versions
var version = pex.GetInternalVersion();
if (!string.IsNullOrWhiteSpace(version))
if (!string.IsNullOrEmpty(version))
return $"v{version}";
return string.Empty;

View File

@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.Packer
return null;
var description = pex.AssemblyDescription;
if (!string.IsNullOrWhiteSpace(description) && description!.StartsWith("Nullsoft Install System"))
if (!string.IsNullOrEmpty(description) && description!.StartsWith("Nullsoft Install System"))
return $"NSIS {description.Substring("Nullsoft Install System".Length).Trim()}";
// Get the .data/DATA section strings, if they exist

View File

@@ -3,7 +3,7 @@ using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Readers;
@@ -38,16 +38,14 @@ namespace BinaryObjectScanner.Packer
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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Should be using stream instead of file, but stream fails to extract anything. My guess is that the executable portion of the archive is causing stream to fail, but not file.

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
#endif
@@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Packer
// Try to get a known version
var version = GetNEHeaderVersion(nex);
if (!string.IsNullOrWhiteSpace(version))
if (!string.IsNullOrEmpty(version))
return $"WinZip SFX {version}";
return $"WinZip SFX Unknown Version (16-bit)";
@@ -49,7 +49,7 @@ namespace BinaryObjectScanner.Packer
if (pex.Model.ExportTable?.ExportDirectoryTable != null)
{
var version = GetPEExportDirectoryVersion(pex);
if (!string.IsNullOrWhiteSpace(version))
if (!string.IsNullOrEmpty(version))
return $"WinZip SFX {version}";
}
@@ -68,16 +68,14 @@ namespace BinaryObjectScanner.Packer
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.Read);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
#if NET462_OR_GREATER || NETCOREAPP
try
{
// Should be using stream instead of file, but stream fails to extract anything. My guess is that the executable portion of the archive is causing stream to fail, but not file.
@@ -693,37 +691,23 @@ namespace BinaryObjectScanner.Packer
|| sfxFileName == "WZIPSE32.exe" || sfxFileName == "SI32LPG.SFX"
|| sfxFileName == "ST32E.WZE")
{
switch (sfxTimeDateStamp)
return sfxTimeDateStamp switch
{
case 842636344:
return "2.0 (32-bit)";
case 865370756:
return "2.1 RC2 (32-bit)";
case 869059925:
return "2.1 (32-bit)";
case 979049321:
return "2.2.4003";
case 1149714685:
return "3.0.7158";
case 1185211734:
return "3.1.7556";
case 1185211920:
return "3.1.7556";
case 1235490556:
return "4.0.8421";
case 1235490757:
return "4.0.8421";
case 1235490687:
return "4.0.8421"; // 3.1.8421.0, SI32LPG?
case 1257193383:
return "4.0.8672"; // 3.1.8672.0
case 1257193543:
return "4.0.8672";
case 1470410848:
return "4.0.12218"; // 4.0.1221.0
default:
return $"{assemblyVersion} (32-bit)";
}
842636344 => "2.0 (32-bit)",
865370756 => "2.1 RC2 (32-bit)",
869059925 => "2.1 (32-bit)",
979049321 => "2.2.4003",
1149714685 => "3.0.7158",
1185211734 => "3.1.7556",
1185211920 => "3.1.7556",
1235490556 => "4.0.8421",
1235490757 => "4.0.8421",
1235490687 => "4.0.8421",// 3.1.8421.0, SI32LPG?
1257193383 => "4.0.8672",// 3.1.8672.0
1257193543 => "4.0.8672",
1470410848 => "4.0.12218",// 4.0.1221.0
_ => $"{assemblyVersion} (32-bit)",
};
}
// Personal Edition
@@ -731,152 +715,90 @@ namespace BinaryObjectScanner.Packer
|| sfxFileName == "wzsepe32.exe" || sfxFileName == "SI32PE.SFX"
|| sfxFileName == "SI32LPE.SFX")
{
switch (sfxTimeDateStamp)
return sfxTimeDateStamp switch
{
case 845061601:
return "Personal Edition (32-bit)"; // TODO: Find version
case 868303343:
return "Personal Edition (32-bit)"; // TODO: Find version
case 868304170:
return "Personal Edition (32-bit)"; // TODO: Find version
case 906039079:
return "Personal Edition 2.2.1260 (32-bit)";
case 906040543:
return "Personal Edition 2.2.1260 (32-bit)";
case 908628435:
return "Personal Edition 2.2.1285 (32-bit)";
case 908628785:
return "Personal Edition 2.2.1285 (32-bit)";
case 956165981:
return "Personal Edition 2.2.3063";
case 956166038:
return "Personal Edition 2.2.3063";
case 1006353695:
return "Personal Edition 2.2.4325";
case 1006353714:
return "Personal Edition 2.2.4325"; // 8.1.0.0
case 1076515698:
return "Personal Edition 2.2.6028";
case 1076515784:
return "Personal Edition 2.2.6028"; // 9.0.6028.0
case 1092688561:
return "Personal Edition 2.2.6224";
case 1092688645:
return "Personal Edition 2.2.6224"; // 9.0.6224.0
case 1125074095:
return "Personal Edition 2.2.6604";
case 1125074162:
return "Personal Edition 2.2.6604"; // 10.0.6604.0
case 1130153399:
return "Personal Edition 2.2.6663";
case 1130153428:
return "Personal Edition 2.2.6663"; // 10.0.6663.0
case 1149714176:
return "Personal Edition 3.0.7158";
case 1163137967:
return "Personal Edition 3.0.7305";
case 1163137994:
return "Personal Edition 3.0.7313"; // 11.0.7313.0
case 1176345383:
return "Personal Edition 3.0.7452";
case 1176345423:
return "Personal Edition 3.1.7466"; // 11.1.7466.0
case 1184106698:
return "Personal Edition 3.1.7556";
case 1207280880:
return "Personal Edition 4.0.8060"; // 2.3.7382.0
case 1207280892:
return "Personal Edition 4.0.8094"; // 11.2.8094.0
case 1220904506:
return "Personal Edition 4.0.8213"; // 2.3.7382.0
case 1220904518:
return "Personal Edition 4.0.8252"; // 12.0.8252.0
case 1235490648:
return "Personal Edition 4.0.8421"; // 3.1.8421.0
case 1242049399:
return "Personal Edition 4.0.8497"; // 12.1.8497.0
case 1257193469:
return "Personal Edition 4.0.8672"; // 3.1.8672.0, SI32LPE?
default:
return $"Personal Edition {assemblyVersion} (32-bit)";
}
845061601 => "Personal Edition (32-bit)",// TODO: Find version
868303343 => "Personal Edition (32-bit)",// TODO: Find version
868304170 => "Personal Edition (32-bit)",// TODO: Find version
906039079 => "Personal Edition 2.2.1260 (32-bit)",
906040543 => "Personal Edition 2.2.1260 (32-bit)",
908628435 => "Personal Edition 2.2.1285 (32-bit)",
908628785 => "Personal Edition 2.2.1285 (32-bit)",
956165981 => "Personal Edition 2.2.3063",
956166038 => "Personal Edition 2.2.3063",
1006353695 => "Personal Edition 2.2.4325",
1006353714 => "Personal Edition 2.2.4325",// 8.1.0.0
1076515698 => "Personal Edition 2.2.6028",
1076515784 => "Personal Edition 2.2.6028",// 9.0.6028.0
1092688561 => "Personal Edition 2.2.6224",
1092688645 => "Personal Edition 2.2.6224",// 9.0.6224.0
1125074095 => "Personal Edition 2.2.6604",
1125074162 => "Personal Edition 2.2.6604",// 10.0.6604.0
1130153399 => "Personal Edition 2.2.6663",
1130153428 => "Personal Edition 2.2.6663",// 10.0.6663.0
1149714176 => "Personal Edition 3.0.7158",
1163137967 => "Personal Edition 3.0.7305",
1163137994 => "Personal Edition 3.0.7313",// 11.0.7313.0
1176345383 => "Personal Edition 3.0.7452",
1176345423 => "Personal Edition 3.1.7466",// 11.1.7466.0
1184106698 => "Personal Edition 3.1.7556",
1207280880 => "Personal Edition 4.0.8060",// 2.3.7382.0
1207280892 => "Personal Edition 4.0.8094",// 11.2.8094.0
1220904506 => "Personal Edition 4.0.8213",// 2.3.7382.0
1220904518 => "Personal Edition 4.0.8252",// 12.0.8252.0
1235490648 => "Personal Edition 4.0.8421",// 3.1.8421.0
1242049399 => "Personal Edition 4.0.8497",// 12.1.8497.0
1257193469 => "Personal Edition 4.0.8672",// 3.1.8672.0, SI32LPE?
_ => $"Personal Edition {assemblyVersion} (32-bit)",
};
}
// Software Installation
else if (sfxFileName == "VW95SRE.SFX" || sfxFileName == "SI32E.SFX"
|| sfxFileName == "SI32E.WZE")
{
switch (sfxTimeDateStamp)
return sfxTimeDateStamp switch
{
case 842636381:
return "Software Installation 2.0 (32-bit)";
case 865370800:
return "Software Installation 2.1 RC2 (32-bit)";
case 869059963:
return "Software Installation 2.1 (32-bit)";
case 893107697:
return "Software Installation 2.2.1110 (32-bit)";
case 952007369:
return "Software Installation 2.2.3063";
case 1006352634:
return "Software Installation 2.2.4325"; // +Personal Edition?
case 979049345:
return "Software Installation 2.2.4403";
case 1026227373:
return "Software Installation 2.2.5196"; // +Personal Edition?
case 1090582390:
return "Software Installation 2.2.6202"; // +Personal Edition?
case 1149714757:
return "Software Installation 3.0.7158";
case 1154357628:
return "Software Installation 3.0.7212";
case 1175234637:
return "Software Installation 3.0.7454";
case 1185211802:
return "Software Installation 3.1.7556";
case 1470410906:
return "Software Installation 4.0.12218"; // 4.0.1221.0
default:
return $"Software Installation {assemblyVersion} (32-bit)";
}
842636381 => "Software Installation 2.0 (32-bit)",
865370800 => "Software Installation 2.1 RC2 (32-bit)",
869059963 => "Software Installation 2.1 (32-bit)",
893107697 => "Software Installation 2.2.1110 (32-bit)",
952007369 => "Software Installation 2.2.3063",
1006352634 => "Software Installation 2.2.4325",// +Personal Edition?
979049345 => "Software Installation 2.2.4403",
1026227373 => "Software Installation 2.2.5196",// +Personal Edition?
1090582390 => "Software Installation 2.2.6202",// +Personal Edition?
1149714757 => "Software Installation 3.0.7158",
1154357628 => "Software Installation 3.0.7212",
1175234637 => "Software Installation 3.0.7454",
1185211802 => "Software Installation 3.1.7556",
1470410906 => "Software Installation 4.0.12218",// 4.0.1221.0
_ => $"Software Installation {assemblyVersion} (32-bit)",
};
}
switch (sfxFileName)
return sfxFileName switch
{
// Standard
case "VW95SE.SFX":
return "Unknown Version (32-bit)"; // TODO: Find starting version
case "ST32E.SFX":
return "Unknown Version (32-bit)"; // TODO: Find starting version
case "WZIPSE32.exe":
return "Unknown Version (32-bit)"; // TODO: Find starting version
case "SI32LPG.SFX":
return "Unknown Version (32-bit)"; // TODO: Find starting version
case "ST32E.WZE":
return "Unknown Version (32-bit)"; // TODO: Find starting version
"VW95SE.SFX" => "Unknown Version (32-bit)",// TODO: Find starting version
"ST32E.SFX" => "Unknown Version (32-bit)",// TODO: Find starting version
"WZIPSE32.exe" => "Unknown Version (32-bit)",// TODO: Find starting version
"SI32LPG.SFX" => "Unknown Version (32-bit)",// TODO: Find starting version
"ST32E.WZE" => "Unknown Version (32-bit)",// TODO: Find starting version
// Personal Edition
case "VW95LE.SFX":
return "Unknown Version before Personal Edition Build 1285 (32-bit)";
case "PE32E.SFX":
return "Unknown Version after Personal Edition Build 1285 (32-bit)";
case "wzsepe32.exe":
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
case "SI32PE.SFX":
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
case "SI32LPE.SFX":
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
"VW95LE.SFX" => "Unknown Version before Personal Edition Build 1285 (32-bit)",
"PE32E.SFX" => "Unknown Version after Personal Edition Build 1285 (32-bit)",
"wzsepe32.exe" => "Unknown Version Personal Edition (32-bit)",// TODO: Find starting version
"SI32PE.SFX" => "Unknown Version Personal Edition (32-bit)",// TODO: Find starting version
"SI32LPE.SFX" => "Unknown Version Personal Edition (32-bit)",// TODO: Find starting version
// Software Installation
case "VW95SRE.SFX":
return "Unknown Version before Software Installation 2.1 (32-bit)";
case "SI32E.SFX":
return "Unknown Version after Software Installation 2.1 (32-bit)";
case "SI32E.WZE":
return "Unknown Version Software Installation (32-bit)"; // TODO: Find starting version
}
return null;
"VW95SRE.SFX" => "Unknown Version before Software Installation 2.1 (32-bit)",
"SI32E.SFX" => "Unknown Version after Software Installation 2.1 (32-bit)",
"SI32E.WZE" => "Unknown Version Software Installation (32-bit)",// TODO: Find starting version
_ => null,
};
}
}
}

View File

@@ -30,10 +30,10 @@ namespace BinaryObjectScanner.Packer
var neMatchSets = new List<ContentMatchSet>
{
// WiseInst
new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x49, 0x6E, 0x73, 0x74 }, "Wise Installation Wizard Module"),
new(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x49, 0x6E, 0x73, 0x74 }, "Wise Installation Wizard Module"),
// WiseMain
new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Wise Installation Wizard Module"),
new(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Wise Installation Wizard Module"),
};
return MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);

View File

@@ -1,7 +0,0 @@
namespace BinaryObjectScanner.Packer
{
/// <summary>
/// This class exists for reflection purposes and should not be used
/// </summary>
public sealed class _DUMMY { }
}

View File

@@ -1,4 +1,4 @@
#if NET40
#if NET20 || NET35 || NET40
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
@@ -50,10 +50,7 @@ namespace System
/// <exception cref="ArgumentNullException">The <paramref name="handler"/> is null (<see langword="Nothing" /> in Visual Basic).</exception>
public Progress(Action<T> handler) : this()
{
if (handler == null)
throw new ArgumentNullException(nameof(handler));
_handler = handler;
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
/// <summary>Raised for each reported progress value.</summary>
@@ -103,7 +100,7 @@ namespace System
internal static class ProgressStatics
{
/// <summary>A default synchronization context that targets the ThreadPool.</summary>
internal static readonly SynchronizationContext DefaultContext = new SynchronizationContext();
internal static readonly SynchronizationContext DefaultContext = new();
}
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// " " + (char)0xC2 + (char)0x16 + (char)0x00 + (char)0xA8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0xB8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x86 + (char)0xC8 + (char)0x16 + (char)0x00 + (char)0x9A + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x10 + (char)0xC2 + (char)0x16 + (char)0x00
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00,
0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00,

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -51,7 +53,7 @@ namespace BinaryObjectScanner.Protection
{
// Found in "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", "Asc006.exe", and "AscLM.cpl" (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
// ÿÿÿÿ\\.\ASCLM
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0x5C, 0x2E, 0x5C,
0x41, 0x53, 0x43, 0x4C, 0x4D
@@ -59,7 +61,7 @@ namespace BinaryObjectScanner.Protection
};
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -67,14 +69,18 @@ namespace BinaryObjectScanner.Protection
}
/// <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 Redump entry 73521/IA item "Nova_HoyleCasino99USA".
new PathMatchSet(new PathMatch("AscLM.cpl", useEndsWith: true), "AegiSoft License Manager"),
new PathMatchSet(new PathMatch("AscLM.vxd", useEndsWith: true), "AegiSoft License Manager"),
new PathMatchSet(new PathMatch("AscLMd.vxd", useEndsWith: true), "AegiSoft License Manager"),
new(new FilePathMatch("AscLM.cpl"), "AegiSoft License Manager"),
new(new FilePathMatch("AscLM.vxd"), "AegiSoft License Manager"),
new(new FilePathMatch("AscLMd.vxd"), "AegiSoft License Manager"),
// There are a few other files present, but the file names on their own may be too overmatching. Due to the small sample size, it's not sure if these files are always present together.
// These files are "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", and "Asc006.exe" (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA").
@@ -89,9 +95,9 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA".
new PathMatchSet(new PathMatch("AscLM.cpl", useEndsWith: true), "AegiSoft License Manager"),
new PathMatchSet(new PathMatch("AscLM.vxd", useEndsWith: true), "AegiSoft License Manager"),
new PathMatchSet(new PathMatch("AscLMd.vxd", useEndsWith: true), "AegiSoft License Manager"),
new(new FilePathMatch("AscLM.cpl"), "AegiSoft License Manager"),
new(new FilePathMatch("AscLM.vxd"), "AegiSoft License Manager"),
new(new FilePathMatch("AscLMd.vxd"), "AegiSoft License Manager"),
// There are a few other files present, but the file names on their own may be too overmatching. Due to the small sample size, it's not sure if these files are always present together.
// These files are "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", and "Asc006.exe" (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA").

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -16,11 +18,15 @@ namespace BinaryObjectScanner.Protection
public class AlphaDVD : IPathCheck
{
/// <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>
{
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("PlayDVD.exe"), "Alpha-DVD (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -31,7 +37,7 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD (Unconfirmed - Please report to us on Github"),
new(new FilePathMatch("PlayDVD.exe"), "Alpha-DVD (Unconfirmed - Please report to us on Github"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -13,19 +15,23 @@ namespace BinaryObjectScanner.Protection
public class Bitpool : IPathCheck
{
/// <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>
{
new PathMatchSet(new PathMatch("bitpool.rsc", useEndsWith: true), "Bitpool"),
new PathMatchSet(new FilePathMatch("CD.IDX"), "Bitpool"),
new(new FilePathMatch("bitpool.rsc"), "Bitpool"),
new(new FilePathMatch("CD.IDX"), "Bitpool"),
// Completely empty file present on multiple discs with Bitpool (Redump entries 52626 and 50229).
new PathMatchSet(new PathMatch("LEADOUT.OFS", useEndsWith: true), "Bitpool"),
new(new FilePathMatch("LEADOUT.OFS"), "Bitpool"),
// A set of 4 identically sized (within the same game, not between games), corrupted/padded files present in several games (Redump entries 31782 and 35476).
// Both examples with only having the first letter uppercase and as the whole file name being uppercase have been seen.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new FilePathMatch("Crc_a"),
new FilePathMatch("Crc_b"),
@@ -42,11 +48,11 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("bitpool.rsc", useEndsWith: true), "Bitpool"),
new PathMatchSet(new FilePathMatch("CD.IDX"), "Bitpool"),
new(new FilePathMatch("bitpool.rsc"), "Bitpool"),
new(new FilePathMatch("CD.IDX"), "Bitpool"),
// Completely empty file present on multiple discs with Bitpool (Redump entries 52626 and 50229).
new PathMatchSet(new PathMatch("LEADOUT.OFS", useEndsWith: true), "Bitpool"),
new(new FilePathMatch("LEADOUT.OFS"), "Bitpool"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -130,14 +132,18 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Investigate reference to "bbz650.tmp" in "Byteshield.dll" (Redump entry 6236)
// Files with the ".bbz" extension are associated with ByteShield, but the extenstion is known to be used in other places as well.
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield Component Module"),
new PathMatchSet(new PathMatch("Byteshield.ini", useEndsWith: true), "ByteShield"),
new(new FilePathMatch("Byteshield.dll"), "ByteShield Component Module"),
new(new FilePathMatch("Byteshield.ini"), "ByteShield"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -150,8 +156,8 @@ namespace BinaryObjectScanner.Protection
// Files with the ".bbz" extension are associated with ByteShield, but the extenstion is known to be used in other places as well.
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("Byteshield.dll", useEndsWith: true), "ByteShield Component Module"),
new PathMatchSet(new PathMatch("Byteshield.ini", useEndsWith: true), "ByteShield"),
new(new FilePathMatch("Byteshield.dll"), "ByteShield Component Module"),
new(new FilePathMatch("Byteshield.ini"), "ByteShield"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -76,14 +78,14 @@ namespace BinaryObjectScanner.Protection
{
// TODO: Remove from here once it's confirmed that no PE executables contain this string
// CD-Cops, ver.
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
}, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"),
// // DVD-Cops, ver.
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73,
0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
@@ -109,7 +111,7 @@ namespace BinaryObjectScanner.Protection
{
// CD-Cops, ver.
// Found in "h3blade.exe" in Redump entry 85077.
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C,
0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20
@@ -155,14 +157,14 @@ namespace BinaryObjectScanner.Protection
{
// WEBCOPS
// Found in "HyperBowl.C_S" in https://web.archive.org/web/20120616074941/http://icm.games.tucows.com/files2/HyperDemo-109a.exe.
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x57, 0x45, 0x42, 0x43, 0x4F, 0x50, 0x53
}, "WEB-Cops")
};
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -182,7 +184,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Original had "CDCOPS.DLL" required and all the rest in a combined OR
var matchers = new List<PathMatchSet>
@@ -191,12 +197,12 @@ namespace BinaryObjectScanner.Protection
// Presumably used to increase the amount of data written to the disc to allow DPM checking to be used for the protection. It's unknown if this file is used on any other protected discs.
// Found in Redump entry 84517.
new PathMatchSet(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
new PathMatchSet(new PathMatch(".W_X", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new PathMatchSet(new PathMatch(".QZ_", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
new(new PathMatch(".W_X", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new(new PathMatch(".QZ_", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new PathMatchSet(new PathMatch(".GZ_", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch(".Qz", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new(new PathMatch(".GZ_", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new(new PathMatch(".Qz", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -211,12 +217,12 @@ namespace BinaryObjectScanner.Protection
// Presumably used to increase the amount of data written to the disc to allow DPM checking to be used for the protection. It's unknown if this file is used on any other protected discs.
// Found in Redump entry 84517.
new PathMatchSet(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
new PathMatchSet(new PathMatch(".W_X", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new PathMatchSet(new PathMatch(".QZ_", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new(new PathMatch("CDCOPS.DLL", useEndsWith: true), "CD-Cops"),
new(new PathMatch(".W_X", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new(new PathMatch(".QZ_", matchExact: true, useEndsWith: true), "CD/DVD-Cops"),
new PathMatchSet(new PathMatch(".GZ_", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch(".Qz", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new(new PathMatch(".GZ_", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
new(new PathMatch(".Qz", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -228,7 +234,7 @@ namespace BinaryObjectScanner.Protection
if (fileContent == null)
return null;
#if NET40
#if NET20 || NET35 || NET40
byte[] versionBytes = new byte[4];
Array.Copy(fileContent, positions[0] + 15, versionBytes, 0, 4);
char[] version = versionBytes.Select(b => (char)b).ToArray();

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -55,12 +57,16 @@ namespace BinaryObjectScanner.Protection
}
/// <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 Redump entry 97142.
new PathMatchSet(new PathMatch("cdguard.dll", useEndsWith: true), "CD-Guard Copy Protection System"),
new(new FilePathMatch("cdguard.dll"), "CD-Guard Copy Protection System"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -72,7 +78,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in Redump entry 97142.
new PathMatchSet(new PathMatch("cdguard.dll", useEndsWith: true), "CD-Guard Copy Protection System"),
new(new FilePathMatch("cdguard.dll"), "CD-Guard Copy Protection System"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -43,7 +45,7 @@ namespace BinaryObjectScanner.Protection
// Found in game executables protected with CD-Lock (Redump entries 24287 and 31615).
// TODO: Check for possible false postives (Redump entry 97942).
// 2 + (char)0xF2 + (char)0x02 + (char)0x82 + (char)0xC3 + (char)0xBC + (char)0x0B + $ + (char)0x99 + (char)0xAD + 'C + (char)0xE4 + (char)0x9D + st + (char)0x99 + (char)0xFA + 2$ + (char)0x9D + )4 + (char)0xFF + t
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x32, 0xF2, 0x02, 0x82, 0xC3, 0xBC, 0x0B, 0x24,
0x99, 0xAD, 0x27, 0x43, 0xE4, 0x9D, 0x73, 0x74,
@@ -53,7 +55,7 @@ namespace BinaryObjectScanner.Protection
};
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -61,14 +63,18 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// TODO: Determine if there's any consistency in the naming of the additional AFP files.
// Found in every confirmed sample of CD-Lock, generally (but not always) appears to include markers relating to the additional AFP files present (Redump entries 24287 and 31615).
new PathMatchSet(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
new(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
// There is also a "$$$$$$$$.$$$" file present on some discs, but it isn't known if this is directly related to CD-Lock (Redump entries 37788 and 43221).
};
@@ -84,7 +90,7 @@ namespace BinaryObjectScanner.Protection
// TODO: Determine if there's any consistency in the naming of the additional AFP files.
// Found in every confirmed sample of CD-Lock, generally (but not always) appears to include markers relating to the additional AFP files present (Redump entries 24287 and 31615).
new PathMatchSet(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
new(new PathMatch("CONFIG.AFP", useEndsWith: true), "CD-Lock"),
// There is also a "$$$$$$$$.$$$" file present on some discs, but it isn't known if this is directly related to CD-Lock (Redump entries 37788 and 43221).
};

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -17,7 +19,11 @@ namespace BinaryObjectScanner.Protection
public class CDProtector : IPathCheck
{
/// <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>
{
@@ -26,13 +32,13 @@ namespace BinaryObjectScanner.Protection
// "_cdp32.dat" is actually an archive that contains the original executable.
// Another EXE is created, with the name of the original executable. I'm not sure what this executable does, but it appears to be compressed with NeoLite.
// TODO: Invesitage if this EXE itself can be detected in any way.
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector"),
new(new FilePathMatch("_cdp16.dat"), "CD-Protector"),
new(new FilePathMatch("_cdp16.dll"), "CD-Protector"),
new(new FilePathMatch("_cdp32.dat"), "CD-Protector"),
new(new FilePathMatch("_cdp32.dll"), "CD-Protector"),
// This is the "Phantom Trax" file generated by CD-Protector, intended to be burned to a protected CD as an audio track.
new PathMatchSet(new PathMatch("Track#1 - Track#2 Cd-Protector.wav", useEndsWith: true), "CD-Protector"),
new(new FilePathMatch("Track#1 - Track#2 Cd-Protector.wav"), "CD-Protector"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -48,13 +54,13 @@ namespace BinaryObjectScanner.Protection
// "_cdp32.dat" is actually an archive that contains the original executable.
// Another EXE is created, with the name of the original executable. I'm not sure what this executable does, but it appears to be compressed with NeoLite.
// TODO: Invesitage if this EXE itself can be detected in any way.
new PathMatchSet(new PathMatch("_cdp16.dat", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp16.dll", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp32.dat", useEndsWith: true), "CD-Protector"),
new PathMatchSet(new PathMatch("_cdp32.dll", useEndsWith: true), "CD-Protector"),
new(new FilePathMatch("_cdp16.dat"), "CD-Protector"),
new(new FilePathMatch("_cdp16.dll"), "CD-Protector"),
new(new FilePathMatch("_cdp32.dat"), "CD-Protector"),
new(new FilePathMatch("_cdp32.dll"), "CD-Protector"),
// This is the "Phantom Trax" file generated by CD-Protector, intended to be burned to a protected CD as an audio track.
new PathMatchSet(new PathMatch("Track#1 - Track#2 Cd-Protector.wav", useEndsWith: true), "CD-Protector"),
new(new FilePathMatch("Track#1 - Track#2 Cd-Protector.wav"), "CD-Protector"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -8,14 +10,18 @@ namespace BinaryObjectScanner.Protection
public class CDX : IPathCheck
{
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Verify if these are OR or AND
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDX16.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDX32.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDXNT.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -26,9 +32,9 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("CHKCDX16.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("CHKCDX32.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDX16.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDX32.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("CHKCDXNT.DLL"), "CD-X (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -17,10 +17,10 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// CDSPlayer
new ContentMatchSet(new byte?[] { 0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72 }, "Cactus Data Shield 200"),
new(new byte?[] { 0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72 }, "Cactus Data Shield 200"),
// yucca.cds
new ContentMatchSet(new byte?[] { 0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73 }, "Cactus Data Shield 200"),
new(new byte?[] { 0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73 }, "Cactus Data Shield 200"),
};
if (contentMatchSets != null && contentMatchSets.Any())

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -53,13 +55,17 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// Seems likely to be present in most, if not all discs protected with Cenega ProtectDVD, but unable to confirm due to only having a small sample size.
// Found in Redump entry 31422 and IA item "speed-pack".
new PathMatchSet(new PathMatch("cenega.dll", useEndsWith: true), "Cenega ProtectDVD"),
new(new FilePathMatch("cenega.dll"), "Cenega ProtectDVD"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -72,7 +78,7 @@ namespace BinaryObjectScanner.Protection
{
// Seems likely to be present in most, if not all discs protected with Cenega ProtectDVD, but unable to confirm due to only having a small sample size.
// Found in Redump entry 31422 and IA item "speed-pack".
new PathMatchSet(new PathMatch("cenega.dll", useEndsWith: true), "Cenega ProtectDVD"),
new(new FilePathMatch("cenega.dll"), "Cenega ProtectDVD"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -54,15 +56,19 @@ namespace BinaryObjectScanner.Protection
}
/// <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 the installation directory of Code-Lock version 2.35.
new PathMatchSet(new PathMatch("Code-Lock.chm", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock.DEP", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock.ocx", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock Wizard.exe", useEndsWith: true), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.chm"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.DEP"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.ocx"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock Wizard.exe"), "ChosenBytes Code-Lock"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -74,10 +80,10 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in the installation directory of Code-Lock version 2.35.
new PathMatchSet(new PathMatch("Code-Lock.chm", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock.DEP", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock.ocx", useEndsWith: true), "ChosenBytes Code-Lock"),
new PathMatchSet(new PathMatch("Code-Lock Wizard.exe", useEndsWith: true), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.chm"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.DEP"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock.ocx"), "ChosenBytes Code-Lock"),
new(new FilePathMatch("Code-Lock Wizard.exe"), "ChosenBytes Code-Lock"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -16,7 +18,7 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// Tom Commander
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x54, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x6D, 0x6D,
0x61, 0x6E, 0x64, 0x65, 0x72
@@ -30,13 +32,17 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
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
var matchers = new List<PathMatchSet>
{
//new PathMatchSet(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -49,7 +55,7 @@ namespace BinaryObjectScanner.Protection
// TODO: Look into .PFF files as an indicator. At least one disc has those oversized files
var matchers = new List<PathMatchSet>
{
//new PathMatchSet(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
//new(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -29,7 +29,7 @@ namespace BinaryObjectScanner.Protection
{
// Confirmed to detect most examples known of Cucko. The only known exception is the version of "TSLHost.dll" included on Redump entry 36119.
// ŠU‰8...…™...ŠUŠ8T...
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -8,11 +10,15 @@ namespace BinaryObjectScanner.Protection
public class DVDCrypt : IPathCheck
{
/// <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>
{
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("DvdCrypt.pdb"), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -23,7 +29,7 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("DvdCrypt.pdb"), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -10,9 +12,17 @@ namespace BinaryObjectScanner.Protection
public class DVDMoviePROTECT : IPathCheck
{
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
#if NET20 || NET35
var protections = new Queue<string>();
#else
var protections = new ConcurrentQueue<string>();
#endif
if (files == null)
return protections;
@@ -21,11 +31,11 @@ namespace BinaryObjectScanner.Protection
string[] bupfiles = files.Where(s => s.EndsWith(".bup")).ToArray();
for (int i = 0; i < bupfiles.Length; i++)
{
FileInfo bupfile = new FileInfo(bupfiles[i]);
var bupfile = new FileInfo(bupfiles[i]);
if (bupfile.DirectoryName == null)
continue;
FileInfo ifofile = new FileInfo(Path.Combine(bupfile.DirectoryName, bupfile.Name.Substring(0, bupfile.Name.Length - bupfile.Extension.Length) + ".ifo"));
var ifofile = new FileInfo(Path.Combine(bupfile.DirectoryName, bupfile.Name.Substring(0, bupfile.Name.Length - bupfile.Extension.Length) + ".ifo"));
if (bupfile.Length != ifofile.Length)
{
protections.Enqueue("DVD-Movie-PROTECT (Unconfirmed - Please report to us on Github)");

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -76,7 +78,7 @@ namespace BinaryObjectScanner.Protection
var timingMatchers = new List<ContentMatchSet>
{
// Denuvo Timing
new ContentMatchSet(
new(
new byte?[]
{
0x44, 0x65, 0x6E, 0x75, 0x76, 0x6F, 0x20, 0x54,
@@ -85,7 +87,7 @@ namespace BinaryObjectScanner.Protection
};
// TODO: Re-enable all Entry Point checks after implementing
// if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrWhiteSpace(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug)))
// if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrEmpty(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug)))
// {
// if (pex.OH_Magic == OptionalHeaderType.PE32Plus)
// {
@@ -158,7 +160,7 @@ namespace BinaryObjectScanner.Protection
// };
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// if (!string.IsNullOrEmpty(match))
// return match;
// return "Denuvo (Unknown x64 Version)";
@@ -224,7 +226,7 @@ namespace BinaryObjectScanner.Protection
// };
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// if (!string.IsNullOrEmpty(match))
// return match;
// //// Check if steam_api64.dll present
@@ -255,19 +257,23 @@ namespace BinaryObjectScanner.Protection
}
/// <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 Doom Eternal Update 1 (Steam Depot 782332, Manifest 7064393210727378308).
// These files are automatically installed into an "Denuvo Anti-Cheat" folder when the game is installed.
new PathMatchSet(new PathMatch("denuvo-anti-cheat.sys", useEndsWith: true), "Denuvo Anti-Cheat"),
new PathMatchSet(new PathMatch("denuvo-anti-cheat-update-service.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new PathMatchSet(new PathMatch("denuvo-anti-cheat-runtime.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat.sys", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-update-service.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-runtime.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
// 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 PathMatchSet(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -281,12 +287,12 @@ namespace BinaryObjectScanner.Protection
// Found in Doom Eternal Update 1 (Steam Depot 782332, Manifest 7064393210727378308).
// These files are automatically installed into an "Denuvo Anti-Cheat" folder when the game is installed.
new PathMatchSet(new PathMatch("denuvo-anti-cheat.sys", useEndsWith: true), "Denuvo Anti-Cheat"),
new PathMatchSet(new PathMatch("denuvo-anti-cheat-update-service.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new PathMatchSet(new PathMatch("denuvo-anti-cheat-runtime.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat.sys", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-update-service.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("denuvo-anti-cheat-runtime.dll", useEndsWith: true), "Denuvo Anti-Cheat"),
// 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 PathMatchSet(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
new(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -53,12 +55,16 @@ namespace BinaryObjectScanner.Protection
}
/// <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 "Nova_DellBigWIGDVD_USA"/Redump entry 108588.
new PathMatchSet(new FilePathMatch("DecryptWrap.exe"), "DigiGuard"),
new(new FilePathMatch("DecryptWrap.exe"), "DigiGuard"),
// There are at least two additional specifically named DecryptWrap files, "DecryptWrapTW2000.exe" and "DecryptWrapTW2KCode.exe" in IA item "Nova_DellBigWIGDVD_USA"/Redump entry 108588.
};
@@ -72,7 +78,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in IA item "Nova_DellBigWIGDVD_USA"/Redump entry 108588.
new PathMatchSet(new FilePathMatch("DecryptWrap.exe"), "DigiGuard"),
new(new FilePathMatch("DecryptWrap.exe"), "DigiGuard"),
// There are at least two additional specifically named DecryptWrap files, "DecryptWrapTW2000.exe" and "DecryptWrapTW2KCode.exe" in IA item "Nova_DellBigWIGDVD_USA"/Redump entry 108588.
};

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
@@ -22,20 +24,24 @@ namespace BinaryObjectScanner.Protection
// https://www.gamecopyworld.com/games/pc_pc_calcio_2000.shtml
// https://www.gamecopyworld.com/games/pc_pc_futbol_2000.shtml
#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>
{
// Many more checks are likely possible based on the sources, but only ones that have been personally verified are getting added.
// Uncopyable files found in at least http://redump.org/disc/70531/, and likely in multiple others.
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "COMPPLAY._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "LANDER.DA0").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.DAP").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.VBX").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch(Path.Combine("XCONTROL", "COMPPLAY._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch(Path.Combine("XCONTROL", "LANDER.DA0").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.DAP").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch(Path.Combine("XCONTROL", "XSMGOP.VBX").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
// Copyable file found in http://redump.org/disc/70531/ that seems to be exclusively associated with the protection and other files that are part of the protection.
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "COMPSCO._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch(Path.Combine("XCONTROL", "COMPSCO._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -49,15 +55,15 @@ namespace BinaryObjectScanner.Protection
// Many more checks are likely possible based on the sources, but only ones that have been personally verified are getting added.
// Uncopyable files found in at least http://redump.org/disc/70531/, and likely in multiple others.
new PathMatchSet(new PathMatch("2kscore.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("arrcalc.obj", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("bdrvisa.drv", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("gprinter.dll", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("hstadium.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("omanager.odl", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("opublic.001", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("spland.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new PathMatchSet(new PathMatch("uqprime.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("2kscore.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("arrcalc.obj", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("bdrvisa.drv", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("gprinter.dll", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("hstadium.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("omanager.odl", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("opublic.001", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("spland.sc0", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
new(new PathMatch("uqprime.ipx", useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -82,7 +84,7 @@ namespace BinaryObjectScanner.Protection
{
// Found in "T29.dll" (Redump entry 31914).
// This check should be as long as the following check, as this data is nearly identical (including length) in the original files, but for some reason the section ends early, causing part of the remaining data to not be part of a section.
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
@@ -100,7 +102,7 @@ namespace BinaryObjectScanner.Protection
}, GetVersion, "DiscGuard"),
// Found in "T5375.dll" (Redump entry 79284), "TD352.dll" and "TE091.dll" (Redump entry 46743), "T71E1.dll" and "T7181.dll" (Redump entry 46961), and "TA0E4.DLL" (Redump entry 79374).
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
@@ -128,7 +130,7 @@ namespace BinaryObjectScanner.Protection
};
var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -137,29 +139,33 @@ namespace BinaryObjectScanner.Protection
}
/// <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 together in seemingly every DiscGuard game (Redump entries 31914, 46743, 46961, 79284, and 79374).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("IOSLINK.VXD", useEndsWith: true),
new PathMatch("IOSLINK.SYS", useEndsWith: true),
new FilePathMatch("IOSLINK.VXD"),
new FilePathMatch("IOSLINK.SYS"),
}, "DiscGuard"),
// Found together in one DiscGuard game (Redump entry 31914).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("TTR1.DLL", useEndsWith: true),
new PathMatch("TTR2.DLL", useEndsWith: true),
new FilePathMatch("TTR1.DLL"),
new FilePathMatch("TTR2.DLL"),
}, "DiscGuard"),
// Found together in most DiscGuard games (Redump entries 46743, 46961, 79284, and 79374).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("T111.DLL", useEndsWith: true),
new PathMatch("T222.DLL", useEndsWith: true),
new FilePathMatch("T111.DLL"),
new FilePathMatch("T222.DLL"),
}, "DiscGuard"),
};
@@ -172,11 +178,11 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found together in seemingly every DiscGuard game (Redump entries 31914, 46743, 46961, 79284, and 79374).
new PathMatchSet(new PathMatch("IOSLINK.VXD", useEndsWith: true), "DiscGuard"),
new PathMatchSet(new PathMatch("IOSLINK.SYS", useEndsWith: true), "DiscGuard"),
new(new FilePathMatch("IOSLINK.VXD"), "DiscGuard"),
new(new FilePathMatch("IOSLINK.SYS"), "DiscGuard"),
// IOSLINK.DLL doesn't seem to be present in any known samples, but a check for it was in the original BurnOut.
new PathMatchSet(new PathMatch("IOSLINK.DLL", useEndsWith: true), "DiscGuard (Unconfirmed check, report this to us on GitHub))"),
new(new FilePathMatch("IOSLINK.DLL"), "DiscGuard (Unconfirmed check, report this to us on GitHub))"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -212,11 +218,9 @@ namespace BinaryObjectScanner.Protection
{
try
{
using (Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var pex = PortableExecutable.Create(fileStream);
return pex?.GetInternalVersion() ?? string.Empty;
}
using Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read);
var pex = PortableExecutable.Create(fileStream);
return pex?.GetInternalVersion() ?? string.Empty;
}
catch
{

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -80,47 +82,52 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Search for the presence of the folder "EasyAntiCheat" specifically, which is present in every checked version so far.
var matchers = new List<PathMatchSet>
{
// Found installed in "Program Files (x86)\EasyAntiCheat".
new PathMatchSet(new PathMatch("EasyAntiCheat.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.sys", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.sys"), "Easy Anti-Cheat"),
// Found installed in "Program Files (x86)\EasyAntiCheat_EOS".
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.sys", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("EasyAntiCheat_EOS.exe"), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("EasyAntiCheat_EOS.sys"), "Easy Anti-Cheat (EOS Version)"),
// Found installed in "AppData\Roaming\EasyAntiCheat".
new PathMatchSet(new PathMatch("easyanticheat_wow64_x64.eac", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat_wow64_x64.eac.metadata", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheatAnimation.png", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_wow64_x64.eac"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_wow64_x64.eac.metadata"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheatAnimation.png"), "Easy Anti-Cheat"),
// Found in "Intruder" (Version 2287, Steam).
new PathMatchSet(new PathMatch("eac_server.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat.icns", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.Client.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.Server.dll", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("eac_server.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat.icns"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.Client.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.Server.dll"), "Easy Anti-Cheat"),
// Found in "Intruder" (Version 2287, Steam) and "Rec Room" (Version 20220803, Oculus).
new PathMatchSet(new PathMatch("EasyAntiCheat.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_Setup.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_x64.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_x86.dll", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_Setup.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_x64.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_x86.dll"), "Easy Anti-Cheat"),
// Found in "Video Horror Society" (Patch 1.0.70309, Steam).
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS_Setup.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new PathMatchSet(new PathMatch("InstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("UninstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_EOS_Setup.exe"), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("InstallAntiCheat.bat"), "Easy Anti-Cheat"),
new(new FilePathMatch("UninstallAntiCheat.bat"), "Easy Anti-Cheat"),
// Found in "VRChat" (Version 2022.2.2p2, Oculus).
new PathMatchSet(new PathMatch("start_protected_game.exe", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("start_protected_game.exe"), "Easy Anti-Cheat"),
// Found in "Apex Legends" (Build ID 12029216, Steam)
new PathMatchSet(new PathMatch("EasyAntiCheat_launcher.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat_x64.so", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_launcher.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_x64.so"), "Easy Anti-Cheat"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -133,41 +140,41 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found installed in "Program Files (x86)\EasyAntiCheat".
new PathMatchSet(new PathMatch("EasyAntiCheat.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.sys", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.sys"), "Easy Anti-Cheat"),
// Found installed in "Program Files (x86)\EasyAntiCheat_EOS".
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS.sys", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("EasyAntiCheat_EOS.exe"), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("EasyAntiCheat_EOS.sys"), "Easy Anti-Cheat (EOS Version)"),
// Found installed in "AppData\Roaming\EasyAntiCheat".
new PathMatchSet(new PathMatch("easyanticheat_wow64_x64.eac", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat_wow64_x64.eac.metadata", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheatAnimation.png", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_wow64_x64.eac"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_wow64_x64.eac.metadata"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheatAnimation.png"), "Easy Anti-Cheat"),
// Found in "Intruder" (Version 2287, Steam).
new PathMatchSet(new PathMatch("eac_server.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat.icns", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.Client.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat.Server.dll", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("eac_server.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat.icns"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.Client.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.Server.dll"), "Easy Anti-Cheat"),
// Found in "Intruder" (Version 2287, Steam) and "Rec Room" (Version 20220803, Oculus).
new PathMatchSet(new PathMatch("EasyAntiCheat.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_Setup.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_x64.dll", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("EasyAntiCheat_x86.dll", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_Setup.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_x64.dll"), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_x86.dll"), "Easy Anti-Cheat"),
// Found in "Video Horror Society" (Patch 1.0.70309, Steam).
new PathMatchSet(new PathMatch("EasyAntiCheat_EOS_Setup.exe", useEndsWith: true), "Easy Anti-Cheat (EOS Version)"),
new PathMatchSet(new PathMatch("InstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("UninstallAntiCheat.bat", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_EOS_Setup.exe"), "Easy Anti-Cheat (EOS Version)"),
new(new FilePathMatch("InstallAntiCheat.bat"), "Easy Anti-Cheat"),
new(new FilePathMatch("UninstallAntiCheat.bat"), "Easy Anti-Cheat"),
// Found in "VRChat" (Version 2022.2.2p2, Oculus).
new PathMatchSet(new PathMatch("start_protected_game.exe", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("start_protected_game.exe"), "Easy Anti-Cheat"),
// Found in "Apex Legends" (Build ID 12029216, Steam)
new PathMatchSet(new PathMatch("EasyAntiCheat_launcher.exe", useEndsWith: true), "Easy Anti-Cheat"),
new PathMatchSet(new PathMatch("easyanticheat_x64.so", useEndsWith: true), "Easy Anti-Cheat"),
new(new FilePathMatch("EasyAntiCheat_launcher.exe"), "Easy Anti-Cheat"),
new(new FilePathMatch("easyanticheat_x64.so"), "Easy Anti-Cheat"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -51,7 +53,11 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -15,36 +17,40 @@ namespace BinaryObjectScanner.Protection
// TODO: Add an MS-DOS executable check for "FREELOCK.EXE".
/// <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>
{
// The disk image that every version of Freelock is distributed through.
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "Freelock Disk Image"),
new(new FilePathMatch("FREELOCK.IMG"), "Freelock Disk Image"),
// Found in every "FREELOCK.IMG".
new PathMatchSet(new PathMatch("FREELOCK.EXE", useEndsWith: true), "Freelock"),
new PathMatchSet(new PathMatch("FREELOCK.TXT", useEndsWith: true), "Freelock"),
new(new FilePathMatch("FREELOCK.EXE"), "Freelock"),
new(new FilePathMatch("FREELOCK.TXT"), "Freelock"),
// Found in "FREELOCK.IMG" from Freelock 1.0-1.2.
new PathMatchSet(new PathMatch("FREELOCK", useEndsWith: true), "Freelock 1.0-1.2"),
new(new FilePathMatch("FREELOCK"), "Freelock 1.0-1.2"),
// Found in "FREELOCK.IMG" from Freelock 1.2+.
new PathMatchSet(new PathMatch("GENLOCK.EXE", useEndsWith: true), "Freelock 1.2+"),
new PathMatchSet(new PathMatch("freelock.ico", useEndsWith: true), "Freelock 1.2+"),
new PathMatchSet(new PathMatch("freelock.pif", useEndsWith: true), "Freelock 1.2+"),
new(new FilePathMatch("GENLOCK.EXE"), "Freelock 1.2+"),
new(new FilePathMatch("freelock.ico"), "Freelock 1.2+"),
new(new FilePathMatch("freelock.pif"), "Freelock 1.2+"),
// Created by "GENLOCK.EXE" in Freelock 1.2+.
new PathMatchSet(new PathMatch("FREELOCK.DAT", useEndsWith: true), "Freelock 1.2+"),
new(new FilePathMatch("FREELOCK.DAT"), "Freelock 1.2+"),
// Found in "FREELOCK.IMG" From Freelock 1.3.
new PathMatchSet(new PathMatch("FREELOCK.13", useEndsWith: true), "Freelock 1.3"),
new(new FilePathMatch("FREELOCK.13"), "Freelock 1.3"),
// Found in "FREELOCK.IMG" From Freelock 1.3.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("FREELOCK.13", useEndsWith: true),
new PathMatch("FL.DAT", useEndsWith: true),
new FilePathMatch("FREELOCK.13"),
new FilePathMatch("FL.DAT"),
}, "Freelock 1.3"),
};
@@ -57,25 +63,25 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// The disk image that every version of Freelock is distributed through.
new PathMatchSet(new PathMatch("FREELOCK.IMG", useEndsWith: true), "Freelock Disk Image"),
new(new FilePathMatch("FREELOCK.IMG"), "Freelock Disk Image"),
// Found in every "FREELOCK.IMG".
new PathMatchSet(new PathMatch("FREELOCK.EXE", useEndsWith: true), "Freelock"),
new PathMatchSet(new PathMatch("FREELOCK.TXT", useEndsWith: true), "Freelock"),
new(new FilePathMatch("FREELOCK.EXE"), "Freelock"),
new(new FilePathMatch("FREELOCK.TXT"), "Freelock"),
// Found in "FREELOCK.IMG" from Freelock 1.0-1.2.
new PathMatchSet(new PathMatch("FREELOCK", useEndsWith: true), "Freelock 1.0-1.2"),
new(new FilePathMatch("FREELOCK"), "Freelock 1.0-1.2"),
// Found in "FREELOCK.IMG" from Freelock 1.2+.
new PathMatchSet(new PathMatch("GENLOCK.EXE", useEndsWith: true), "Freelock 1.2+"),
new PathMatchSet(new PathMatch("freelock.ico", useEndsWith: true), "Freelock 1.2+"),
new PathMatchSet(new PathMatch("freelock.pif", useEndsWith: true), "Freelock 1.2+"),
new(new FilePathMatch("GENLOCK.EXE"), "Freelock 1.2+"),
new(new FilePathMatch("freelock.ico"), "Freelock 1.2+"),
new(new FilePathMatch("freelock.pif"), "Freelock 1.2+"),
// Created by "GENLOCK.EXE" in Freelock 1.2+.
new PathMatchSet(new PathMatch("FREELOCK.DAT", useEndsWith: true), "Freelock 1.2+"),
new(new FilePathMatch("FREELOCK.DAT"), "Freelock 1.2+"),
// Found in "FREELOCK.IMG" From Freelock 1.3.
new PathMatchSet(new PathMatch("FREELOCK.13", useEndsWith: true), "Freelock 1.3"),
new(new FilePathMatch("FREELOCK.13"), "Freelock 1.3"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -36,14 +38,18 @@ namespace BinaryObjectScanner.ProtectionType
}
/// <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>
{
// Might be specifically GFWL/Gfwlivesetup.exe
new PathMatchSet(new PathMatch("Gfwlivesetup.exe", useEndsWith: true), "Games for Windows LIVE"),
new PathMatchSet(new PathMatch("xliveinstall.dll", useEndsWith: true), "Games for Windows LIVE"),
new PathMatchSet(new PathMatch("XLiveRedist.msi", useEndsWith: true), "Games for Windows LIVE"),
new(new FilePathMatch("Gfwlivesetup.exe"), "Games for Windows LIVE"),
new(new FilePathMatch("xliveinstall.dll"), "Games for Windows LIVE"),
new(new FilePathMatch("XLiveRedist.msi"), "Games for Windows LIVE"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -55,9 +61,9 @@ namespace BinaryObjectScanner.ProtectionType
var matchers = new List<PathMatchSet>
{
// Might be specifically GFWL/Gfwlivesetup.exe
new PathMatchSet(new PathMatch("Gfwlivesetup.exe", useEndsWith: true), "Games for Windows LIVE"),
new PathMatchSet(new PathMatch("xliveinstall.dll", useEndsWith: true), "Games for Windows LIVE"),
new PathMatchSet(new PathMatch("XLiveRedist.msi", useEndsWith: true), "Games for Windows LIVE"),
new(new FilePathMatch("Gfwlivesetup.exe"), "Games for Windows LIVE"),
new(new FilePathMatch("xliveinstall.dll"), "Games for Windows LIVE"),
new(new FilePathMatch("XLiveRedist.msi"), "Games for Windows LIVE"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -39,7 +41,11 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -68,35 +70,39 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// "Start_Here.exe" is the default name used in HexaLock AutoLock 4.5.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("Start_Here.exe", useEndsWith: true),
new PathMatch("MFINT.DLL", useEndsWith: true),
new PathMatch("MFIMP.DLL", useEndsWith: true),
new FilePathMatch("Start_Here.exe"),
new FilePathMatch("MFINT.DLL"),
new FilePathMatch("MFIMP.DLL"),
}, "Hexalock AutoLock 4.5"),
// Used for PDF protection in HexaLock AutoLock 4.7. "Start.exe" likely has some internal strings that can be checked.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("kleft.ipf", useEndsWith: true),
new PathMatch("ReadPFile.exe", useEndsWith: true),
new PathMatch("Start.exe", useEndsWith: true),
new FilePathMatch("kleft.ipf"),
new FilePathMatch("ReadPFile.exe"),
new FilePathMatch("Start.exe"),
}, "HexaLock AutoLock 4.7 PDF DRM"),
// Should be present in all known versions.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("MFINT.DLL", useEndsWith: true),
new PathMatch("MFIMP.DLL", useEndsWith: true),
new FilePathMatch("MFINT.DLL"),
new FilePathMatch("MFIMP.DLL"),
}, "HexaLock AutoLock"),
// Found inside the file typically named "Start_Here.exe" in version 4.5.
new PathMatchSet(new PathMatch("HCPSMng.exe", useEndsWith: true), "HexaLock AutoLock 4.5"),
new(new PathMatch("HCPSMng.exe"), "HexaLock AutoLock 4.5"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -108,18 +114,18 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found to be the default name used in HexaLock AutoLock 4.5.
new PathMatchSet(new PathMatch("Start_Here.exe", useEndsWith: true), "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 PathMatchSet(new PathMatch("MFINT.DLL", useEndsWith: true), "HexaLock AutoLock"),
new PathMatchSet(new PathMatch("MFIMP.DLL", useEndsWith: true), "HexaLock AutoLock"),
new(new FilePathMatch("MFINT.DLL"), "HexaLock AutoLock"),
new(new FilePathMatch("MFIMP.DLL"), "HexaLock AutoLock"),
// Used for PDF protection in HexaLock AutoLock 4.7.
new PathMatchSet(new PathMatch("kleft.ipf", useEndsWith: true), "HexaLock AutoLock 4.7 PDF DRM"),
new PathMatchSet(new PathMatch("ReadPFile.exe", useEndsWith: true), "HexaLock AutoLock 4.7 PDF DRM"),
new(new FilePathMatch("kleft.ipf"), "HexaLock AutoLock 4.7 PDF DRM"),
new(new FilePathMatch("ReadPFile.exe"), "HexaLock AutoLock 4.7 PDF DRM"),
// Found inside the file typically named "Start_Here.exe" in version 4.5.
new PathMatchSet(new PathMatch("HCPSMng.exe", useEndsWith: true), "HexaLock AutoLock 4.5"),
new(new FilePathMatch("HCPSMng.exe"), "HexaLock AutoLock 4.5"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -54,12 +56,16 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
new PathMatchSet(new PathMatch("ImpulseReactor.dll", useEndsWith: true), GetInternalVersion, "Impulse Reactor Core Module"),
new PathMatchSet(new PathMatch("ReactorActivate.exe", useEndsWith: true), GetInternalVersion, "Stardock Product Activation"),
new(new FilePathMatch("ImpulseReactor.dll"), GetInternalVersion, "Impulse Reactor Core Module"),
new(new FilePathMatch("ReactorActivate.exe"), GetInternalVersion, "Stardock Product Activation"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -70,8 +76,8 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("ImpulseReactor.dll", useEndsWith: true), GetInternalVersion, "Impulse Reactor Core Module"),
new PathMatchSet(new PathMatch("ReactorActivate.exe", useEndsWith: true), GetInternalVersion, "Stardock Product Activation"),
new(new FilePathMatch("ImpulseReactor.dll"), GetInternalVersion, "Impulse Reactor Core Module"),
new(new FilePathMatch("ReactorActivate.exe"), GetInternalVersion, "Stardock Product Activation"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -81,11 +87,9 @@ namespace BinaryObjectScanner.Protection
{
try
{
using (Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var pex = PortableExecutable.Create(fileStream);
return pex?.GetInternalVersion() ?? string.Empty;
}
using Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read);
var pex = PortableExecutable.Create(fileStream);
return pex?.GetInternalVersion() ?? string.Empty;
}
catch
{

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -12,13 +14,17 @@ namespace BinaryObjectScanner.Protection
public class IndyVCD : IPathCheck
{
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Verify if these are OR or AND
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("INDYVCD.AX", useEndsWith: true), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("INDYMP3.idt", useEndsWith: true), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("INDYVCD.AX"), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("INDYMP3.idt"), "IndyVCD (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -29,8 +35,8 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("INDYVCD.AX", useEndsWith: true), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new PathMatchSet(new PathMatch("INDYMP3.idt", useEndsWith: true), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("INDYVCD.AX"), "IndyVCD (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("INDYMP3.idt"), "IndyVCD (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -35,7 +35,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// kernel32.dll + (char)0x00 + (char)0x00 + (char)0x00 + VirtualProtect
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x33, 0x32,
0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x56,
@@ -45,7 +45,7 @@ namespace BinaryObjectScanner.Protection
};
var match = MatchUtil.GetFirstMatch(file, dcrtextData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -73,7 +73,7 @@ namespace BinaryObjectScanner.Protection
return null;
int position = positions[0];
#if NET40
#if NET20 || NET35 || NET40
byte[] versionBytes = new byte[8];
Array.Copy(fileContent, position + 67, versionBytes, 0, 8);
char[] version = versionBytes.Select(b => (char)b).ToArray();

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// KEY-LOCK COMMAND
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x4B, 0x45, 0x59, 0x2D, 0x4C, 0x4F, 0x43, 0x4B,
0x20, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -49,23 +51,32 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// All found to be present on at multiple albums with LabelGate CD2 (Redump entry 95010 and product ID SVWC-7185), the original version of LabelGate still needs to be investigated.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch(Path.Combine("BIN", "WIN32", "MQ2SETUP.EXE").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("BIN", "WIN32", "MQSTART.EXE").Replace("\\", "/"), useEndsWith: true),
#if NET20 || NET35
new(Path.Combine(Path.Combine("BIN", "WIN32"), "MQ2SETUP.EXE").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine(Path.Combine("BIN", "WIN32"), "MQSTART.EXE").Replace("\\", "/"), useEndsWith: true),
#else
new(Path.Combine("BIN", "WIN32", "MQ2SETUP.EXE").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("BIN", "WIN32", "MQSTART.EXE").Replace("\\", "/"), useEndsWith: true),
#endif
}, "LabelGate CD2 Media Player"),
// All of these are also found present on all known LabelGate CD2 releases, though an additional file "RESERVED.DAT" is found in the same directory in at least one release (Product ID SVWC-7185)
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch(Path.Combine("MQDISC", "LICENSE.TXT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("MQDISC", "MQDISC.INI").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("MQDISC", "START.INI").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("MQDISC", "LICENSE.TXT").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("MQDISC", "MQDISC.INI").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("MQDISC", "START.INI").Replace("\\", "/"), useEndsWith: true),
}, "LabelGate CD2"),
};
@@ -78,7 +89,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// This is the installer for the media player used by LabelGate CD2 (Redump entry 95010 and product ID SVWC-7185).
new PathMatchSet(new PathMatch("MQ2SETUP.EXE", useEndsWith: true), "LabelGate CD2 Media Player"),
new(new FilePathMatch("MQ2SETUP.EXE"), "LabelGate CD2 Media Player"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -24,7 +26,7 @@ namespace BinaryObjectScanner.Protection
// C:\NOMOUSE.SP
//
// // :\LASERLOK\LASERLOK.IN + (char)0x00 + C:\NOMOUSE.SP
// new ContentMatchSet(new byte?[]
// new(new byte?[]
// {
// 0x3A, 0x5C, 0x5C, 0x4C, 0x41, 0x53, 0x45, 0x52,
// 0x4C, 0x4F, 0x4B, 0x5C, 0x5C, 0x4C, 0x41, 0x53,
@@ -34,7 +36,7 @@ namespace BinaryObjectScanner.Protection
// }, "LaserLok 3"),
// // LASERLOK_INIT + (char)0xC + LASERLOK_RUN + (char)0xE + LASERLOK_CHECK + (char)0xF + LASERLOK_CHECK2 + (char)0xF + LASERLOK_CHECK3
// new ContentMatchSet(new byte?[]
// new(new byte?[]
// {
// 0x4C, 0x41, 0x53, 0x45, 0x52, 0x4C, 0x4F, 0x4B,
// 0x5F, 0x49, 0x4E, 0x49, 0x54, 0x0C, 0x4C, 0x41,
@@ -54,15 +56,15 @@ namespace BinaryObjectScanner.Protection
return null;
// Packed by SPEEnc V2 Asterios Parlamentas.PE
byte?[] check = new byte?[]
{
byte?[] check =
[
0x50, 0x61, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x62,
0x79, 0x20, 0x53, 0x50, 0x45, 0x45, 0x6E, 0x63,
0x20, 0x56, 0x32, 0x20, 0x41, 0x73, 0x74, 0x65,
0x72, 0x69, 0x6F, 0x73, 0x20, 0x50, 0x61, 0x72,
0x6C, 0x61, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x73,
0x2E, 0x50, 0x45
};
];
int endDosStub = (int)(pex.Model.Stub?.Header?.NewExeHeaderAddr ?? 0);
int position = -1;
bool containsCheck = pex.StubExecutableData?.FirstPosition(check, out position) ?? false;
@@ -79,8 +81,8 @@ namespace BinaryObjectScanner.Protection
if (containsCheck2 && pex.ContainsSection(".text"))
{
// GetModuleHandleA + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + GetProcAddress + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + LoadLibraryA + (char)0x00 + (char)0x00 + KERNEL32.dll + (char)0x00 + ëy + (char)0x01 + SNIF/MPVI
byte?[] check2 = new byte?[]
{
byte?[] check2 =
[
0x47, 0x65, 0x74, 0x4D, 0x6F, 0x64, 0x75, 0x6C,
0x65, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x41,
0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x74, 0x50,
@@ -90,7 +92,7 @@ namespace BinaryObjectScanner.Protection
0x79, 0x41, 0x00, 0x00, 0x4B, 0x45, 0x52, 0x4E,
0x45, 0x4C, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C,
0x00, 0xEB, 0x79, 0x01, null, null, null, null,
};
];
containsCheck2 = pex.GetFirstSectionData(".text")?.FirstPosition(check2, out position2) ?? false;
}
else
@@ -111,21 +113,25 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
new PathMatchSet($"LASERLOK{Path.DirectorySeparatorChar}", "LaserLok [Check disc for physical ring]"),
new($"LASERLOK{Path.DirectorySeparatorChar}", "LaserLok [Check disc for physical ring]"),
// TODO: Verify if these are OR or AND
new PathMatchSet(new FilePathMatch("NOMOUSE.SP"), GetVersion16Bit, "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new FilePathMatch("NOMOUSE.COM"), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("l16dll.dll", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.in", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o10", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o11", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o12", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.out", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new FilePathMatch("NOMOUSE.SP"), GetVersion16Bit, "LaserLok [Check disc for physical ring]"),
new(new FilePathMatch("NOMOUSE.COM"), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("l16dll.dll", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.in", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o10", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o11", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o12", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.out", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -136,16 +142,16 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new FilePathMatch("NOMOUSE.SP"), GetVersion16Bit, "LaserLok [Check disc for physical ring]"),
new(new FilePathMatch("NOMOUSE.SP"), GetVersion16Bit, "LaserLok [Check disc for physical ring]"),
// TODO: Verify if these are OR or AND
new PathMatchSet(new FilePathMatch("NOMOUSE.COM"), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("l16dll.dll", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.in", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o10", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o11", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.o12", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new PathMatchSet(new PathMatch("laserlok.out", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new FilePathMatch("NOMOUSE.COM"), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("l16dll.dll", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.in", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o10", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o11", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.o12", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
new(new PathMatch("laserlok.out", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -157,11 +163,11 @@ namespace BinaryObjectScanner.Protection
return "(Build unknown)";
// Unkown + (char)0x00 + Unkown
byte?[] check = new byte?[]
{
byte?[] check =
[
0x55, 0x6E, 0x6B, 0x6F, 0x77, 0x6E, 0x00, 0x55,
0x6E, 0x6B, 0x6F, 0x77, 0x6E
};
];
if (!sectionContent.FirstPosition(check, out int position))
return "(Build unknown)";
@@ -169,7 +175,7 @@ namespace BinaryObjectScanner.Protection
if (versionTwo)
{
int index = position + 14;
#if NET40
#if NET20 || NET35 || NET40
byte[] temp = new byte[2];
Array.Copy(sectionContent, index, temp, 0, 2);
day = new string(temp.Select(b => (char)b).ToArray());
@@ -190,7 +196,7 @@ namespace BinaryObjectScanner.Protection
else
{
int index = position + 13;
#if NET40
#if NET20 || NET35 || NET40
byte[] temp = new byte[2];
Array.Copy(sectionContent, index, temp, 0, 2);
day = new string(temp.Select(b => (char)b).ToArray());
@@ -218,7 +224,7 @@ namespace BinaryObjectScanner.Protection
if (sectionContent == null)
return null;
#if NET40
#if NET20 || NET35 || NET40
byte[] temp = new byte[4];
Array.Copy(sectionContent, position + 76, temp, 0, 4);
return new string(temp.Select(b => (char)b).ToArray());
@@ -232,16 +238,14 @@ namespace BinaryObjectScanner.Protection
if (!File.Exists(firstMatchedString))
return string.Empty;
using (var fs = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var br = new BinaryReader(fs))
{
return GetVersion16Bit(br.ReadBytes((int)fs.Length));
}
using var fs = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var br = new BinaryReader(fs);
return GetVersion16Bit(br.ReadBytes((int)fs.Length));
}
private static string GetVersion16Bit(byte[] fileContent)
{
#if NET40
#if NET20 || NET35 || NET40
byte[] temp = new byte[7];
Array.Copy(fileContent, 71, temp, 0, 7);
char[] version = temp.Select(b => (char)b).ToArray();

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using SabreTools.Matching;
@@ -148,43 +150,47 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> CDillaCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> CDillaCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
// Found in C-Dilla CD-Secure/CD-Compress 1.31.34.
new PathMatchSet(new PathMatch("CDANT.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA05.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA10.EXE", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA40.DLL", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDANT.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA05.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA10.EXE"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA40.DLL"), "C-Dilla License Management System"),
// Found in C-Dilla LMS version 3.24.010 (IA item "ejay_nestle_trial").
// TODO: Verify that all of these are exclusively part of LMS, and not SafeCast.
new PathMatchSet(new PathMatch("CdaLMS.exe", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("cdilla51.dll", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("cdilla52.dll", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CdaLMS.exe"), "C-Dilla License Management System"),
new(new FilePathMatch("cdilla51.dll"), "C-Dilla License Management System"),
new(new FilePathMatch("cdilla52.dll"), "C-Dilla License Management System"),
// Found in the installer C-Dilla LMS version 3.27.000.
// The files "CdRemove.exe", "CdSet32.exe", "CdSet32.ini", "CdSetup.exe", "CdSetup.ini", and "CdUnin16.exe" are found there as well, but aren't currently checked for due to possibly being too generic.
// TODO: Add grouped check for "CdRemove.exe", "CdSet32.exe", "CdSet32.ini", "CdSetup.exe", "CdSetup.ini", and "CdUnin16.exe".
new PathMatchSet(new PathMatch("CdaIns16.dll", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CdaIns32.dll", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CdaIns16.dll"), "C-Dilla License Management System"),
new(new FilePathMatch("CdaIns32.dll"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows 3.1.
// The files "CDILLA05.DLL", "CDILLA10.EXE", and "CDILLA40.DLL" are included as well.
// TODO: Check into what file "CDAW31X.38_" gets installed as. I wasn't able to find what it gets installed to.
new PathMatchSet(new PathMatch("CDILLA32.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA64.EXE", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA32.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA64.EXE"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows 95. All the files installed for Windows 3.1 are also installed for 95.
new PathMatchSet(new PathMatch("CDAINT2F.VXD", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDAWIN95.VXD", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA13.DLL", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDAINT2F.VXD"), "C-Dilla License Management System"),
new(new FilePathMatch("CDAWIN95.VXD"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA13.DLL"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows NT. All the files installed for Windows 95 and 3.1 (except for the VXD files) are also installed for NT.
new PathMatchSet(new PathMatch("CDANT.SYS", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDANTSRV.EXE", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA16.EXE", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDANT.SYS"), "C-Dilla License Management System"),
new(new FilePathMatch("CDANTSRV.EXE"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA16.EXE"), "C-Dilla License Management System"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -196,38 +202,38 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in C-Dilla CD-Secure/CD-Compress 1.31.34.
new PathMatchSet(new PathMatch("CDANT.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA05.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA10.EXE", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA40.DLL", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDANT.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA05.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA10.EXE"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA40.DLL"), "C-Dilla License Management System"),
// Found in C-Dilla LMS version 3.24.010 (IA item "ejay_nestle_trial").
// TODO: Verify that all of these are exclusively part of LMS, and not SafeCast.
new PathMatchSet(new PathMatch("CdaLMS.exe", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("cdilla51.dll", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("cdilla52.dll", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CdaLMS.exe"), "C-Dilla License Management System"),
new(new FilePathMatch("cdilla51.dll"), "C-Dilla License Management System"),
new(new FilePathMatch("cdilla52.dll"), "C-Dilla License Management System"),
// Found in the installer C-Dilla LMS version 3.27.000.
// The files "CdRemove.exe", "CdSet32.exe", "CdSet32.ini", "CdSetup.exe", "CdSetup.ini", and "CdUnin16.exe" are found there as well, but aren't currently checked for due to possibly being too generic.
// TODO: Add grouped check for "CdRemove.exe", "CdSet32.exe", "CdSet32.ini", "CdSetup.exe", "CdSetup.ini", and "CdUnin16.exe".
new PathMatchSet(new PathMatch("CdaIns16.dll", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CdaIns32.dll", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CdaIns16.dll"), "C-Dilla License Management System"),
new(new FilePathMatch("CdaIns32.dll"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows 3.1.
// The files "CDILLA05.DLL", "CDILLA10.EXE", and "CDILLA40.DLL" are included as well.
// TODO: Check into what file "CDAW31X.38_" gets installed as. I wasn't able to find what it gets installed to.
new PathMatchSet(new PathMatch("CDILLA32.DLL", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA64.EXE", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA32.DLL"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA64.EXE"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows 95. All the files installed for Windows 3.1 are also installed for 95.
new PathMatchSet(new PathMatch("CDAINT2F.VXD", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDAWIN95.VXD", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA13.DLL", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDAINT2F.VXD"), "C-Dilla License Management System"),
new(new FilePathMatch("CDAWIN95.VXD"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA13.DLL"), "C-Dilla License Management System"),
// Found installed in C-Dilla LMS version 3.27.000 for Windows NT. All the files installed for Windows 95 and 3.1 (except for the VXD files) are also installed for NT.
new PathMatchSet(new PathMatch("CDANT.SYS", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDANTSRV.EXE", useEndsWith: true), "C-Dilla License Management System"),
new PathMatchSet(new PathMatch("CDILLA16.EXE", useEndsWith: true), "C-Dilla License Management System"),
new(new FilePathMatch("CDANT.SYS"), "C-Dilla License Management System"),
new(new FilePathMatch("CDANTSRV.EXE"), "C-Dilla License Management System"),
new(new FilePathMatch("CDILLA16.EXE"), "C-Dilla License Management System"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -64,7 +66,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> CactusDataShieldCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> CactusDataShieldCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// TODO: Verify if these are OR or AND
var matchers = new List<PathMatchSet>
@@ -72,16 +78,16 @@ namespace BinaryObjectScanner.Protection
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
// The file "DATA16.BML" is also present on this disc but the name is too generic to check for.
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), "PlayJ Music Player (Cactus Data Shield 200)"),
new(new FilePathMatch("CACTUSPJ.exe"), "PlayJ Music Player (Cactus Data Shield 200)"),
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
// In "Volumina! - Puur" (7 43218 63282 2), this file is composed of multiple PLJ files combined together.
// In later versions, this file is a padded dummy file. ("Ich Habe Einen Traum" by Uwe Busse (Barcode 9 002723 251203)).
new PathMatchSet(new PathMatch("YUCCA.CDS", useEndsWith: true), "Cactus Data Shield 200"),
new(new FilePathMatch("YUCCA.CDS"), "Cactus Data Shield 200"),
// TODO: Find samples of the following:
new PathMatchSet(new PathMatch("CDSPlayer.app", useEndsWith: true), GetCactusDataShieldVersion, "Cactus Data Shield"),
new PathMatchSet(new PathMatch("wmmp.exe", useEndsWith: true), GetCactusDataShieldVersion, "Cactus Data Shield"),
new(new FilePathMatch("CDSPlayer.app"), GetCactusDataShieldVersion, "Cactus Data Shield"),
new(new FilePathMatch("wmmp.exe"), GetCactusDataShieldVersion, "Cactus Data Shield"),
// The file "00000001.TMP" (with a filesize of 2,048 bytes) can be found in CDS-300, as well as SafeDisc.
// Due to this file being used in both protections, this file is detected within the general Macrovision checks.
@@ -98,16 +104,16 @@ namespace BinaryObjectScanner.Protection
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
// Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable.
// The file "DATA16.BML" is also present on this disc but the name is too generic to check for.
new PathMatchSet(new PathMatch("CACTUSPJ.exe", useEndsWith: true), "PlayJ Music Player (Cactus Data Shield 200)"),
new(new FilePathMatch("CACTUSPJ.exe"), "PlayJ Music Player (Cactus Data Shield 200)"),
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]),
// In "Volumia! - Puur", this file is composed of multiple PLJ files combined together.
// In later versions, this file is a padded dummy file. ("Ich Habe Einen Traum" by Uwe Busse (Barcode 9 002723 251203)).
new PathMatchSet(new PathMatch("YUCCA.CDS", useEndsWith: true), "Cactus Data Shield 200"),
new(new FilePathMatch("YUCCA.CDS"), "Cactus Data Shield 200"),
// TODO: Find samples of the following:
new PathMatchSet(new PathMatch("CDSPlayer.app", useEndsWith: true), "Cactus Data Shield 200"),
new PathMatchSet(new PathMatch("wmmp.exe", useEndsWith: true), "Cactus Data Shield 200"),
new(new FilePathMatch("CDSPlayer.app"), "Cactus Data Shield 200"),
new(new FilePathMatch("wmmp.exe"), "Cactus Data Shield 200"),
// The file "00000001.TMP" (with a filesize of 2,048 bytes) can be found in CDS-300, as well as SafeDisc.
// Due to this file being used in both protections, this file is detected within the general Macrovision checks.
@@ -124,10 +130,10 @@ namespace BinaryObjectScanner.Protection
// Find the version.txt file first
var versionPath = files.FirstOrDefault(f => Path.GetFileName(f).Equals("version.txt", StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(versionPath))
if (!string.IsNullOrEmpty(versionPath))
{
var version = GetCactusDataShieldInternalVersion(versionPath);
if (!string.IsNullOrWhiteSpace(version))
if (!string.IsNullOrEmpty(version))
return version!;
}
@@ -141,14 +147,12 @@ namespace BinaryObjectScanner.Protection
try
{
using (var sr = new StreamReader(path, Encoding.Default))
{
var line = sr.ReadLine();
if (line == null)
return null;
using var sr = new StreamReader(path, Encoding.Default);
var line = sr.ReadLine();
if (line == null)
return null;
return $"{line.Substring(3)} ({sr.ReadLine()})";
}
return $"{line.Substring(3)} ({sr.ReadLine()})";
}
catch
{

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using SabreTools.Matching;
@@ -36,11 +38,11 @@ namespace BinaryObjectScanner.Protection
if (name?.Equals("rgasdev", StringComparison.OrdinalIgnoreCase) == true)
return "RipGuard";
if (!string.IsNullOrWhiteSpace(file) && File.Exists(file))
if (!string.IsNullOrEmpty(file) && File.Exists(file))
{
try
{
FileInfo fi = new FileInfo(file);
var fi = new FileInfo(file);
// So far, every seemingly-randomly named EXE on RipGuard discs have a consistent hash.
if (fi.Length == 49_152)
@@ -59,35 +61,39 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> RipGuardCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> RipGuardCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
// Found in the Black Lagoon Season 1 DVD steelbook box set (Geneon ID 12970).
new PathMatchSet(new PathMatch("G23YHWO1.EXE", useEndsWith: true), "RipGuard"),
new PathMatchSet(new PathMatch("RGASDEV.SYS", useEndsWith: true), "RipGuard"),
new(new PathMatch("G23YHWO1.EXE", useEndsWith: true), "RipGuard"),
new(new PathMatch("RGASDEV.SYS", useEndsWith: true), "RipGuard"),
// Mentioned online in https://forum.redfox.bz/threads/resolved-one-on-one-with-tony-horton-vol2-disc3.33901/.
new PathMatchSet(new PathMatch("9KMJ9G4I.EXE", useEndsWith: true), "RipGuard (Unconfirmed - Please report to us on GitHub)"),
new(new PathMatch("9KMJ9G4I.EXE", useEndsWith: true), "RipGuard (Unconfirmed - Please report to us on GitHub)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
internal string? RipGuardCheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
internal string? RipGuardCheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// Found in the Black Lagoon Season 1 DVD steelbook box set (Geneon ID 12970).
new PathMatchSet(new PathMatch("G23YHWO1.EXE", useEndsWith: true), "RipGuard"),
new PathMatchSet(new PathMatch("RGASDEV.SYS", useEndsWith: true), "RipGuard"),
new(new PathMatch("G23YHWO1.EXE", useEndsWith: true), "RipGuard"),
new(new PathMatch("RGASDEV.SYS", useEndsWith: true), "RipGuard"),
// Mentioned online in https://forum.redfox.bz/threads/resolved-one-on-one-with-tony-horton-vol2-disc3.33901/.
new PathMatchSet(new PathMatch("9KMJ9G4I.EXE", useEndsWith: true), "RipGuard (Unconfirmed - Please report to us on GitHub)"),
new(new PathMatch("9KMJ9G4I.EXE", useEndsWith: true), "RipGuard (Unconfirmed - Please report to us on GitHub)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -60,7 +62,7 @@ namespace BinaryObjectScanner.Protection
{
// SafeCast
// Found as the Product Name in "cdac01aa.dll" from IA item "ejay_nestle_trial". Windows 10 appears to incorrectly truncate this to "SafeCas" in File Explorer.
new ContentMatchSet(new byte?[] { 0x53, 0x61, 0x66, 0x65, 0x43, 0x61, 0x73, 0x74 }, "SafeCast"),
new(new byte?[] { 0x53, 0x61, 0x66, 0x65, 0x43, 0x61, 0x73, 0x74 }, "SafeCast"),
};
return MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
@@ -144,43 +146,47 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> SafeCastCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> SafeCastCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
// Found in IA item "britney-spears-special-edition-cd-rom".
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("C2C.16", useEndsWith: true),
new PathMatch("C2C.DLL", useEndsWith: true),
new PathMatch("C2CDEL.16", useEndsWith: true),
new PathMatch("C2CDEL.EXE", useEndsWith: true),
new FilePathMatch("C2C.16"),
new FilePathMatch("C2C.DLL"),
new FilePathMatch("C2CDEL.16"),
new FilePathMatch("C2CDEL.EXE"),
}, "SafeCast"),
// Found in IA item "ejay_nestle_trial".
new PathMatchSet(new PathMatch("cdac01aa.dll", useEndsWith: true), "SafeCast"),
new PathMatchSet(new PathMatch("cdac01ba.dll", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("cdac01aa.dll"), "SafeCast"),
new(new FilePathMatch("cdac01ba.dll"), "SafeCast"),
// Found in multiple versions of SafeCast, including Redump entries 83145 and 95524, as well as IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("cdac14ba.dll", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("cdac14ba.dll"), "SafeCast"),
// Found in Redump entry 83145.
new PathMatchSet(new PathMatch("CDAC21BA.DLL", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC21BA.DLL"), "SafeCast"),
// Found in Redump entry 102979.
new PathMatchSet(new PathMatch("SCRfrsh.exe", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCRfrsh.exe"), "SafeCast"),
// Found in Redump entries 26211 and 95524.
new PathMatchSet(new PathMatch("SCSHD.CSA", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCSHD.CSA"), "SafeCast"),
// Found in Redump entries 95524.
new PathMatchSet(new PathMatch("SCSHD.EXE", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCSHD.EXE"), "SafeCast"),
// Found in IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("CDAC15BA.SYS", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC15BA.SYS"), "SafeCast"),
// Found in "cdac14ba.dll" in IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("CDAC13BA.EXE", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC13BA.EXE"), "SafeCast"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -192,31 +198,31 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in IA item "ejay_nestle_trial".
new PathMatchSet(new PathMatch("cdac01aa.dll", useEndsWith: true), "SafeCast"),
new PathMatchSet(new PathMatch("cdac01ba.dll", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("cdac01aa.dll"), "SafeCast"),
new(new FilePathMatch("cdac01ba.dll"), "SafeCast"),
new PathMatchSet(new PathMatch("cdac11ba.exe", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("cdac11ba.exe"), "SafeCast"),
// Found in multiple versions of SafeCast, including Redump entry 83145 and IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("cdac14ba.dll", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("cdac14ba.dll"), "SafeCast"),
// Found in Redump entry 83145.
new PathMatchSet(new PathMatch("CDAC21BA.DLL", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC21BA.DLL"), "SafeCast"),
// Found in Redump entry 102979.
new PathMatchSet(new PathMatch("SCRfrsh.exe", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCRfrsh.exe"), "SafeCast"),
// Found in Redump entries 26211 and 95524.
new PathMatchSet(new PathMatch("SCSHD.CSA", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCSHD.CSA"), "SafeCast"),
// Found in Redump entries 95524.
new PathMatchSet(new PathMatch("SCSHD.EXE", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("SCSHD.EXE"), "SafeCast"),
// Found in IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("CDAC15BA.SYS", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC15BA.SYS"), "SafeCast"),
// Found in "cdac14ba.dll" in IA item "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282".
new PathMatchSet(new PathMatch("CDAC13BA.EXE", useEndsWith: true), "SafeCast"),
new(new FilePathMatch("CDAC13BA.EXE"), "SafeCast"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -110,55 +112,58 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> SafeDiscCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> SafeDiscCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("CLCD16.DLL", useEndsWith: true),
new PathMatch("CLCD32.DLL", useEndsWith: true),
new PathMatch("CLOKSPL.EXE", useEndsWith: true),
new PathMatch(".icd", useEndsWith: true),
new FilePathMatch("CLCD16.DLL"),
new FilePathMatch("CLCD32.DLL"),
new FilePathMatch("CLOKSPL.EXE"),
new(".icd", useEndsWith: true),
}, "SafeDisc 1/Lite"),
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("00000001.TMP", useEndsWith: true),
new FilePathMatch("00000001.TMP"),
// The .016 and .256 files are banners stored in the BMP image format. The 016 and 256 refers to the color depth of the BMP.
// There are common file names used, such as 00000407.XXX and 00000409.XXX. Further investigation is needed to determine the consistency of these names.
new PathMatch(".016", useEndsWith: true),
new PathMatch(".256", useEndsWith: true),
new(".016", useEndsWith: true),
new(".256", useEndsWith: true),
}, "SafeDisc 1.06.000-3.20.024"),
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("00000001.TMP", useEndsWith: true),
new FilePathMatch("00000001.TMP"),
// The .016 files stop being used as of 4.00.000, while the .256 remain in fairly consistent use.
new PathMatch(".256", useEndsWith: true),
new(".256", useEndsWith: true),
}, "SafeDisc 1.06.000+"),
// The file "mcp.dll" is known to only be used in a specific version range for SafeDisc, but is currently only used in a grouped file name check with other SafeDisc files to prevent false positives.
// Found in Redump entries 28810, 30555, 55078, and 62935.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("00000001.TMP", useEndsWith: true),
new PathMatch("drvmgt.dll", useEndsWith: true),
new PathMatch("mcp.dll", useEndsWith: true),
new PathMatch("secdrv.sys", useEndsWith: true),
new FilePathMatch("00000001.TMP"),
new FilePathMatch("drvmgt.dll"),
new FilePathMatch("mcp.dll"),
new FilePathMatch("secdrv.sys"),
}, "SafeDisc 1.45.011-1.50.020"),
// TODO: Research "splash16.bmp" and "splash256.bmp".
// Found to be present in every version of SafeDisc, possibly every single release.
//new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), GetSafeDisc00000001TMPVersion, "SafeDisc"),
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
// 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 PathMatchSet(new PathMatch("00000002.TMP", useEndsWith: true), "SafeDisc 2+"),
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
new PathMatchSet(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
new PathMatchSet(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
new(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
new(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
// The SD0XXX.dll files appear to solely contain custom strings that allowed the publisher to customize the SafeDisc error messages. They are currently only known to be used by EA.
// Each file appears to contain strings for a specific language each.
@@ -167,51 +172,51 @@ namespace BinaryObjectScanner.Protection
// "d:\DiceCanada\BoosterPack2\Installers\BF2XpackInstaller\Safedisk\SafeDiscDLLs\DLLs\Release\SD0816.pdb" (Redump entry 65569).
// Found in Redump entries 20729 and 65569.
new PathMatchSet(new PathMatch("SD040e.dll", useEndsWith: true), "SafeDisc"),
new(new FilePathMatch("SD040e.dll"), "SafeDisc"),
// Found in Redump entry 65569.
new PathMatchSet(new PathMatch("SD0c0a.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD040b.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD040c.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0419.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD041d.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD041e.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0404.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0405.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0406.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0407.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0409.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0410.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0411.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0412.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0413.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0414.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0415.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0416.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0804.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0809.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0816.dll", useEndsWith: true), "SafeDisc"),
new(new FilePathMatch("SD0c0a.dll"), "SafeDisc"),
new(new FilePathMatch("SD040b.dll"), "SafeDisc"),
new(new FilePathMatch("SD040c.dll"), "SafeDisc"),
new(new FilePathMatch("SD0419.dll"), "SafeDisc"),
new(new FilePathMatch("SD041d.dll"), "SafeDisc"),
new(new FilePathMatch("SD041e.dll"), "SafeDisc"),
new(new FilePathMatch("SD0404.dll"), "SafeDisc"),
new(new FilePathMatch("SD0405.dll"), "SafeDisc"),
new(new FilePathMatch("SD0406.dll"), "SafeDisc"),
new(new FilePathMatch("SD0407.dll"), "SafeDisc"),
new(new FilePathMatch("SD0409.dll"), "SafeDisc"),
new(new FilePathMatch("SD0410.dll"), "SafeDisc"),
new(new FilePathMatch("SD0411.dll"), "SafeDisc"),
new(new FilePathMatch("SD0412.dll"), "SafeDisc"),
new(new FilePathMatch("SD0413.dll"), "SafeDisc"),
new(new FilePathMatch("SD0414.dll"), "SafeDisc"),
new(new FilePathMatch("SD0415.dll"), "SafeDisc"),
new(new FilePathMatch("SD0416.dll"), "SafeDisc"),
new(new FilePathMatch("SD0804.dll"), "SafeDisc"),
new(new FilePathMatch("SD0809.dll"), "SafeDisc"),
new(new FilePathMatch("SD0816.dll"), "SafeDisc"),
// Used to distribute SafeDisc driver updates over the internet. Two distinct versions known to exist, with Microsoft also having distributed the later update as well.
// Version 1: https://web.archive.org/web/20040614184055/http://www.macrovision.com:80/products/safedisc/safedisc.exe
// Version 2: https://web.archive.org/web/20051104123646/http://www.macrovision.com/products/safedisc/safedisc.exe
// Microsoft download page: https://web.archive.org/web/20080204081329/http://www.microsoft.com/downloads/details.aspx?FamilyID=eae20f0f-c41c-44fe-84ce-1df707d7a2e9&DisplayLang=en
new PathMatchSet(new PathMatch("safedisc.exe", useEndsWith: true), "SafeDisc Driver Installer"),
new(new FilePathMatch("safedisc.exe"), "SafeDisc Driver Installer"),
// Found in Redump entries 28810 and 30555.
// Name check overmatches with a seemingly completely unrelated application, ironically included on at least one SafeDisc game (Redump entry 34828).
// new PathMatchSet(new PathMatch("mcp.dll", useEndsWith: true), "SafeDisc (Version 1.45.011-1.50.020)"),
// new(new FilePathMatch("mcp.dll"), "SafeDisc (Version 1.45.011-1.50.020)"),
// Found in Redump entry 58455 and 65569.
// Unknown if it's a game specific file, but it contains the stxt371 and stxt774 sections.
// new PathMatchSet(new PathMatch("CoreDLL.dll", useEndsWith: true), "SafeDisc"),
// new(new FilePathMatch("CoreDLL.dll"), "SafeDisc"),
// Found in seemingly every SafeDisc Lite disc. (CD: Redump entries 25579 and 57986. DVD: Redump entry 63941).
new PathMatchSet(new PathMatch("00000001.LT1", useEndsWith: true), "SafeDisc Lite"),
new PathMatchSet(new PathMatch("LTDLL.DLL", useEndsWith: true), "SafeDisc Lite"),
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
// Found on Redump entry 42762.
new PathMatchSet(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -222,17 +227,17 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("CLCD16.DLL", useEndsWith: true), GetSafeDiscCLCD16Version, "SafeDisc"),
new PathMatchSet(new PathMatch("CLCD32.DLL", useEndsWith: true), GetSafeDiscCLCD32Version, "SafeDisc"),
new PathMatchSet(new PathMatch("CLOKSPL.EXE", useEndsWith: true), GetSafeDiscCLOKSPLVersion, "SafeDisc"),
new(new FilePathMatch("CLCD16.DLL"), GetSafeDiscCLCD16Version, "SafeDisc"),
new(new FilePathMatch("CLCD32.DLL"), GetSafeDiscCLCD32Version, "SafeDisc"),
new(new FilePathMatch("CLOKSPL.EXE"), GetSafeDiscCLOKSPLVersion, "SafeDisc"),
//new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), GetSafeDisc00000001TMPVersion, "SafeDisc"),
new PathMatchSet(new PathMatch("00000002.TMP", useEndsWith: true), "SafeDisc 2+"),
//new(new FilePathMatch("00000001.TMP"), GetSafeDisc00000001TMPVersion, "SafeDisc"),
new(new FilePathMatch("00000002.TMP"), "SafeDisc 2+"),
// TODO: Research "splash16.bmp" and "splash256.bmp".
new PathMatchSet(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
new PathMatchSet(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
new(new FilePathMatch("DPLAYERX.DLL"), GetSafeDiscDPlayerXVersion, "SafeDisc"),
new(new FilePathMatch("drvmgt.dll"), GetSafeDiscDrvmgtVersion, "SafeDisc"),
// The SD0XXX.dll files appear to solely contain custom strings that allowed the publisher to customize the SafeDisc error messages. They are currently only known to be used by EA.
// Each file appears to contain strings for a specific language each.
@@ -241,54 +246,54 @@ namespace BinaryObjectScanner.Protection
// "d:\DiceCanada\BoosterPack2\Installers\BF2XpackInstaller\Safedisk\SafeDiscDLLs\DLLs\Release\SD0816.pdb" (Redump entry 65569).
// Found in Redump entries 20729 and 65569.
new PathMatchSet(new PathMatch("SD040e.dll", useEndsWith: true), "SafeDisc"),
new(new FilePathMatch("SD040e.dll"), "SafeDisc"),
// Found in Redump entry 65569.
new PathMatchSet(new PathMatch("SD0c0a.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD040b.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD040c.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0419.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD041d.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD041e.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0404.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0405.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0406.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0407.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0409.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0410.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0411.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0412.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0413.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0414.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0415.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0416.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0804.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0809.dll", useEndsWith: true), "SafeDisc"),
new PathMatchSet(new PathMatch("SD0816.dll", useEndsWith: true), "SafeDisc"),
new(new FilePathMatch("SD0c0a.dll"), "SafeDisc"),
new(new FilePathMatch("SD040b.dll"), "SafeDisc"),
new(new FilePathMatch("SD040c.dll"), "SafeDisc"),
new(new FilePathMatch("SD0419.dll"), "SafeDisc"),
new(new FilePathMatch("SD041d.dll"), "SafeDisc"),
new(new FilePathMatch("SD041e.dll"), "SafeDisc"),
new(new FilePathMatch("SD0404.dll"), "SafeDisc"),
new(new FilePathMatch("SD0405.dll"), "SafeDisc"),
new(new FilePathMatch("SD0406.dll"), "SafeDisc"),
new(new FilePathMatch("SD0407.dll"), "SafeDisc"),
new(new FilePathMatch("SD0409.dll"), "SafeDisc"),
new(new FilePathMatch("SD0410.dll"), "SafeDisc"),
new(new FilePathMatch("SD0411.dll"), "SafeDisc"),
new(new FilePathMatch("SD0412.dll"), "SafeDisc"),
new(new FilePathMatch("SD0413.dll"), "SafeDisc"),
new(new FilePathMatch("SD0414.dll"), "SafeDisc"),
new(new FilePathMatch("SD0415.dll"), "SafeDisc"),
new(new FilePathMatch("SD0416.dll"), "SafeDisc"),
new(new FilePathMatch("SD0804.dll"), "SafeDisc"),
new(new FilePathMatch("SD0809.dll"), "SafeDisc"),
new(new FilePathMatch("SD0816.dll"), "SafeDisc"),
// Found in Redump entries 28810 and 30555.
// Name check overmatches with a seemingly completely unrelated application, ironically included on at least one SafeDisc game (Redump entry 34828).
// new PathMatchSet(new PathMatch("mcp.dll", useEndsWith: true), "SafeDisc (Version 1.45.011-1.50.020)"),
// new(new FilePathMatch("mcp.dll"), "SafeDisc (Version 1.45.011-1.50.020)"),
// Found in Redump entry 58455 and 65569.
// Unknown if it's a game specific file, but it contains the stxt371 and stxt774 sections.
// new PathMatchSet(new PathMatch("CoreDLL.dll", useEndsWith: true), "SafeDisc"),
// new(new FilePathMatch("CoreDLL.dll"), "SafeDisc"),
// Found in Redump entry 58990.
new PathMatchSet(new PathMatch("SafediskSplash.bmp", useEndsWith: true), "SafeDisc"),
new(new FilePathMatch("SafediskSplash.bmp"), "SafeDisc"),
// Used to distribute SafeDisc driver updates over the internet. Two distinct versions known to exist, with Microsoft also having distributed the later update as well.
// Version 1: https://web.archive.org/web/20040614184055/http://www.macrovision.com:80/products/safedisc/safedisc.exe
// Version 2: https://web.archive.org/web/20051104123646/http://www.macrovision.com/products/safedisc/safedisc.exe
// Microsoft download page: https://web.archive.org/web/20080204081329/http://www.microsoft.com/downloads/details.aspx?FamilyID=eae20f0f-c41c-44fe-84ce-1df707d7a2e9&DisplayLang=en
new PathMatchSet(new PathMatch("safedisc.exe", useEndsWith: true), "SafeDisc Driver Installer"),
new(new FilePathMatch("safedisc.exe"), "SafeDisc Driver Installer"),
// Found in seemingly every SafeDisc Lite disc. (CD: Redump entries 25579 and 57986. DVD: Redump entry 63941).
new PathMatchSet(new PathMatch("00000001.LT1", useEndsWith: true), "SafeDisc Lite"),
new PathMatchSet(new PathMatch("LTDLL.DLL", useEndsWith: true), "SafeDisc Lite"),
new(new FilePathMatch("00000001.LT1"), "SafeDisc Lite"),
new(new FilePathMatch("LTDLL.DLL"), "SafeDisc Lite"),
// Found in Redump entry 42762.
new PathMatchSet(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
new(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -301,21 +306,20 @@ namespace BinaryObjectScanner.Protection
// The hash of the file CLCD16.dll is able to provide a broad version range that appears to be consistent, but it seems it was rarely updated so these checks are quite broad.
var sha1 = GetFileSHA1(firstMatchedString);
switch (sha1)
return sha1 switch
{
// Found in Redump entries 61731 and 66005.
case "C13493AB753891B8BEE9E4E014896B026C01AC92":
return "1.00.025-1.01.044";
"C13493AB753891B8BEE9E4E014896B026C01AC92" => "1.00.025-1.01.044",
// Found in Redump entries 1882 and 30049.
// It is currently unknown why the previous hash covers both the version before this one, and several afterwards, with this one being a consistent outlier between these versions.
case "2418D791C7B9D4F05BCB01FAF98F770CDF798464":
return "1.00.026";
"2418D791C7B9D4F05BCB01FAF98F770CDF798464" => "1.00.026",
// Found in Redump entries 31149 and 28810.
case "848EDF9F45A8437438B7289BB4D2D1BCF752FD4A":
return "1.06.000-1.50.020/Lite";
default:
return "Unknown Version (Report this to us on GitHub)";
}
"848EDF9F45A8437438B7289BB4D2D1BCF752FD4A" => "1.06.000-1.50.020/Lite",
_ => "Unknown Version (Report this to us on GitHub)",
};
}
internal static string GetSafeDiscCLCD32Version(string firstMatchedString, IEnumerable<string>? files)
@@ -325,86 +329,85 @@ namespace BinaryObjectScanner.Protection
// The hash of the file CLCD32.dll so far appears to be a solid indicator of version for versions it was used with. It appears to have been updated with every release, unlike its counterpart, CLCD16.dll.
var sha1 = GetFileSHA1(firstMatchedString);
switch (sha1)
return sha1 switch
{
// Found in Redump entry 66005.
case "BAD49BA0DEA041E85EF1CABAA9F0ECD822CE1376":
return "1.00.025";
"BAD49BA0DEA041E85EF1CABAA9F0ECD822CE1376" => "1.00.025",
// Found in Redump entry 34828.
case "6137C7E789A329865649FCB8387B963FC8C763C6":
return "1.00.026 (pre-10/1998)";
"6137C7E789A329865649FCB8387B963FC8C763C6" => "1.00.026 (pre-10/1998)",
// Found in Redump entries 1882 and 30049.
case "AFEFBBF1033EA65C366A1156E21566DB419CFD7B":
return "1.00.026 (post-10/1998)";
"AFEFBBF1033EA65C366A1156E21566DB419CFD7B" => "1.00.026 (post-10/1998)",
// Found in Redump entries 31575 and 41923.
case "6E54AC24C344E4A132D1B7A6A61B2EC824DE5092":
return "1.00.030";
"6E54AC24C344E4A132D1B7A6A61B2EC824DE5092" => "1.00.030",
// Found in Redump entries 1883 and 42114.
case "23DAA95DAF75732C27CEB133A00F7E10D1D482D3":
return "1.00.032";
"23DAA95DAF75732C27CEB133A00F7E10D1D482D3" => "1.00.032",
// Found in Redump entries 36223 and 40771.
case "C8F609DDFC3E1CF69FADD60B7AED7A63B4B1DA62":
return "1.00.035";
"C8F609DDFC3E1CF69FADD60B7AED7A63B4B1DA62" => "1.00.035",
// Found in Redump entries 42155 and 47574.
case "39CC3C053702D9F6EFF0DF6535E54F6C78CEA639":
return "1.01.034";
"39CC3C053702D9F6EFF0DF6535E54F6C78CEA639" => "1.01.034",
// Found in Redump entry 51459.
case "BC476F625A4A7A89AE50E2A4CD0F248D6CEB5A84":
return "1.01.038";
"BC476F625A4A7A89AE50E2A4CD0F248D6CEB5A84" => "1.01.038",
// Found in Redump entries 34562 and 63304.
case "1AB79AA78F706A1A24C02CE2B9398EC78249700B":
return "1.01.043";
"1AB79AA78F706A1A24C02CE2B9398EC78249700B" => "1.01.043",
// Found in Redump entries 61731 and 81619.
case "E2326F66EA9C2E5153EC619EEE424D83E2FD4CA4":
return "1.01.044";
"E2326F66EA9C2E5153EC619EEE424D83E2FD4CA4" => "1.01.044",
// Found in Redump entries 29073 and 31149.
case "AEDE9939C4B62AC6DCCE3A771919B23A661247B3":
return "1.06.000";
"AEDE9939C4B62AC6DCCE3A771919B23A661247B3" => "1.06.000",
// Found in Redump entries 9718 and 46756.
case "B5503E2222B3DA387BB5D7150A4A32A47824988F":
return "1.07.000";
"B5503E2222B3DA387BB5D7150A4A32A47824988F" => "1.07.000",
// Found in Redump entries 12885 and 66210.
case "7D33EA7B241245182FFB7A392873079B6183050B":
return "1.09.000";
"7D33EA7B241245182FFB7A392873079B6183050B" => "1.09.000",
// Found in Redump entries 37523 and 66586.
case "61A4A5A758A5CFFB226CE2AE96E55A40AB073AC6":
return "1.11.000";
"61A4A5A758A5CFFB226CE2AE96E55A40AB073AC6" => "1.11.000",
// Found in Redump entries 21154 and 37982.
case "14D3267C1D5C925F6DA44F1B19CB14F6DFCA73E3":
return "1.20.000";
"14D3267C1D5C925F6DA44F1B19CB14F6DFCA73E3" => "1.20.000",
// Found in Redump entry 37920.
case "CB4570F3F37E0FA70D7B9F3211FDC2105864C664":
return "1.20.001";
"CB4570F3F37E0FA70D7B9F3211FDC2105864C664" => "1.20.001",
// Found in Redump entries 31526 and 55080.
case "1B5FD2D3DFBD89574D602DA9AE317C55F24902F0":
return "1.30.010";
"1B5FD2D3DFBD89574D602DA9AE317C55F24902F0" => "1.30.010",
// Found in Redump entries 9617 and 49552.
case "CC73C219BFC2D729515D25CA1B93D53672153175":
return "1.35.000";
"CC73C219BFC2D729515D25CA1B93D53672153175" => "1.35.000",
// Found in Redump entries 2595 and 30121.
case "5825FF56B50114CD5D82BD4667D7097B29973197":
return "1.40.004";
"5825FF56B50114CD5D82BD4667D7097B29973197" => "1.40.004",
// Found in Redump entries 44350 and 63323.
case "38DE3C6CF8FA89E5E99C359AA8ABFC65ADE396A5":
return "1.41.000";
"38DE3C6CF8FA89E5E99C359AA8ABFC65ADE396A5" => "1.41.000",
// Found in Redump entries 37832 and 42091.
case "894D38AD949576928F67FF1595DC9C877A34A91C":
return "1.41.001";
"894D38AD949576928F67FF1595DC9C877A34A91C" => "1.41.001",
// Found in Redump entries 30555 and 55078.
case "0235E03CA78232417C93FBB5F56B1BE819926B0C":
return "1.45.011";
"0235E03CA78232417C93FBB5F56B1BE819926B0C" => "1.45.011",
// Found in Redump entries 28810 and 62935.
case "331B777A0BA2A358982575EA3FAA2B59ECAEA404":
return "1.50.020";
"331B777A0BA2A358982575EA3FAA2B59ECAEA404" => "1.50.020",
// Found in Redump entries 57986 and 63941.
case "85A92DC1D9CCBA6349D70F489043E649A8C21F2B":
return "Lite";
"85A92DC1D9CCBA6349D70F489043E649A8C21F2B" => "Lite",
// Found in Redump entry 14928.
case "538351FF5955A3D8438E8C278E9D6D6274CF13AB":
return "Lite";
default:
return "Unknown Version (Report this to us on GitHub)";
}
"538351FF5955A3D8438E8C278E9D6D6274CF13AB" => "Lite",
_ => "Unknown Version (Report this to us on GitHub)",
};
}
internal static string GetSafeDiscCLOKSPLVersion(string firstMatchedString, IEnumerable<string>? files)
@@ -425,80 +428,79 @@ namespace BinaryObjectScanner.Protection
// The hash of every "CLOKSPL.EXE" correlates directly to a specific SafeDisc version.
var sha1 = GetFileSHA1(firstMatchedString);
switch (sha1)
return sha1 switch
{
// Found in Redump entry 66005.
case "DD131A7B988065764E2A0F20B66C89049B20A7DE":
return "1.00.025";
"DD131A7B988065764E2A0F20B66C89049B20A7DE" => "1.00.025",
// Found in Redump entry 34828.
case "41C8699A6E0F046EB7A21984441B555237DA4758":
return "1.00.026 (pre-10/1998)";
"41C8699A6E0F046EB7A21984441B555237DA4758" => "1.00.026 (pre-10/1998)",
// Found in Redump entries 1882 and 30049.
case "D1C19C26DEC7C33825FFC59AD02B0EBA782643FA":
return "1.00.026 (post-10/1998)";
"D1C19C26DEC7C33825FFC59AD02B0EBA782643FA" => "1.00.026 (post-10/1998)",
// Found in Redump entries 31575 and 41923.
case "B7C6C61688B354AB5D4E20CDEB36C992F203289B":
return "1.00.030";
"B7C6C61688B354AB5D4E20CDEB36C992F203289B" => "1.00.030",
// Found in Redump entries 1883 and 42114.
case "7445CD9FB49C322D18E92CC457DD880967C2B010":
return "1.00.032";
"7445CD9FB49C322D18E92CC457DD880967C2B010" => "1.00.032",
// Found in Redump entries 36223 and 40771.
case "50D4466F55BEDB3FE0E262235A6BAC751CA26599":
return "1.00.035";
"50D4466F55BEDB3FE0E262235A6BAC751CA26599" => "1.00.035",
// Found in Redump entries 42155 and 47574.
case "8C2F792326856C6D326707F76823FC7430AC86D5":
return "1.01.034";
"8C2F792326856C6D326707F76823FC7430AC86D5" => "1.01.034",
// Found in Redump entry 51459.
case "107BF8077255FD4CA0875FB7C306F0B427E66800":
return "1.01.038";
"107BF8077255FD4CA0875FB7C306F0B427E66800" => "1.01.038",
// Found in Redump entries 34562 and 63304.
case "E8F4BA30376FCDAE00E7B88312300172674ABFA9":
return "1.01.043";
"E8F4BA30376FCDAE00E7B88312300172674ABFA9" => "1.01.043",
// Found in Redump entries 61731 and 81619.
case "CAB911C5CFC0A13C822DBFE0F0E1570C09F211FB":
return "1.01.044";
"CAB911C5CFC0A13C822DBFE0F0E1570C09F211FB" => "1.01.044",
// Found in Redump entries 29073 and 31149.
case "43C1318B38742E05E7C858A02D64EEA13D9DFB9B":
return "1.06.000";
"43C1318B38742E05E7C858A02D64EEA13D9DFB9B" => "1.06.000",
// Found in Redump entries 9718 and 46756.
case "451BD4C60AB826C16840815996A5DF03672666A8":
return "1.07.000";
"451BD4C60AB826C16840815996A5DF03672666A8" => "1.07.000",
// Found in Redump entries 12885 and 66210.
case "6C02A20A521112777D4843B8ACD9278F34314A35":
return "1.09.000";
"6C02A20A521112777D4843B8ACD9278F34314A35" => "1.09.000",
// Found in Redump entries 37523 and 66586.
case "0548F1B12F60395C9394DDB7BED5E3E65E09D72E":
return "1.11.000";
"0548F1B12F60395C9394DDB7BED5E3E65E09D72E" => "1.11.000",
// Found in Redump entries 21154 and 37982.
case "64A406FE640F2AC86A0E23F619F6EBE63BFFB8A1":
return "1.20.000";
"64A406FE640F2AC86A0E23F619F6EBE63BFFB8A1" => "1.20.000",
// Found in Redump entry 37920.
case "8E874C9AF4CE5A9F1CBE96FCC761AA1C201C6938":
return "1.20.001";
"8E874C9AF4CE5A9F1CBE96FCC761AA1C201C6938" => "1.20.001",
// Found in Redump entries 31526 and 55080.
case "766EC536A10E68513138D1183705F5F19B9B8091":
return "1.30.010";
"766EC536A10E68513138D1183705F5F19B9B8091" => "1.30.010",
// Found in Redump entries 9617 and 49552.
case "1F1460FD66DD518159CCCDC99C12252EA0B2EEC4":
return "1.35.000";
"1F1460FD66DD518159CCCDC99C12252EA0B2EEC4" => "1.35.000",
// Found in Redump entries 2595 and 30121.
case "B1CF007BA36BA1B207DE334635F7BCEC146F8E35":
return "1.40.004";
"B1CF007BA36BA1B207DE334635F7BCEC146F8E35" => "1.40.004",
// Found in Redump entries 44350 and 63323.
case "90F92A6DB15387F4C7619C442493791EBFC1041B":
return "1.41.000";
"90F92A6DB15387F4C7619C442493791EBFC1041B" => "1.41.000",
// Found in Redump entries 37832 and 42091.
case "836D42BF7B7AD719AB67682CF8D6B2D9C07AD218":
return "1.41.001";
"836D42BF7B7AD719AB67682CF8D6B2D9C07AD218" => "1.41.001",
// Found in Redump entries 30555 and 55078.
case "24DE959BC4484CD95DAA26947670C63A161E64AE":
return "1.45.011";
"24DE959BC4484CD95DAA26947670C63A161E64AE" => "1.45.011",
// Found in Redump entries 28810 and 62935.
case "9758F0637184816D02049A53CD2653F0BFFE92C9":
return "1.50.020";
default:
return "Unknown Version (Report this to us on GitHub)";
}
"9758F0637184816D02049A53CD2653F0BFFE92C9" => "1.50.020",
_ => "Unknown Version (Report this to us on GitHub)",
};
}
internal static string GetSafeDiscDPlayerXVersion(string firstMatchedString, IEnumerable<string>? files)
@@ -506,48 +508,39 @@ namespace BinaryObjectScanner.Protection
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
FileInfo fi = new FileInfo(firstMatchedString);
switch (fi.Length)
var fi = new FileInfo(firstMatchedString);
return fi.Length switch
{
// File size of "dplayerx.dll" and others is a commonly used indicator of SafeDisc version, though it has been found to not be completely consistent.
// Checks for versions 1.2X have been commented out, due to these versions already being detected via more accurate checks.
// Examples of "dplayerx.dll" that are detected using these more accurate checks can be found in Redump entries 28810, 30121, and 37982.
// Found in Redump entry 34828.
case 81_408:
return "1.00.026 (pre-10/1998)";
81_408 => "1.00.026 (pre-10/1998)",
// Found in Redump entries 21154, 41923, 42114, and 66005.
case 78_848:
return "1.00.025-1.00.032";
78_848 => "1.00.025-1.00.032",
// Found in Redump entries 36223 and 40771.
case 77_824:
return "1.00.035";
77_824 => "1.00.035",
// Found in Redump entries 42155 and 47574.
case 115_712:
return "1.01.034";
115_712 => "1.01.034",
// Found in Redump entry 42155.
case 116_736:
return "1.01.038";
116_736 => "1.01.038",
// Found in Redump entries 34562 and 63304.
case 124_416:
return "1.01.043";
124_416 => "1.01.043",
// Found in Redump entries 61731 and 81619.
case 125_952:
return "1.01.044";
125_952 => "1.01.044",
// Found in Redump entries 29073 and 31149.
case 155_648:
return "1.06.000";
155_648 => "1.06.000",
// Found in Redump entries 9718, 12885, and 37523.
case 156_160:
return "1.07.000-1.11.000";
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.
// 157,184 bytes corresponds to SafeDisc 1.20.000-1.20.001 (Redump entries 21154 and 37920).
@@ -558,9 +551,8 @@ namespace BinaryObjectScanner.Protection
// 136,704 bytes corresponds to SafeDisc 1.45.011 (Redump entries 30555 and 55078).
// 138,752 bytes corresponds to SafeDisc 1.50.020 (Redump entries 28810 and 62935).
default:
return "1";
}
_ => "1",
};
}
internal static string GetSafeDiscDrvmgtVersion(string firstMatchedString, IEnumerable<string>? files)
@@ -573,200 +565,169 @@ namespace BinaryObjectScanner.Protection
// Particularly interesting inconsistencies will be noted below:
// Redump entry 73786 has an EXE with a scrubbed version, a DIAG.exe with a version of 4.60.000, and a copy of drvmgt.dll belonging to version 3.10.020. This seems like an accidental(?) distribution of older drivers, as this game was released 3 years after the use of 3.10.020.
var sha1 = GetFileSHA1(firstMatchedString);
switch (sha1)
return sha1 switch
{
// Found in Redump entry 102979.
case "B858CB282617FB0956D960215C8E84D1CCF909C6":
return "(Empty File)";
"B858CB282617FB0956D960215C8E84D1CCF909C6" => "(Empty File)",
// Found in Redump entries 29073 and 31149.
case "33434590D7DE4EEE2C35FCC98B0BF141F422B26D":
return "1.06.000";
"33434590D7DE4EEE2C35FCC98B0BF141F422B26D" => "1.06.000",
// Found in Redump entries 9718 and 46756.
case "D5E4C99CDCA8091EC8010FCB96C5534A8BE35B43":
return "1.07.000";
"D5E4C99CDCA8091EC8010FCB96C5534A8BE35B43" => "1.07.000",
// Found in Redump entries 12885 and 66210.
case "412067F80F6B644EDFB25932EA34A7E92AD4FC21":
return "1.09.000";
"412067F80F6B644EDFB25932EA34A7E92AD4FC21" => "1.09.000",
// Found in Redump entries 37523 and 66586.
case "87C0DA1B52681FA8052A915E85699738993BEA72":
return "1.11.000";
"87C0DA1B52681FA8052A915E85699738993BEA72" => "1.11.000",
// Found in Redump entries 21154 and 37982.
case "3569FE747311265FDC83CBDF13361B4E06484725":
return "1.20.000";
"3569FE747311265FDC83CBDF13361B4E06484725" => "1.20.000",
// Found in Redump entry 37920.
case "89795A34A2CAD4602713524365F710948F7367D0":
return "1.20.001";
"89795A34A2CAD4602713524365F710948F7367D0" => "1.20.001",
// Found in Redump entries 31526 and 55080.
case "D31725FF99BE44BC1BFFF171F4C4705F786B8E91":
return "1.30.010";
"D31725FF99BE44BC1BFFF171F4C4705F786B8E91" => "1.30.010",
// Found in Redump entries 9617 and 49552.
case "2A86168FE8EFDFC31ABCC7C5D55A1A693F2483CD":
return "1.35.000";
"2A86168FE8EFDFC31ABCC7C5D55A1A693F2483CD" => "1.35.000",
// Found in Redump entries 2595 and 30121.
case "8E41DB1C60BBAC631B06AD4F94ADB4214A0E65DC":
return "1.40.004";
"8E41DB1C60BBAC631B06AD4F94ADB4214A0E65DC" => "1.40.004",
// Found in Redump entries 44350 and 63323.
case "833EA803FB5B0FA22C9CF4DD840F0B7DE31D24FE":
return "1.41.000";
"833EA803FB5B0FA22C9CF4DD840F0B7DE31D24FE" => "1.41.000",
// Found in Redump entries 37832 and 42091.
case "1A9C8F6A5BD68F23CA0C8BCB890991AB214F14E0":
return "1.41.001";
"1A9C8F6A5BD68F23CA0C8BCB890991AB214F14E0" => "1.41.001",
// Found in Redump entries 30555 and 55078.
case "0BF4574813EA92FEE373481CA11DF220B6C4F61A":
return "1.45.011";
"0BF4574813EA92FEE373481CA11DF220B6C4F61A" => "1.45.011",
// Found in Redump entries 28810 and 62935.
case "812121D39D6DCC4947E177240655903DEC4DA15A":
return "1.50.020";
"812121D39D6DCC4947E177240655903DEC4DA15A" => "1.50.020",
// Found in Redump entries 72195 and 73502.
case "04ED7AC39FE7A6FAB497A498CBCFF7DA19BF0556":
return "2.05.030";
"04ED7AC39FE7A6FAB497A498CBCFF7DA19BF0556" => "2.05.030",
// Found in Redump entries 38541 and 59462 and 81096.
case "0AB8330A33E188A29E8CE1EA9625AA5935D7E8CE":
return "2.10.030";
"0AB8330A33E188A29E8CE1EA9625AA5935D7E8CE" => "2.10.030",
// Found in Redump entries 55823 and 79476.
case "5198DA51184CA9F3A8096C6136F645B454A85F6C":
return "2.30.030";
"5198DA51184CA9F3A8096C6136F645B454A85F6C" => "2.30.030",
// Found in Redump entries 15312 and 48863.
case "414CAC2BE3D9BE73796D51A15076A5A323ABBF2C":
return "2.30.031";
"414CAC2BE3D9BE73796D51A15076A5A323ABBF2C" => "2.30.031",
// Found in Redump entries 9819 and 53658.
case "126DCA2317DA291CBDE13A91B3FE47BA4719446A":
return "2.30.033";
"126DCA2317DA291CBDE13A91B3FE47BA4719446A" => "2.30.033",
// Found in Redump entries 9846 and 65642.
case "1437C8C149917C76F741C6DBEE6B6B0CC0664F13":
return "2.40.010";
"1437C8C149917C76F741C6DBEE6B6B0CC0664F13" => "2.40.010",
// Found in Redump entries 23786 and 37478.
case "10FAD492991C251C9C9394A2B746C1BF48A18173":
return "2.40.011";
"10FAD492991C251C9C9394A2B746C1BF48A18173" => "2.40.011",
// Found in Redump entries 30022 and 75014.
case "94267BB97C418A6AA22C1354E38136F889EB0B6A":
return "2.51.020";
"94267BB97C418A6AA22C1354E38136F889EB0B6A" => "2.51.020",
// Found in Redump entries 31666 and 66852.
case "27D5E7F7EEE1F22EBDAA903A9E58A7FDB50EF82C":
return "2.51.021";
"27D5E7F7EEE1F22EBDAA903A9E58A7FDB50EF82C" => "2.51.021",
// Found in Redump entries 2064 and 47047.
case "F346F4D0CAB4775041AD692A6A49C47D34D46571":
return "2.60.052";
"F346F4D0CAB4775041AD692A6A49C47D34D46571" => "2.60.052",
// Found in Redump entries 13048 and 35385.
case "88C7AA6E91C9BA5F2023318048E3C3571088776F":
return "2.70.030";
"88C7AA6E91C9BA5F2023318048E3C3571088776F" => "2.70.030",
// Found in Redump entries 48101 and 64198.
case "544EE77889092129E9818B5086E19197E5771C7F":
return "2.72.000";
"544EE77889092129E9818B5086E19197E5771C7F" => "2.72.000",
// Found in Redump entries 32783 and 72743.
case "EA6E24B1F306391CD78A1E7C2F2C0C31828EF004":
return "2.80.010";
"EA6E24B1F306391CD78A1E7C2F2C0C31828EF004" => "2.80.010",
// Found in Redump entries 39273 and 59351.
case "1BF885FDEF8A1824C34C10E2729AD133F70E1516":
return "2.80.011";
"1BF885FDEF8A1824C34C10E2729AD133F70E1516" => "2.80.011",
// Found in Redump entries 11638, 52606, and 62505.
case "B824ED257946EEE93F438B25C855E9DDE7A3671A":
return "2.90.010-2.90.040";
"B824ED257946EEE93F438B25C855E9DDE7A3671A" => "2.90.010-2.90.040",
// Found in Redump entries 13230 and 68204.
case "CDA56FD150C9E9A19D7AF484621352122431F029":
return "3.10.020";
"CDA56FD150C9E9A19D7AF484621352122431F029" => "3.10.020",
// Found in Redump entries 36511 and 74338.
case "E5504C4C31561D38C1F626C851A8D06212EA13E0":
return "3.15.010";
"E5504C4C31561D38C1F626C851A8D06212EA13E0" => "3.15.010",
// Found in Redump entries 15383 and 35512.
case "AABA7B3EF08E80BC55282DA3C3B7AA598379D385":
return "3.15.011";
"AABA7B3EF08E80BC55282DA3C3B7AA598379D385" => "3.15.011",
// Found in Redump entries 58625, 75782, and 84586.
// The presence of any drvmgt.dll file at all is notably missing in several games with SafeDisc versions 3.20.020-3.20.024, including Redump entries 20729, 30404, and 56748.
// TODO: Further investigate versions 3.20.020-3.20.024, and verify that 3.20.024 doesn't use drvmgt.dll at all.
case "ECB341AB36C5B3B912F568D347368A6A2DEF8D5F":
return "3.20.020-3.20.022";
"ECB341AB36C5B3B912F568D347368A6A2DEF8D5F" => "3.20.020-3.20.022",
// Found in Redump entries 53666, 76775, and 102301.
case "69C776F67EBD53CB5FD760B498B4A491BF22F293":
return "3.20.022";
"69C776F67EBD53CB5FD760B498B4A491BF22F293" => "3.20.022",
// Found in Redump entry 102806.
case "2BD7CD06CED6F6FB1A31AAE2D6C403C166366C6F":
return "3.20.022";
"2BD7CD06CED6F6FB1A31AAE2D6C403C166366C6F" => "3.20.022",
// Found in Redump entries 15614, 79729, 83408, and 86196.
// The presence of any drvmgt.dll file at all is notably missing in several games with SafeDisc versions 4.00.001-4.00.003, including Redump entries 33326, 51597, and 67927.
case "E21FF43C2E663264D6CB11FBBC31EB1DCEE42B1A":
return "4.00.000-4.00.003";
"E21FF43C2E663264D6CB11FBBC31EB1DCEE42B1A" => "4.00.000-4.00.003",
// Found in Redump entry 49677.
case "7C5AB9BDF965B70E60B99086519327168F43F362":
return "4.00.002";
"7C5AB9BDF965B70E60B99086519327168F43F362" => "4.00.002",
// Found in Redump entries 46765 and 78980.
case "A5247EC0EC50B8F470C93BF23E3F2514C402D5AD":
return "4.00.002+";
"A5247EC0EC50B8F470C93BF23E3F2514C402D5AD" => "4.00.002+",
// Found in Redump entries 74564 and 80776.
// The presence of any drvmgt.dll file at all is notably missing in several games with SafeDisc versions 4.50.000, including Redump entries 58990 and 65569.
case "C658E0B4992903D5E8DD9B235C25CB07EE5BFEEB":
return "4.50.000";
// Found in Redump entry 20092.
case "02F373C1D246DBEFBFD5F39B6D0E40E2964B0027":
return "4.60.000";
// Found in Redump entry 56320.
case "84480ABCE4676EEB9C43DFF7C5C49F0D574FAC25":
return "4.70.000";
// Found distributed in https://web.archive.org/web/20040614184055/http://www.macrovision.com:80/products/safedisc/safedisc.exe and https://web.archive.org/web/20010707163339/http://www.macrovision.com:80/demos/safedisc.exe, but unknown what version it is associated with.
case "8426690FA43076EE466FD1B2D1F2F1267F9CC3EC":
return "Unknown Version (Report this to us on GitHub)";
default:
return "Unknown Version (Report this to us on GitHub)";
"C658E0B4992903D5E8DD9B235C25CB07EE5BFEEB" => "4.50.000",
// File size of drvmgt.dll and others is a commonly used indicator of SafeDisc version, though it has been found to not be completely consistent, and is completely replaced by hash checks.
// 34,816 bytes corresponds to SafeDisc 1.0x
// 32,256 bytes corresponds to SafeDisc 1.1x-1.3x
// 31,744 bytes corresponds to SafeDisc 1.4x
// 34,304 bytes corresponds to SafeDisc 1.5x-2.40
// 35,840 bytes corresponds to SafeDisc 2.51-2.60
// 40,960 bytes corresponds to SafeDisc 2.70
// 23,552 bytes corresponds to SafeDisc 2.80
// 41,472 bytes corresponds to SafeDisc 2.90-3.10
// 24,064 bytes corresponds to SafeDisc 3.15-3.20;
}
// Found in Redump entry 20092.
"02F373C1D246DBEFBFD5F39B6D0E40E2964B0027" => "4.60.000",
// Found in Redump entry 56320.
"84480ABCE4676EEB9C43DFF7C5C49F0D574FAC25" => "4.70.000",
// Found distributed in https://web.archive.org/web/20040614184055/http://www.macrovision.com:80/products/safedisc/safedisc.exe and https://web.archive.org/web/20010707163339/http://www.macrovision.com:80/demos/safedisc.exe, but unknown what version it is associated with.
"8426690FA43076EE466FD1B2D1F2F1267F9CC3EC" => "Unknown Version (Report this to us on GitHub)",
_ => "Unknown Version (Report this to us on GitHub)",
};
}
private string? GetVersionFromSHA1Hash(string sha1Hash)
{
switch (sha1Hash.ToLowerInvariant())
return sha1Hash.ToLowerInvariant() switch
{
// dplayerx.dll
case "f7a57f83bdc29040e20fd37cd0c6d7e6b2984180":
return "1.00.030";
case "a8ed1613d47d1b5064300ff070484528ebb20a3b":
return "1.11.000";
case "ed680e9a13f593e7a80a69ee1035d956ab62212b":
return "1.3x";
case "66d8589343e00fa3e11bbf462e38c6f502515bea":
return "1.30.010";
case "5751ae2ee805d31227cfe7680f3c8be4ab8945a3":
return "1.40";
"f7a57f83bdc29040e20fd37cd0c6d7e6b2984180" => "1.00.030",
"a8ed1613d47d1b5064300ff070484528ebb20a3b" => "1.11.000",
"ed680e9a13f593e7a80a69ee1035d956ab62212b" => "1.3x",
"66d8589343e00fa3e11bbf462e38c6f502515bea" => "1.30.010",
"5751ae2ee805d31227cfe7680f3c8be4ab8945a3" => "1.40",
// secdrv.sys
case "b64ad3ec82f2eb9fb854512cb59c25a771322181":
return "1.11.000";
case "ebf69b0a96adfc903b7e486708474dc864cc0c7c":
return "1.40.004";
case "f68a1370660f8b94f896bbba8dc6e47644d19092":
return "2.30";
case "60bc8c3222081bf76466c521474d63714afd43cd":
return "2.40";
case "08ceca66432278d8c4e0f448436b77583c3c61c8":
return "2.50";
case "10080eb46bf76ac9cf9ea74372cfa4313727f0ca":
return "2.51";
case "832d359a6de191c788b0e61e33f3d01f8d793d3c":
return "2.70";
case "afcfaac945a5b47712719a5e6a7eb69e36a5a6e0":
case "cb24fbe8aa23a49e95f3c83fb15123ffb01f43f4":
return "2.80";
case "0383b69f98d0a9c0383c8130d52d6b431c79ac48":
return "2.90";
case "d7c9213cc78ff57f2f655b050c4d5ac065661aa9":
return "3.20";
case "fc6fedacc21a7244975b8f410ff8673285374cc2":
return "4.00.002"; // Also 4.60.000, might be a fluke
case "2d9f54f35f5bacb8959ef3affdc3e4209a4629cb":
return "1-4";
"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",
default:
return null;
}
_ => null,
};
}
private string GetSafeDiscDiagExecutableVersion(PortableExecutable pex)
@@ -775,23 +736,22 @@ namespace BinaryObjectScanner.Protection
var version = pex.FileVersion;
if (!string.IsNullOrEmpty(version))
{
switch (version)
return version switch
{
// Found to be in Redump entry 65569.
// The product version is "4.50.00.1619 2005/06/08".
case "4.50.00.1619":
return "4.50.0.1619 / SafeDisc 4.50.000";
"4.50.00.1619" => "4.50.0.1619 / SafeDisc 4.50.000",
// Found to be in Redump entry 20092.
// The product version is "4.60.00.1702 2005/08/03".
case "4.60.00.1702":
return "4.60.0.1702 / SafeDisc 4.60.000";
"4.60.00.1702" => "4.60.0.1702 / SafeDisc 4.60.000",
// Found to be in Redump entry 34783.
// The product version is "4.70.00.1941 2006/04/26".
case "4.70.00.1941":
return "4.70.0.1941 / SafeDisc 4.70.000";
default:
return $"Unknown Version {version} (Report this to us on GitHub)";
}
"4.70.00.1941" => "4.70.0.1941 / SafeDisc 4.70.000",
_ => $"Unknown Version {version} (Report this to us on GitHub)",
};
}
return "Unknown Version (Report this to us on GitHub)";

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -27,16 +29,16 @@ namespace BinaryObjectScanner.Protection
// Run C-Dilla NE checks
var cDilla = CDillaCheckNewExecutable(file, nex, includeDebug);
if (!string.IsNullOrWhiteSpace(cDilla))
if (!string.IsNullOrEmpty(cDilla))
resultsList.Add(cDilla!);
// Run SafeCast NE checks
var safeCast = SafeCastCheckNewExecutable(file, nex, includeDebug);
if (!string.IsNullOrWhiteSpace(safeCast))
if (!string.IsNullOrEmpty(safeCast))
resultsList.Add(safeCast!);
if (resultsList != null && resultsList.Count > 0)
return string.Join(", ", resultsList);
return string.Join(", ", [.. resultsList]);
return null;
}
@@ -73,7 +75,7 @@ namespace BinaryObjectScanner.Protection
{
// Check the header padding for protected sections.
var sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, true);
if (!string.IsNullOrWhiteSpace(sectionMatch))
if (!string.IsNullOrEmpty(sectionMatch))
{
resultsList.Add(sectionMatch!);
}
@@ -81,7 +83,7 @@ namespace BinaryObjectScanner.Protection
{
// Get the .data section, if it exists, for protected sections.
sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), true);
if (!string.IsNullOrWhiteSpace(sectionMatch))
if (!string.IsNullOrEmpty(sectionMatch))
resultsList.Add(sectionMatch!);
}
@@ -110,7 +112,7 @@ namespace BinaryObjectScanner.Protection
{
// Check the header padding for protected sections.
var sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, false);
if (!string.IsNullOrWhiteSpace(sectionMatch))
if (!string.IsNullOrEmpty(sectionMatch))
{
resultsList.Add(sectionMatch!);
}
@@ -118,138 +120,178 @@ namespace BinaryObjectScanner.Protection
{
// Check the .data section, if it exists, for protected sections.
sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), false);
if (!string.IsNullOrWhiteSpace(sectionMatch))
if (!string.IsNullOrEmpty(sectionMatch))
resultsList.Add(sectionMatch!);
}
}
// Run Cactus Data Shield PE checks
var match = CactusDataShieldCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Run C-Dilla PE checks
match = CDillaCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Run RipGuard PE checks
match = RipGuardCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Run SafeCast PE checks
match = SafeCastCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Run SafeDisc PE checks
match = SafeDiscCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Run FLEXnet PE checks
match = FLEXnetCheckPortableExecutable(file, pex, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
resultsList.Add(match!);
// Clean the result list
resultsList = CleanResultList(resultsList);
if (resultsList != null && resultsList.Count > 0)
return string.Join(", ", resultsList);
return string.Join(", ", [.. resultsList]);
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
{
#if NET20 || NET35
var results = new Queue<string>();
#else
var results = new ConcurrentQueue<string>();
#endif
// Run Macrovision directory checks
var macrovision = MacrovisionCheckDirectoryPath(path, files);
#if NET20 || NET35
if (macrovision != null && macrovision.Count > 0)
#else
if (macrovision != null && !macrovision.IsEmpty)
#endif
results.AddRange(macrovision);
// Run Cactus Data Shield directory checks
var cactusDataShield = CactusDataShieldCheckDirectoryPath(path, files);
#if NET20 || NET35
if (cactusDataShield != null && cactusDataShield.Count > 0)
#else
if (cactusDataShield != null && !cactusDataShield.IsEmpty)
#endif
results.AddRange(cactusDataShield);
// Run C-Dilla directory checks
var cDilla = CDillaCheckDirectoryPath(path, files);
#if NET20 || NET35
if (cDilla != null && cDilla.Count > 0)
#else
if (cDilla != null && !cDilla.IsEmpty)
#endif
results.AddRange(cDilla);
// Run RipGuard directory checks
var ripGuard = RipGuardCheckDirectoryPath(path, files);
#if NET20 || NET35
if (ripGuard != null && ripGuard.Count > 0)
#else
if (ripGuard != null && !ripGuard.IsEmpty)
#endif
results.AddRange(ripGuard);
// Run SafeCast directory checks
var safeCast = SafeCastCheckDirectoryPath(path, files);
#if NET20 || NET35
if (safeCast != null && safeCast.Count > 0)
#else
if (safeCast != null && !safeCast.IsEmpty)
#endif
results.AddRange(safeCast);
// Run SafeDisc directory checks
var safeDisc = SafeDiscCheckDirectoryPath(path, files);
#if NET20 || NET35
if (safeDisc != null && safeDisc.Count > 0)
#else
if (safeDisc != null && !safeDisc.IsEmpty)
#endif
results.AddRange(safeDisc);
if (results != null && results.Count > 0)
return results;
#if NET20 || NET35
return new Queue<string>();
#else
return new ConcurrentQueue<string>();
#endif
}
/// <inheritdoc/>
public string? CheckFilePath(string path)
{
List<string> resultsList = new List<string>();
var resultsList = new List<string>();
// Run Macrovision file checks
var macrovision = MacrovisionCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(macrovision))
if (!string.IsNullOrEmpty(macrovision))
resultsList.Add(macrovision!);
// Run Cactus Data Shield file checks
var cactusDataShield = CactusDataShieldCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(cactusDataShield))
if (!string.IsNullOrEmpty(cactusDataShield))
resultsList.Add(cactusDataShield!);
// Run C-Dilla file checks
var cDilla = CDillaCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(cDilla))
if (!string.IsNullOrEmpty(cDilla))
resultsList.Add(cDilla!);
// Run RipGuard file checks
var ripGuard = RipGuardCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(ripGuard))
if (!string.IsNullOrEmpty(ripGuard))
resultsList.Add(ripGuard!);
// Run SafeCast file checks
var safeCast = SafeCastCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(safeCast))
if (!string.IsNullOrEmpty(safeCast))
resultsList.Add(safeCast!);
// Run SafeDisc file checks
var safeDisc = SafeDiscCheckFilePath(path);
if (!string.IsNullOrWhiteSpace(safeDisc))
if (!string.IsNullOrEmpty(safeDisc))
resultsList.Add(safeDisc!);
if (resultsList != null && resultsList.Count > 0)
return string.Join(", ", resultsList);
return string.Join(", ", [.. resultsList]);
return null;
}
/// <inheritdoc cref="IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
#if NET20 || NET35
internal Queue<string> MacrovisionCheckDirectoryPath(string path, IEnumerable<string>? files)
#else
internal ConcurrentQueue<string> MacrovisionCheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, string.Empty),
new PathMatchSet(new FilePathMatch("secdrv.sys"), GetSecdrvFileSizeVersion, "Macrovision Security Driver"),
new(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, string.Empty),
new(new FilePathMatch("secdrv.sys"), GetSecdrvFileSizeVersion, "Macrovision Security Driver"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -260,8 +302,8 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, string.Empty),
new PathMatchSet(new FilePathMatch("secdrv.sys"), GetSecdrvFileSizeVersion, "Macrovision Security Driver"),
new(new PathMatch("00000001.TMP", useEndsWith: true), Get00000001TMPVersion, string.Empty),
new(new FilePathMatch("secdrv.sys"), GetSecdrvFileSizeVersion, "Macrovision Security Driver"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -275,21 +317,20 @@ namespace BinaryObjectScanner.Protection
// This file is present in most, if not all, SafeDisc protected discs. It seems to have very consistent file sizes, only being found to use three different file sizes in it's entire run.
// A rough estimate of the product and version can be gotten by checking the file size.
// One filesize is known to overlap with both SafeDisc and CDS-300, and so is detected separately here.
FileInfo fi = new FileInfo(firstMatchedString);
switch (fi.Length)
var fi = new FileInfo(firstMatchedString);
return fi.Length switch
{
// Found in Redump entries 37832 and 66005.
case 20:
return "SafeDisc 1.00.025-1.41.001";
20 => "SafeDisc 1.00.025-1.41.001",
// Found in Redump entries 30555 and 58573.
case 2_048:
return "Macrovision Protection File [Likely indicates either SafeDisc 1.45.011+ (CD) or CDS-300]";
2_048 => "Macrovision Protection File [Likely indicates either SafeDisc 1.45.011+ (CD) or CDS-300]",
// Found in Redump entries 11347 and 64255.
case 20_482_048:
return "SafeDisc 3+ (DVD)";
default:
return "(Unknown Version - Report this to us on GitHub)";
}
20_482_048 => "SafeDisc 3+ (DVD)",
_ => "(Unknown Version - Report this to us on GitHub)",
};
}
// TODO: Verify these checks and remove any that may not be needed, file version checks should remove the need for any checks for 2.80+.
@@ -298,74 +339,73 @@ namespace BinaryObjectScanner.Protection
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
FileInfo fi = new FileInfo(firstMatchedString);
switch (fi.Length)
var fi = new FileInfo(firstMatchedString);
return fi.Length switch
{
// Found in Redump entry 102979.
case 1:
return "(Empty File)";
1 => "(Empty File)",
// Found in Redump entries 9718, 12885, 21154, 31149, 37523, 37920.
case 14_304:
return "/ SafeDisc 1.06.000-1.20.001";
14_304 => "/ SafeDisc 1.06.000-1.20.001",
// Found in Redump entries 9617 and 31526.
case 14_368:
return "/ SafeDisc 1.30.010-1.35.000";
14_368 => "/ SafeDisc 1.30.010-1.35.000",
// Found in Redump entries 2595, 37832, and 44350.
case 10_848:
return "/ SafeDisc 1.40.004-1.41.001";
10_848 => "/ SafeDisc 1.40.004-1.41.001",
// Found in Redump entries 30555 and 55078.
case 11_968:
return "/ SafeDisc 1.45.011";
11_968 => "/ SafeDisc 1.45.011",
// Found in Redump entries 28810 and 62935.
case 11_616:
return "/ SafeDisc 1.50.020";
11_616 => "/ SafeDisc 1.50.020",
// Found in Redump entries 72195 and 73502.
case 18_768:
return "/ SafeDisc 2.05.030";
18_768 => "/ SafeDisc 2.05.030",
// Found in Redump entries 38541 and 59462.
case 20_128:
return "/ SafeDisc 2.10.030";
20_128 => "/ SafeDisc 2.10.030",
// Found in Redump entries 9819, 15312, 55823.
case 27_440:
return "/ SafeDisc 2.30.030-2.30.033";
27_440 => "/ SafeDisc 2.30.030-2.30.033",
// Found in Redump entries 9846 and 23786.
case 28_624:
return "/ SafeDisc 2.40.010-2.40.011";
28_624 => "/ SafeDisc 2.40.010-2.40.011",
// Found in Redump entries 30022 and 31666.
case 28_400:
return "/ SafeDisc 2.51.020-2.51.021";
28_400 => "/ SafeDisc 2.51.020-2.51.021",
// Found in Redump entries 2064 and 47047.
case 29_392:
return "/ SafeDisc 2.60.052";
29_392 => "/ SafeDisc 2.60.052",
// Found in Redump entries 13048 and 48101.
case 11_376:
return "/ SafeDisc 2.70.030-2.72.000";
11_376 => "/ SafeDisc 2.70.030-2.72.000",
// Found in Redump entries 32783 and 39273.
case 12_464:
return "3.17.000 / SafeDisc 2.80.010-2.80.011";
12_464 => "3.17.000 / SafeDisc 2.80.010-2.80.011",
// Found in Redump entries 11638 and 52606.
case 12_400:
return "3.18.000 / SafeDisc 2.90.010-2.90.040";
12_400 => "3.18.000 / SafeDisc 2.90.010-2.90.040",
// Found in Redump entries 13230, 15383, and 36511.
case 12_528:
return "3.19.000 / SafeDisc 3.10.020-3.15.011";
12_528 => "3.19.000 / SafeDisc 3.10.020-3.15.011",
// Found in Redump entries 58625 and 84586.
case 11_973:
return "3.22.000 / SafeDisc 3.20.020-3.20.022";
11_973 => "3.22.000 / SafeDisc 3.20.020-3.20.022",
// Found in Redump entries 15614, 42034, 45686, 56320, 60021, 79729, and 80776.
case 163_644:
return "4.00.060 / SafeDisc 4.00.000-4.70.000";
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/.
case 23_040:
return "4.03.086 / Product Unknown";
23_040 => "4.03.086 / Product Unknown",
// Found in https://web.archive.org/web/20010417215205/http://www.macrovision.com:80/demos/Trialware.exe.
case 10_784:
return "/ SafeCast ESD 2.02.040";
10_784 => "/ SafeCast ESD 2.02.040",
// This file is not currently known to be used in versions past 4.70.000.
default:
return "/ Product Unknown (Report this to us on GitHub)";
}
_ => "/ Product Unknown (Report this to us on GitHub)",
};
}
// TODO: Combine with filesize version checks if possible.
@@ -376,36 +416,35 @@ namespace BinaryObjectScanner.Protection
var version = pex.FileVersion;
if (!string.IsNullOrEmpty(version))
{
switch (version)
return version switch
{
// Found in Redump entries 32783 and 39273.
// The product version is "3.17.000 Windows NT 2002/07/01".
case "3.17.000":
return "3.17.000 / SafeDisc 2.80.010-2.80.011";
"3.17.000" => "3.17.000 / SafeDisc 2.80.010-2.80.011",
// Found in Redump entries 11638 and 52606.
// The product version is "3.18.000 Windows NT 2002/11/14".
case "3.18.000":
return "3.18.000 / SafeDisc 2.90.010-2.90.040";
"3.18.000" => "3.18.000 / SafeDisc 2.90.010-2.90.040",
// Found in Redump entries 13230, 15383, and 36511.
// The product version is "3.19.000 Windows NT/2K/XP 2003/03/19".
case "3.19.000":
return "3.19.000 / SafeDisc 3.10.020-3.15.011";
"3.19.000" => "3.19.000 / SafeDisc 3.10.020-3.15.011",
// Found in Redump entries 58625 and 84586.
// The product version is "SECURITY Driver 3.22.000 2004/01/16".
case "3.22.000":
return "3.22.000 / SafeDisc 3.20.020-3.20.022";
"3.22.000" => "3.22.000 / SafeDisc 3.20.020-3.20.022",
// Found in Redump entries 15614, 42034, 45686, 56320, 60021, 79729, and 80776.
// The product version is "SECURITY Driver 4.00.060 2004/08/31".
case "4.00.060":
return "4.00.060 / SafeDisc 4.00.000-4.70.000";
"4.00.060" => "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/.
// The product version is "SECURITY Driver 4.03.086 2006/09/13".
case "4.03.086":
return "4.03.086 / Unknown Product";
default:
return $"Unknown Version {version} (Report this to us on GitHub)";
}
"4.03.086" => "4.03.086 / Unknown Product",
_ => $"Unknown Version {version} (Report this to us on GitHub)",
};
}
return "Unknown Version (Report this to us on GitHub)";
@@ -432,7 +471,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// BoG_ *90.0&!! Yy>
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30,
0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59,
@@ -481,102 +520,101 @@ namespace BinaryObjectScanner.Protection
private static string MacrovisionVersionToProductName(string version)
{
switch (version)
return version switch
{
// CDS-300 (Confirmed)
case "2.90.044": // Found in "American Made World Played" by Les Paul & Friends (Japan) (https://www.discogs.com/release/18934432-Les-Paul-Friends-American-Made-World-Played) and "X&Y" by Coldplay (Japan) (https://www.discogs.com/release/822378-Coldplay-XY).
return "CDS-300";
// Found in "American Made World Played" by Les Paul & Friends (Japan) (https://www.discogs.com/release/18934432-Les-Paul-Friends-American-Made-World-Played) and "X&Y" by Coldplay (Japan) (https://www.discogs.com/release/822378-Coldplay-XY).
"2.90.044" => "CDS-300",
// SafeCast (Confirmed)
// Version 1.04.000/1.4.0.0 can be found in "cdac01aa.dll" and "cdac01ba.dll" from IA item "ejay_nestle_trial", but needs further research.
case "2.11.010": // Found in Redump entry 83145.
case "2.11.020": // Found in IA item "microsoft-software-jukebox-for-toshiba-1.0".
case "2.11.060": // Found in Redump entry 102979.
case "2.16.050": // Found in IA items "cdrom-turbotax-2002", "TurboTax_Deluxe_Tax_Year_2002_for_Wndows_2.00R_Intuit_2002_352282", and "TurboTax_Premier_Tax_Year_2002_for_Windows_v02.00Z-R_Intuit_352283_2002".
case "2.60.030": // Found in Redump entry 74384 (Semi-confirmed) and "Data Becker Web To Date v3.1" according to https://web.archive.org/web/20210331144912/https://protectionid.net/ (Unconfirmed).
case "2.67.010": // Found in "[Win] Photoshop CS2.7z" in IA item "Adobe-CS2".
return "SafeCast";
// Found in Redump entry 83145.
"2.11.010"
or "2.11.020"
or "2.11.060"
or "2.16.050"
or "2.60.030"
or "2.67.010" => "SafeCast",
// SafeCast (Unconfirmed)
case "2.41.000": // Found in Adobe Photoshop according to http://www.reversing.be/article.php?story=2006102413541932
case "2.42.000": // Found in "Dreamweaver MX 2004 v7.0.1" according to https://web.archive.org/web/20210331144912/https://protectionid.net/.
case "2.50.030": // Found in "ArcSoft Media Card Companion v1.0" according to https://web.archive.org/web/20210331144912/https://protectionid.net/.
case "2.51.000": // Found in "Autodesk Inventor Professional v9.0" according to https://web.archive.org/web/20210331144912/https://protectionid.net/.
return "SafeCast (Unconfirmed - Please report to us on GitHub)";
// Found in Adobe Photoshop according to http://www.reversing.be/article.php?story=2006102413541932
"2.41.000"
or "2.42.000"
or "2.50.030"
or "2.51.000" => "SafeCast (Unconfirmed - Please report to us on GitHub)",
// SafeCast ESD (Confirmed)
case "2.02.040": // Found in https://web.archive.org/web/20010417215205/http://www.macrovision.com:80/demos/Trialware.exe.
return "SafeCast ESD";
// Found in https://web.archive.org/web/20010417215205/http://www.macrovision.com:80/demos/Trialware.exe.
"2.02.040" => "SafeCast ESD",
// SafeDisc (Confirmed)
case "1.00.025": // Found in Redump entry 66005.
case "1.00.026": // Found in Redump entries 1882 and 30049.
case "1.00.030": // Found in Redump entries 31575 and 41923.
case "1.00.032": // Found in Redump entries 1883 and 42114.
case "1.00.035": // Found in Redump entries 36223 and 40771.
case "1.01.034": // Found in Redump entries 42155 and 47574.
case "1.01.038": // Found in Redump entry 51459.
case "1.01.043": // Found in Redump entries 34562 and 63304.
case "1.01.044": // Found in Redump entries 61731 and 81619.
case "1.06.000": // Found in Redump entries 29073 and 31149.
case "1.07.000": // Found in Redump entries 9718 and 46756.
case "1.09.000": // Found in Redump entries 12885 and 66210.
case "1.11.000": // Found in Redump entries 37523 and 66586.
case "1.20.000": // Found in Redump entries 21154 and 37982.
case "1.20.001": // Found in Redump entry 37920.
case "1.30.010": // Found in Redump entries 31526 and 55080.
case "1.35.000": // Found in Redump entries 9617 and 49552.
case "1.40.004": // Found in Redump entries 2595 and 30121.
case "1.41.000": // Found in Redump entries 44350 and 63323.
case "1.41.001": // Found in Redump entries 37832 and 42091.
case "1.45.011": // Found in Redump entries 30555 and 55078.
case "1.50.020": // Found in Redump entries 28810 and 62935.
case "2.05.030": // Found in Redump entries 72195 and 73502.
case "2.10.030": // Found in Redump entries 38541, 59462, and 81096.
case "2.30.030": // Found in Redump entries 55823 and 79476.
case "2.30.031": // Found in Redump entries 15312 and 48863.
case "2.30.033": // Found in Redump entries 9819 and 53658.
case "2.40.010": // Found in Redump entries 9846 and 65642.
case "2.40.011": // Found in Redump entries 23786 and 37478.
case "2.51.020": // Found in Redump entries 30022 and 75014.
case "2.51.021": // Found in Redump entries 31666 and 66852.
case "2.60.052": // Found in Redump entries 2064 and 47047.
case "2.70.030": // Found in Redump entries 13048 and 35385.
case "2.72.000": // Found in Redump entries 48101 and 64198.
case "2.80.010": // Found in Redump entries 32783 and 72743.
case "2.80.011": // Found in Redump entries 39273 and 59351.
case "2.90.040": // Found in Redump entries 52606 and 62505.
case "3.10.020": // Found in Redump entries 13230 and 68204.
case "3.15.010": // Found in Redump entries 36511 and 74338.
case "3.15.011": // Found in Redump entries 15383 and 35512.
case "3.20.020": // Found in Redump entries 30404 and 56748.
case "3.20.022": // Found in Redump entries 58625 and 91552.
case "3.20.024": // Found in Redump entries 20729 and 63813 (CD) and Redump entries 20728 and 64255 (DVD).
case "4.00.000": // Found in Redump entries 35382 and 79729 (CD) and Redump entry 74520 (DVD).
case "4.00.001": // Found in Redump entries 8842 and 83017 (CD) and Redump entries 15614 and 38143 (DVD).
case "4.00.002": // Found in Redump entries 42034 and 71646 (CD) and Redump entries 78980 and 86196 (DVD).
case "4.00.003": // Found in Redump entries 60021 and 68551 (CD) and Redump entries 51597 and 83408 (DVD).
case "4.50.000": // Found in Redump entries 58990 and 80776 (CD) and Redump entries 65569 and 76813 (DVD).
case "4.60.000": // Found in Redump entries 45686 and 46765 (CD) and Redump entries 45469 and 50682 (DVD).
case "4.70.000": // Found in Redump entry 56320 (CD) and Redump entries 34783 and 66403 (DVD).
case "4.80.000": // Found in Redump entries 64145 and 78543 (CD only).
case "4.81.000": // Found in Redump entries 52523 and 76346 (DVD only).
case "4.85.000": // Found in Redump entries 20434 and 31766 (DVD only).
case "4.90.000": // Found in Redump entries 56319 and 66333 (DVD only).
case "4.90.010": // Found in Redump entries 58573 and 78976 (CD) and Redump entries 11347 and 29069 (DVD).
return "SafeDisc";
// Found in Redump entry 66005.
"1.00.025"
or "1.00.026"
or "1.00.030"
or "1.00.032"
or "1.00.035"
or "1.01.034"
or "1.01.038"
or "1.01.043"
or "1.01.044"
or "1.06.000"
or "1.07.000"
or "1.09.000"
or "1.11.000"
or "1.20.000"
or "1.20.001"
or "1.30.010"
or "1.35.000"
or "1.40.004"
or "1.41.000"
or "1.41.001"
or "1.45.011"
or "1.50.020"
or "2.05.030"
or "2.10.030"
or "2.30.030"
or "2.30.031"
or "2.30.033"
or "2.40.010"
or "2.40.011"
or "2.51.020"
or "2.51.021"
or "2.60.052"
or "2.70.030"
or "2.72.000"
or "2.80.010"
or "2.80.011"
or "2.90.040"
or "3.10.020"
or "3.15.010"
or "3.15.011"
or "3.20.020"
or "3.20.022"
or "3.20.024"
or "4.00.000"
or "4.00.001"
or "4.00.002"
or "4.00.003"
or "4.50.000"
or "4.60.000"
or "4.70.000"
or "4.80.000"
or "4.81.000"
or "4.85.000"
or "4.90.000"
or "4.90.010" => "SafeDisc",
// SafeDisc (Unconfirmed)
case "1.01.045": // Currently only found in a pirate compilation disc: IA item "cdrom-classic-fond-58".
return "SafeDisc (Unconfirmed - Please report to us on GitHub)";
// Currently only found in a pirate compilation disc: IA item "cdrom-classic-fond-58".
"1.01.045" => "SafeDisc (Unconfirmed - Please report to us on GitHub)",
// SafeDisc Lite (Confirmed)
case "2.60.020": // Found in Redump entry 14928.
return "SafeDisc Lite";
// Found in Redump entry 14928.
"2.60.020" => "SafeDisc Lite",
default:
return "Macrovision Protected Application (Generic detection - Report to us on GitHub)";
}
_ => "Macrovision Protected Application (Generic detection - Report to us on GitHub)",
};
}
private List<string>? CleanResultList(List<string>? resultsList)
@@ -586,7 +624,7 @@ namespace BinaryObjectScanner.Protection
return resultsList;
// Get distinct and order
return resultsList.Distinct().OrderBy(s => s).ToList();
return [.. resultsList.Distinct().OrderBy(s => s)];
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -37,14 +39,18 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// The file "sunncomm.ico" was a previously used file check, but since it's just an icon of the SunnComm logo, it seems too likely to result in false positives.
// Found on "Charley Pride - A Tribute to Jim Reeves" (barcode "7 816190222-2 4").
new PathMatchSet(new PathMatch("scvfy.exe", useEndsWith: true), "MediaCloQ"),
new(new PathMatch("scvfy.exe", useEndsWith: true), "MediaCloQ"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -58,7 +64,7 @@ namespace BinaryObjectScanner.Protection
// The file "sunncomm.ico" was a previously used file check, but since it's just an icon of the SunnComm logo, it seems too likely to result in false positives.
// Found on "Charley Pride - A Tribute to Jim Reeves" (barcode "7 816190222-2 4").
new PathMatchSet(new PathMatch("scvfy.exe", useEndsWith: true), "MediaCloQ"),
new(new PathMatch("scvfy.exe", useEndsWith: true), "MediaCloQ"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -63,26 +65,30 @@ namespace BinaryObjectScanner.Protection
}
/// <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 on "All That I Am" by Santana (Barcode 8 2876-59773-2 6)
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// TODO: Verify if these are OR or AND
// TODO: Verify that this is directly related to MediaMax CD-3.
new PathMatch("PlayDisc.exe", useEndsWith: true),
new PathMatch("PlayDisc.xml", useEndsWith: true),
new FilePathMatch("PlayDisc.exe"),
new FilePathMatch("PlayDisc.xml"),
}, "MediaMax CD-3"),
// Found on "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8)
// "SCCD3X01.dll" should already be detected by the content checks, but not "SCCD3X02.dll".
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// TODO: Verify if these are OR or AND
new PathMatch("SCCD3X01.dll", useEndsWith: true),
new PathMatch("SCCD3X02.dll", useEndsWith: true),
new FilePathMatch("SCCD3X01.dll"),
new FilePathMatch("SCCD3X02.dll"),
}, "MediaMax CD-3"),
};
@@ -95,8 +101,8 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found on "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8)
new PathMatchSet(new PathMatch("SCCD3X01.dll", useEndsWith: true), "MediaMax CD-3"),
new PathMatchSet(new PathMatch("SCCD3X02.dll", useEndsWith: true), "MediaMax CD-3"),
new(new FilePathMatch("SCCD3X01.dll"), "MediaMax CD-3"),
new(new FilePathMatch("SCCD3X02.dll"), "MediaMax CD-3"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -50,17 +52,21 @@ namespace BinaryObjectScanner.Protection
}
/// <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 installed in the main game folder.
new PathMatchSet(new PathMatch("NeacClient.exe", useEndsWith: true), "NEAC Protect"),
new PathMatchSet(new PathMatch("NeacInterface.dll", useEndsWith: true), "NEAC Protect"),
new PathMatchSet(new PathMatch("NeacSafe64.sys", useEndsWith: true), "NEAC Protect"),
new(new FilePathMatch("NeacClient.exe"), "NEAC Protect"),
new(new FilePathMatch("NeacInterface.dll"), "NEAC Protect"),
new(new FilePathMatch("NeacSafe64.sys"), "NEAC Protect"),
// Found installed in "System32\drivers".
new PathMatchSet(new PathMatch("NeacSafe.sys", useEndsWith: true), "NEAC Protect"),
new(new FilePathMatch("NeacSafe.sys"), "NEAC Protect"),
// Known associated log files: "NeacSafe.log", "Neac.log", "NeacDll.log", "NeacLoader.log", and "NeacBak.log".
};
@@ -74,12 +80,12 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found installed in the main game folder.
new PathMatchSet(new PathMatch("NeacClient.exe", useEndsWith: true), "NEAC Protect"),
new PathMatchSet(new PathMatch("NeacInterface.dll", useEndsWith: true), "NEAC Protect"),
new PathMatchSet(new PathMatch("NeacSafe64.sys", useEndsWith: true), "NEAC Protect"),
new(new FilePathMatch("NeacClient.exe"), "NEAC Protect"),
new(new FilePathMatch("NeacInterface.dll"), "NEAC Protect"),
new(new FilePathMatch("NeacSafe64.sys"), "NEAC Protect"),
// Found installed in "System32\drivers".
new PathMatchSet(new PathMatch("NeacSafe.sys", useEndsWith: true), "NEAC Protect"),
new(new FilePathMatch("NeacSafe.sys"), "NEAC Protect"),
// Known associated log files: "NeacSafe.log", "Neac.log", "NeacDll.log", "NeacLoader.log", and "NeacBak.log".
};

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
@@ -64,26 +66,30 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// So far found in every known release that uses OpenMG ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
// Files with the extension ".OMA" in the directory "OMGAUDIO" are the encrypted audio files, and files with in the directory "OMGEXTRA" the extension ".000" are bonus content.
// TODO: Investigate the consistency of "\OMGEXTRA\INDX0000.XML" and "\OMGEXTRA\INDX0001.XML", they seem to only appear when bonus content is present ("Touch" by Amerie).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch(Path.Combine("OMGAUDIO", "00AUDTOC.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGAUDIO", "01AUDSTR.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGAUDIO", "05SRPCDS.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGEXTRA", "OMGSVC.DAT").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("OMGAUDIO", "00AUDTOC.DAT").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("OMGAUDIO", "01AUDSTR.DAT").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("OMGAUDIO", "05SRPCDS.DAT").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("OMGEXTRA", "OMGSVC.DAT").Replace("\\", "/"), useEndsWith: true),
}, "OpenMG"),
// Always found together on OpenMG releases ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch(Path.Combine("SDKHM.DLL").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("SDKHM.EXE").Replace("\\", "/"), useEndsWith: true),
new FilePathMatch("SDKHM.DLL"),
new FilePathMatch("SDKHM.EXE"),
}, "OpenMG"),
};
@@ -96,22 +102,22 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// So far found in every known release that uses OpenMG ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new PathMatch("00AUDTOC.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("01AUDSTR.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("05SRPCDS.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGSVC.DAT", useEndsWith: true), "OpenMG"),
new(new FilePathMatch("00AUDTOC.DAT"), "OpenMG"),
new(new FilePathMatch("01AUDSTR.DAT"), "OpenMG"),
new(new FilePathMatch("05SRPCDS.DAT"), "OpenMG"),
new(new FilePathMatch("OMGSVC.DAT"), "OpenMG"),
// Always found together on OpenMG releases ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new PathMatch("SDKHM.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("SDKHM.EXE", useEndsWith: true), "OpenMG"),
new(new FilePathMatch("SDKHM.DLL"), "OpenMG"),
new(new FilePathMatch("SDKHM.EXE"), "OpenMG"),
// Found together on one specific release ("Touch" by Amerie).
// TODO: Verify if these are OR or AND
new PathMatchSet(new PathMatch("OMGDBP.OCX", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGDWRAP.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGLGD.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGUTILS.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("SALWRAP.DLL", useEndsWith: true), "OpenMG"),
new(new FilePathMatch("OMGDBP.OCX"), "OpenMG"),
new(new FilePathMatch("OMGDWRAP.DLL"), "OpenMG"),
new(new FilePathMatch("OMGLGD.DLL"), "OpenMG"),
new(new FilePathMatch("OMGUTILS.DLL"), "OpenMG"),
new(new FilePathMatch("SALWRAP.DLL"), "OpenMG"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -29,11 +31,15 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
new PathMatchSet(new PathMatch("OriginSetup.exe", useEndsWith: true), "Origin"),
new(new FilePathMatch("OriginSetup.exe"), "Origin"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -44,7 +50,7 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("OriginSetup.exe", useEndsWith: true), "Origin"),
new(new FilePathMatch("OriginSetup.exe"), "Origin"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -16,7 +16,7 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// SOFTWARE TERMINATED\nCONSOLE MAY HAVE BEEN MODIFIED\n CALL 1-888-780-7690
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4F, 0x46,
0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0x54, 0x45,
@@ -32,7 +32,7 @@ namespace BinaryObjectScanner.Protection
}, "PlayStation Anti-modchip (English)"),
// 強制終了しました。\n本体が改造されている\nおそれがあります。
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x5F, 0x37, 0x52, 0x36, 0x7D, 0x42, 0x4E, 0x86,
0x30, 0x57, 0x30, 0x7E, 0x30, 0x57, 0x30, 0x5F,

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -40,17 +42,21 @@ namespace BinaryObjectScanner.Protection
}
/// <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 https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe.
// The files "Data8.bml" and "Data16.bml" are also present in the installation directory, but it is currently unknown if they are specific to this DRM or not.
new PathMatchSet(new PathMatch("PlayJ.exe", useEndsWith: true), "PlayJ Music Player"),
new PathMatchSet(new PathMatch("PLJFilter.ax", useEndsWith: true), "PlayJ Windows Media Player Plug-in"),
new(new FilePathMatch("PlayJ.exe"), "PlayJ Music Player"),
new(new FilePathMatch("PLJFilter.ax"), "PlayJ Windows Media Player Plug-in"),
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
new PathMatchSet(new PathMatch("PJSTREAM.DLL", useEndsWith: true), "PlayJ Music Player Component"),
new(new FilePathMatch("PJSTREAM.DLL"), "PlayJ Music Player Component"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -63,11 +69,11 @@ namespace BinaryObjectScanner.Protection
{
// Found in https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe.
// The files "Data8.bml" and "Data16.bml" are also present in the installation directory, but it is currently unknown if they are specific to this DRM or not.
new PathMatchSet(new PathMatch("PlayJ.exe", useEndsWith: true), "PlayJ Music Player"),
new PathMatchSet(new PathMatch("PLJFilter.ax", useEndsWith: true), "PlayJ Windows Media Player Plug-in"),
new(new FilePathMatch("PlayJ.exe"), "PlayJ Music Player"),
new(new FilePathMatch("PLJFilter.ax"), "PlayJ Windows Media Player Plug-in"),
// Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]).
new PathMatchSet(new PathMatch("PJSTREAM.DLL", useEndsWith: true), "PlayJ Music Player Component"),
new(new FilePathMatch("PJSTREAM.DLL"), "PlayJ Music Player Component"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -10,9 +12,17 @@ namespace BinaryObjectScanner.Protection
public class ProtectDVDVideo : IPathCheck
{
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
#if NET20 || NET35
var protections = new Queue<string>();
#else
var protections = new ConcurrentQueue<string>();
#endif
if (files == null)
return protections;
@@ -21,7 +31,7 @@ namespace BinaryObjectScanner.Protection
string[] ifofiles = files.Where(s => s.EndsWith(".ifo")).ToArray();
for (int i = 0; i < ifofiles.Length; i++)
{
FileInfo ifofile = new FileInfo(ifofiles[i]);
var ifofile = new FileInfo(ifofiles[i]);
if (ifofile.Length == 0)
{
protections.Enqueue("Protect DVD-Video (Unconfirmed - Please report to us on Github)");

View File

@@ -28,11 +28,11 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// ACE-PCD
new ContentMatchSet(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDISC"),
new(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDISC"),
};
var match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -43,11 +43,11 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// DCP-BOV + (char)0x00 + (char)0x00
new ContentMatchSet(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
new(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
};
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -73,14 +73,14 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// HúMETINF
new ContentMatchSet(new byte?[] { 0x48, 0xFA, 0x4D, 0x45, 0x54, 0x49, 0x4E, 0x46 }, GetVersion76till10, "ProtectDISC"),
new(new byte?[] { 0x48, 0xFA, 0x4D, 0x45, 0x54, 0x49, 0x4E, 0x46 }, GetVersion76till10, "ProtectDISC"),
// DCP-BOV + (char)0x00 + (char)0x00
new ContentMatchSet(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
new(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
};
var match = MatchUtil.GetFirstMatch(file, lastSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -136,7 +136,7 @@ namespace BinaryObjectScanner.Protection
int index = positions[0] - 12;
// Version 6-7 with Build Number in plain text
#if NET40
#if NET20 || NET35 || NET40
byte[] temp = new byte[4];
Array.Copy(fileContent, index, temp, 0, 4);
if (temp.SequenceEqual(new byte[] { 0x0A, 0x0D, 0x0A, 0x0D }))
@@ -147,7 +147,7 @@ namespace BinaryObjectScanner.Protection
index = positions[0] - 12 - 6;
// Version 7
#if NET40
#if NET20 || NET35 || NET40
temp = new byte[6];
Array.Copy(fileContent, index, temp, 0, 6);
if (new string(temp.Select(b => (char)b).ToArray()) == "Henrik")
@@ -176,7 +176,7 @@ namespace BinaryObjectScanner.Protection
index -= 5;
}
#if NET40
#if NET20 || NET35 || NET40
temp = new byte[6];
Array.Copy(fileContent, index, temp, 0, 6);
char[] arrBuild = temp.Select(b => (char)b).ToArray();

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -97,33 +99,37 @@ namespace BinaryObjectScanner.Protection
}
/// <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 BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("SENTINEL.VXD", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTSTRT.EXE", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.DLL", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.EXE", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.HLP", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTSTRT.EXE"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.DLL"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.EXE"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.HLP"), "Rainbow Sentinel"),
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and in IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("SNTI386.DLL", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("SNTI386.DLL"), "Rainbow Sentinel"),
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and in IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("RNBOVTMP.DLL", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTINEL.HLP", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTTEMP.SYS", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RNBOVTMP.DLL"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTINEL.HLP"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTTEMP.SYS"), "Rainbow Sentinel"),
// Found in BA entries "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and "Autodesk AutoCAD r14 (1997)", and IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("RAINB95.Z", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("RAINBNT.Z", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RAINB95.Z"), "Rainbow Sentinel"),
new(new FilePathMatch("RAINBNT.Z"), "Rainbow Sentinel"),
// Found in "wd126.zip/WDSHARE.EXE" in IA item "ASMEsMechanicalEngineeringToolkit1997December" and "WDSHARE.ZIP/WDSHARE.EXE/SX32W.DL_" in IA item "aplicaciones-windows".
new PathMatchSet(new PathMatch("RainbowSentinel.386", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SX32W.DL_", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SX32W.DLL", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RainbowSentinel.386"), "Rainbow Sentinel"),
new(new FilePathMatch("SX32W.DL_"), "Rainbow Sentinel"),
new(new FilePathMatch("SX32W.DLL"), "Rainbow Sentinel"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -135,28 +141,28 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("SENTINEL.VXD", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTSTRT.EXE", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.DLL", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.EXE", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTW95.HLP", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("SENTINEL.VXD"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTSTRT.EXE"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.DLL"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.EXE"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTW95.HLP"), "Rainbow Sentinel"),
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and in IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("SNTI386.DLL", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("SNTI386.DLL"), "Rainbow Sentinel"),
// Found in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and in IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("RNBOVTMP.DLL", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTINEL.HLP", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SENTTEMP.SYS", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RNBOVTMP.DLL"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTINEL.HLP"), "Rainbow Sentinel"),
new(new FilePathMatch("SENTTEMP.SYS"), "Rainbow Sentinel"),
// Found in BA entries "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]" and "Autodesk AutoCAD r14 (1997)", and IA item "auto-cad-r14-cdrom".
new PathMatchSet(new PathMatch("RAINB95.Z", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("RAINBNT.Z", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RAINB95.Z"), "Rainbow Sentinel"),
new(new FilePathMatch("RAINBNT.Z"), "Rainbow Sentinel"),
// Found in "wd126.zip/WDSHARE.EXE" in IA item "ASMEsMechanicalEngineeringToolkit1997December" and "WDSHARE.ZIP/WDSHARE.EXE/SX32W.DL_" in IA item "aplicaciones-windows".
new PathMatchSet(new PathMatch("RainbowSentinel.386", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SX32W.DL_", useEndsWith: true), "Rainbow Sentinel"),
new PathMatchSet(new PathMatch("SX32W.DLL", useEndsWith: true), "Rainbow Sentinel"),
new(new FilePathMatch("RainbowSentinel.386"), "Rainbow Sentinel"),
new(new FilePathMatch("SX32W.DL_"), "Rainbow Sentinel"),
new(new FilePathMatch("SX32W.DLL"), "Rainbow Sentinel"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -18,7 +20,7 @@ namespace BinaryObjectScanner.Protection
var contentMatchSets = new List<ContentMatchSet>
{
// (char)0x00 + Allocator + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00
new ContentMatchSet(new byte?[]
new(new byte?[]
{
0x00, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x61, 0x74,
0x6F, 0x72, 0x00, 0x00, 0x00, 0x00
@@ -34,12 +36,16 @@ namespace BinaryObjectScanner.Protection
// TODO: Confirm if these checks are only for ProRing or if they are also for older Ring PROTECH
/// <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 Redump entry 94161
new PathMatchSet(new PathMatch("protect.pro", useEndsWith: true), "Ring PROTECH / ProRing [Check disc for physical ring]"),
new(new PathMatch("protect.pro", useEndsWith: true), "Ring PROTECH / ProRing [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -51,7 +57,7 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in Redump entry 94161
new PathMatchSet(new PathMatch("protect.pro", useEndsWith: true), "Ring PROTECH / ProRing [Check disc for physical ring]"),
new(new PathMatch("protect.pro", useEndsWith: true), "Ring PROTECH / ProRing [Check disc for physical ring]"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -51,17 +53,17 @@ namespace BinaryObjectScanner.Protection
if (pex.EntryPointData.StartsWith(new byte?[]
{
0x60, 0xEB, 0x03, 0xC7, 0x84, 0xE8, 0xEB, 0x03,
0xC7, 0x84, 0x9A, 0xE8, 0x00, 0x00, 0x00, 0x00,
0xC7, 0x84, 0x9A, 0xE8, 0x00, 0x00, 0x00, 0x00,
0x5D, 0x81, 0xED, 0x10, 0x00, 0x00, 0x00, 0xEB,
0x03, 0xC7, 0x84, 0xE9, 0x64, 0xA0, 0x23, 0x00,
0x00, 0x00, 0xEB
}))
return "SVKP v1.051";
// Found in the SVKP 1.11 demo.
if (pex.EntryPointData.StartsWith(new byte?[]
{
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
0xED, 0x06, null, null, null, 0x64, 0xA0, 0x23
}))
return "SVKP v1.11";
@@ -69,8 +71,8 @@ namespace BinaryObjectScanner.Protection
// Found in the SVKP 1.32 demo and Redump entry 84122.
if (pex.EntryPointData.StartsWith(new byte?[]
{
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x06, 0x00, 0x00, 0x00, 0xEB, 0x05, 0xB8,
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
0xED, 0x06, 0x00, 0x00, 0x00, 0xEB, 0x05, 0xB8,
null, null, null, null, 0x64, 0xA0, 0x23
}))
return "SVKP v1.3+";
@@ -90,16 +92,20 @@ namespace BinaryObjectScanner.Protection
}
/// <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 the SVKP 1.05-1.32 demos.
new PathMatchSet(new FilePathMatch("svkp.exe"), "SVKP"),
new PathMatchSet(new FilePathMatch("svkp.key"), "SVKP"),
new(new FilePathMatch("svkp.exe"), "SVKP"),
new(new FilePathMatch("svkp.key"), "SVKP"),
// Found in the SVKP 1.32 demo.
new PathMatchSet(new FilePathMatch("svkpnd.dll"), "SVKP"),
new(new FilePathMatch("svkpnd.dll"), "SVKP"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -111,11 +117,11 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Found in the SVKP 1.05-1.32 demos.
new PathMatchSet(new FilePathMatch("svkp.exe"), "SVKP"),
new PathMatchSet(new FilePathMatch("svkp.key"), "SVKP"),
new(new FilePathMatch("svkp.exe"), "SVKP"),
new(new FilePathMatch("svkp.key"), "SVKP"),
// Found in the SVKP 1.32 demo.
new PathMatchSet(new FilePathMatch("svkpnd.dll"), "SVKP"),
new(new FilePathMatch("svkpnd.dll"), "SVKP"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -20,16 +22,20 @@ namespace BinaryObjectScanner.Protection
public class SafeLock : IPathCheck
{
/// <inheritdoc/>
#if NET20 || NET35
public Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#else
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files)
#endif
{
// Technically all need to exist but some might be renamed
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new FilePathMatch("SafeLock.DAT"), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.001", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.002", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.128", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.256", useEndsWith: true), "SafeLock"),
new(new FilePathMatch("SafeLock.DAT"), "SafeLock"),
new(new FilePathMatch("SafeLock.001"), "SafeLock"),
new(new FilePathMatch("SafeLock.002"), "SafeLock"),
new(new FilePathMatch("SafeLock.128"), "SafeLock"),
new(new FilePathMatch("SafeLock.256"), "SafeLock"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -40,11 +46,11 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new FilePathMatch("SafeLock.DAT"), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.001", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.002", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.128", useEndsWith: true), "SafeLock"),
new PathMatchSet(new PathMatch("SafeLock.256", useEndsWith: true), "SafeLock"),
new(new FilePathMatch("SafeLock.DAT"), "SafeLock"),
new(new FilePathMatch("SafeLock.001"), "SafeLock"),
new(new FilePathMatch("SafeLock.002"), "SafeLock"),
new(new FilePathMatch("SafeLock.128"), "SafeLock"),
new(new FilePathMatch("SafeLock.256"), "SafeLock"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -65,7 +67,7 @@ namespace BinaryObjectScanner.Protection
if (nthSection == null)
continue;
#if NET40 || NET452
#if NET20 || NET35 || NET40 || NET452
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? []).TrimEnd('\0');
#else
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? Array.Empty<byte>()).TrimEnd('\0');
@@ -79,11 +81,11 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<ContentMatchSet>
{
// (char)0xCA + (char)0xDD + (char)0xDD + (char)0xAC + (char)0x03
new ContentMatchSet(new byte?[] { 0xCA, 0xDD, 0xDD, 0xAC, 0x03 }, GetV5Version, "SecuROM"),
new(new byte?[] { 0xCA, 0xDD, 0xDD, 0xAC, 0x03 }, GetV5Version, "SecuROM"),
};
var match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -109,28 +111,32 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// TODO: Verify if these are OR or AND
new PathMatchSet(new PathMatch("CMS16.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS_95.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS_NT.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS32_95.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS32_NT.DLL", useEndsWith: true), "SecuROM"),
new(new FilePathMatch("CMS16.DLL"), "SecuROM"),
new(new FilePathMatch("CMS_95.DLL"), "SecuROM"),
new(new FilePathMatch("CMS_NT.DLL"), "SecuROM"),
new(new FilePathMatch("CMS32_95.DLL"), "SecuROM"),
new(new FilePathMatch("CMS32_NT.DLL"), "SecuROM"),
// TODO: Verify if these are OR or AND
new PathMatchSet(new PathMatch("SINTF32.DLL", useEndsWith: true), "SecuROM New"),
new PathMatchSet(new PathMatch("SINTF16.DLL", useEndsWith: true), "SecuROM New"),
new PathMatchSet(new PathMatch("SINTFNT.DLL", useEndsWith: true), "SecuROM New"),
new(new FilePathMatch("SINTF32.DLL"), "SecuROM New"),
new(new FilePathMatch("SINTF16.DLL"), "SecuROM New"),
new(new FilePathMatch("SINTFNT.DLL"), "SecuROM New"),
// TODO: Find more samples of this for different versions
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("securom_v7_01.bak", useEndsWith: true),
new PathMatch("securom_v7_01.dat", useEndsWith: true),
new PathMatch("securom_v7_01.tmp", useEndsWith: true),
new FilePathMatch("securom_v7_01.bak"),
new FilePathMatch("securom_v7_01.dat"),
new FilePathMatch("securom_v7_01.tmp"),
}, "SecuROM 7.01"),
};
@@ -142,19 +148,19 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("CMS16.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS_95.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS_NT.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS32_95.DLL", useEndsWith: true), "SecuROM"),
new PathMatchSet(new PathMatch("CMS32_NT.DLL", useEndsWith: true), "SecuROM"),
new(new FilePathMatch("CMS16.DLL"), "SecuROM"),
new(new FilePathMatch("CMS_95.DLL"), "SecuROM"),
new(new FilePathMatch("CMS_NT.DLL"), "SecuROM"),
new(new FilePathMatch("CMS32_95.DLL"), "SecuROM"),
new(new FilePathMatch("CMS32_NT.DLL"), "SecuROM"),
new PathMatchSet(new PathMatch("SINTF32.DLL", useEndsWith: true), "SecuROM New"),
new PathMatchSet(new PathMatch("SINTF16.DLL", useEndsWith: true), "SecuROM New"),
new PathMatchSet(new PathMatch("SINTFNT.DLL", useEndsWith: true), "SecuROM New"),
new(new FilePathMatch("SINTF32.DLL"), "SecuROM New"),
new(new FilePathMatch("SINTF16.DLL"), "SecuROM New"),
new(new FilePathMatch("SINTFNT.DLL"), "SecuROM New"),
new PathMatchSet(new PathMatch("securom_v7_01.bak", useEndsWith: true), "SecuROM 7.01"),
new PathMatchSet(new PathMatch("securom_v7_01.dat", useEndsWith: true), "SecuROM 7.01"),
new PathMatchSet(new PathMatch("securom_v7_01.tmp", useEndsWith: true), "SecuROM 7.01"),
new(new FilePathMatch("securom_v7_01.bak"), "SecuROM 7.01"),
new(new FilePathMatch("securom_v7_01.dat"), "SecuROM 7.01"),
new(new FilePathMatch("securom_v7_01.tmp"), "SecuROM 7.01"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -256,15 +262,15 @@ namespace BinaryObjectScanner.Protection
return "8";
// Search .data for the version indicator
var matcher = new ContentMatch(new byte?[]
{
var matcher = new ContentMatch(
[
0x29, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
0x82, 0xD8, 0x0C, 0xAC
});
]);
(bool success, int position) = matcher.Match(dataSectionRaw);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -29,11 +31,15 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new FilePathMatch("00001.TMP"),
new FilePathMatch("00002.TMP")
@@ -48,8 +54,8 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new FilePathMatch("00001.TMP"), "SmartE"),
new PathMatchSet(new FilePathMatch("00002.TMP"), "SmartE"),
new(new FilePathMatch("00001.TMP"), "SmartE"),
new(new FilePathMatch("00002.TMP"), "SmartE"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -82,14 +84,18 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch(needle: "SOFTLOCKC.dat", useEndsWith: true),
new PathMatch("SOFTLOCKI.dat", useEndsWith: true),
new FilePathMatch("SOFTLOCKC.dat"),
new FilePathMatch("SOFTLOCKI.dat"),
}, "SoftLock"),
};
@@ -101,8 +107,8 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("SOFTLOCKC.dat", useEndsWith: true), "SoftLock"),
new PathMatchSet(new PathMatch("SOFTLOCKI.dat", useEndsWith: true), "SoftLock"),
new(new FilePathMatch("SOFTLOCKC.dat"), "SoftLock"),
new(new FilePathMatch("SOFTLOCKI.dat"), "SoftLock"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -59,14 +61,14 @@ namespace BinaryObjectScanner.ProtectionType
var matchers = new List<ContentMatchSet>
{
// (char)0xAD + (char)0xDE + (char)0xFE + (char)0xCA
new ContentMatchSet(new byte?[] { 0xAD, 0xDE, 0xFE, 0xCA }, GetVersionPlusTages, "SolidShield"),
new(new byte?[] { 0xAD, 0xDE, 0xFE, 0xCA }, GetVersionPlusTages, "SolidShield"),
// (char)0xEF + (char)0xBE + (char)0xAD + (char)0xDE
new ContentMatchSet(new byte?[] { 0xEF, 0xBE, 0xAD, 0xDE }, GetExeWrapperVersion, "SolidShield EXE Wrapper"),
new(new byte?[] { 0xEF, 0xBE, 0xAD, 0xDE }, GetExeWrapperVersion, "SolidShield EXE Wrapper"),
};
var match = MatchUtil.GetFirstMatch(file, initData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
}
@@ -109,19 +111,23 @@ namespace BinaryObjectScanner.ProtectionType
}
/// <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 Redump entry 68166.
new PathMatchSet(new FilePathMatch("tdvm.dll"), "SolidShield"),
new PathMatchSet(new FilePathMatch("tdvm.vds"), "SolidShield"),
new PathMatchSet(new PathMatch("vfs20.dll", useEndsWith: true), "SolidShield"),
new(new FilePathMatch("tdvm.dll"), "SolidShield"),
new(new FilePathMatch("tdvm.vds"), "SolidShield"),
new(new PathMatch("vfs20.dll", useEndsWith: true), "SolidShield"),
new PathMatchSet(new FilePathMatch("dvm.dll"), "SolidShield"),
new PathMatchSet(new FilePathMatch("hc.dll"), "SolidShield"),
new PathMatchSet(new PathMatch("solidshield-cd.dll", useEndsWith: true), "SolidShield"),
new PathMatchSet(new PathMatch("c11prot.dll", useEndsWith: true), "SolidShield"),
new(new FilePathMatch("dvm.dll"), "SolidShield"),
new(new FilePathMatch("hc.dll"), "SolidShield"),
new(new PathMatch("solidshield-cd.dll", useEndsWith: true), "SolidShield"),
new(new PathMatch("c11prot.dll", useEndsWith: true), "SolidShield"),
};
// TODO: Verify if these are OR or AND
@@ -133,10 +139,10 @@ namespace BinaryObjectScanner.ProtectionType
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new FilePathMatch("dvm.dll"), "SolidShield"),
new PathMatchSet(new FilePathMatch("hc.dll"), "SolidShield"),
new PathMatchSet(new PathMatch("solidshield-cd.dll", useEndsWith: true), "SolidShield"),
new PathMatchSet(new PathMatch("c11prot.dll", useEndsWith: true), "SolidShield"),
new(new FilePathMatch("dvm.dll"), "SolidShield"),
new(new FilePathMatch("hc.dll"), "SolidShield"),
new(new PathMatch("solidshield-cd.dll", useEndsWith: true), "SolidShield"),
new(new PathMatch("c11prot.dll", useEndsWith: true), "SolidShield"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -150,7 +156,7 @@ namespace BinaryObjectScanner.ProtectionType
int position = positions[0];
#if NET40
#if NET20 || NET35 || NET40
byte[] id1 = new byte[3];
Array.Copy(fileContent, position + 5, id1, 0, 3);
byte[] id2 = new byte[4];
@@ -180,7 +186,7 @@ namespace BinaryObjectScanner.ProtectionType
return null;
int position = positions[0];
#if NET40
#if NET20 || NET35 || NET40
byte[] id1 = new byte[3];
Array.Copy(fileContent, position + 4, id1, 0, 3);
byte[] id2 = new byte[4];
@@ -200,13 +206,13 @@ namespace BinaryObjectScanner.ProtectionType
&& id2.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 }))
{
// "T" + (char)0x00 + "a" + (char)0x00 + "g" + (char)0x00 + "e" + (char)0x00 + "s" + (char)0x00 + "S" + (char)0x00 + "e" + (char)0x00 + "t" + (char)0x00 + "u" + (char)0x00 + "p" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + "0" + (char)0x00 + (char)0x8 + (char)0x00 + (char)0x1 + (char)0x0 + "F" + (char)0x00 + "i" + (char)0x00 + "l" + (char)0x00 + "e" + (char)0x00 + "V" + (char)0x00 + "e" + (char)0x00 + "r" + (char)0x00 + "s" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00
byte?[] check2 = new byte?[]
{
byte?[] check2 =
[
0x54, 0x61, 0x67, 0x65, 0x73, 0x53, 0x65, 0x74,
0x75, 0x70, 0x30, 0x08, 0x01, 0x00, 0x46, 0x69,
0x6C, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F,
0x6E, 0x00, 0x00, 0x00, 0x00
};
];
if (fileContent.FirstPosition(check2, out int position2))
{
position2--; // TODO: Verify this subtract
@@ -224,7 +230,7 @@ namespace BinaryObjectScanner.ProtectionType
private static string GetInternalVersion(PortableExecutable pex)
{
var companyName = pex.CompanyName?.ToLowerInvariant();
if (!string.IsNullOrWhiteSpace(companyName) && (companyName!.Contains("solidshield") || companyName.Contains("tages")))
if (!string.IsNullOrEmpty(companyName) && (companyName!.Contains("solidshield") || companyName.Contains("tages")))
return pex.GetInternalVersion() ?? string.Empty;
return string.Empty;

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.Linq;
using BinaryObjectScanner.Interfaces;
@@ -100,35 +102,39 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// This file combination is found in Redump entry 21136.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("protect.x86", useEndsWith: true),
new PathMatch("protect.x64", useEndsWith: true),
new PathMatch("protect.dll", useEndsWith: true),
new PathMatch("protect.exe", useEndsWith: true),
new PathMatch("protect.msg", useEndsWith: true),
new FilePathMatch("protect.x86"),
new FilePathMatch("protect.x64"),
new FilePathMatch("protect.dll"),
new FilePathMatch("protect.exe"),
new FilePathMatch("protect.msg"),
}, "StarForce"),
// This file combination is found in multiple games, such as Redump entries 81756, 91336, and 93657.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("protect.x86", useEndsWith: true),
new PathMatch("protect.x64", useEndsWith: true),
new PathMatch("protect.dll", useEndsWith: true),
new PathMatch("protect.exe", useEndsWith: true),
new FilePathMatch("protect.x86"),
new FilePathMatch("protect.x64"),
new FilePathMatch("protect.dll"),
new FilePathMatch("protect.exe"),
}, "StarForce"),
// This file combination is found in Redump entry 96137.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("protect.x86", useEndsWith: true),
new PathMatch("protect.dll", useEndsWith: true),
new PathMatch("protect.exe", useEndsWith: true),
new FilePathMatch("protect.x86"),
new FilePathMatch("protect.dll"),
new FilePathMatch("protect.exe"),
}, "StarForce"),
};

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -41,46 +43,50 @@ namespace BinaryObjectScanner.Protection
}
/// <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>
{
// These checks are grouped together due to the names being generic on their own (Redump entry 91450).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// TODO: Identify based on "Steam(TM)" being present in "Description" but not in "File Description".
new PathMatch("steam.exe", useEndsWith: true),
new FilePathMatch("steam.exe"),
new PathMatch("steam.ini", useEndsWith: true),
new FilePathMatch("steam.ini"),
// TODO: Identify file using MSI property parsing.
new PathMatch("steam.msi", useEndsWith: true),
new FilePathMatch("steam.msi"),
}, "Steam"),
new PathMatchSet(new PathMatch("steam_api.dll", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steam_api64.dll", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steam_install_agreement.rtf", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.bom", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.info", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.ini", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.pax.gz", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.pkg", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.sizes", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Czech.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_English.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_French.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_German.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Italian.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Polish.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Russian.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Spanish.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamRetailInstaller", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamRetailInstaller.dmg", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamService.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamSetup.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steamxboxutil64.exe", useEndsWith: true), "Steam"),
new(new FilePathMatch("steam_api.dll"), "Steam"),
new(new FilePathMatch("steam_api64.dll"), "Steam"),
new(new FilePathMatch("steam_install_agreement.rtf"), "Steam"),
new(new FilePathMatch("SteamInstall.bom"), "Steam"),
new(new FilePathMatch("SteamInstall.exe"), "Steam"),
new(new FilePathMatch("SteamInstall.info"), "Steam"),
new(new FilePathMatch("SteamInstall.ini"), "Steam"),
new(new FilePathMatch("SteamInstall.msi"), "Steam"),
new(new FilePathMatch("SteamInstall.pax.gz"), "Steam"),
new(new FilePathMatch("SteamInstall.pkg"), "Steam"),
new(new FilePathMatch("SteamInstall.sizes"), "Steam"),
new(new FilePathMatch("SteamInstall_Czech.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_English.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_French.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_German.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Italian.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Polish.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Russian.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Spanish.msi"), "Steam"),
new(new FilePathMatch("SteamRetailInstaller"), "Steam"),
new(new FilePathMatch("SteamRetailInstaller.dmg"), "Steam"),
new(new FilePathMatch("SteamService.exe"), "Steam"),
new(new FilePathMatch("SteamSetup.exe"), "Steam"),
new(new FilePathMatch("steamxboxutil64.exe"), "Steam"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -91,30 +97,30 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("steam_api.dll", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steam_api64.dll", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steam_install_agreement.rtf", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.bom", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.info", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.ini", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.pax.gz", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.pkg", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall.sizes", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Czech.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_English.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_French.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_German.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Italian.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Polish.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Russian.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamInstall_Spanish.msi", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamRetailInstaller", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamRetailInstaller.dmg", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamService.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("SteamSetup.exe", useEndsWith: true), "Steam"),
new PathMatchSet(new PathMatch("steamxboxutil64.exe", useEndsWith: true), "Steam"),
new(new FilePathMatch("steam_api.dll"), "Steam"),
new(new FilePathMatch("steam_api64.dll"), "Steam"),
new(new FilePathMatch("steam_install_agreement.rtf"), "Steam"),
new(new FilePathMatch("SteamInstall.bom"), "Steam"),
new(new FilePathMatch("SteamInstall.exe"), "Steam"),
new(new FilePathMatch("SteamInstall.info"), "Steam"),
new(new FilePathMatch("SteamInstall.ini"), "Steam"),
new(new FilePathMatch("SteamInstall.msi"), "Steam"),
new(new FilePathMatch("SteamInstall.pax.gz"), "Steam"),
new(new FilePathMatch("SteamInstall.pkg"), "Steam"),
new(new FilePathMatch("SteamInstall.sizes"), "Steam"),
new(new FilePathMatch("SteamInstall_Czech.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_English.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_French.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_German.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Italian.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Polish.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Russian.msi"), "Steam"),
new(new FilePathMatch("SteamInstall_Spanish.msi"), "Steam"),
new(new FilePathMatch("SteamRetailInstaller"), "Steam"),
new(new FilePathMatch("SteamRetailInstaller.dmg"), "Steam"),
new(new FilePathMatch("SteamService.exe"), "Steam"),
new(new FilePathMatch("SteamSetup.exe"), "Steam"),
new(new FilePathMatch("steamxboxutil64.exe"), "Steam"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using BinaryObjectScanner.Interfaces;
using SabreTools.Matching;
@@ -53,15 +55,19 @@ namespace BinaryObjectScanner.Protection
public class TZCopyProtection : IPathCheck
{
/// <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>
{
// Unconfirmed, not sure where this is supposed to be found.
new PathMatchSet(new PathMatch("_742893.016", useEndsWith: true), "TZCopyProtection (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("_742893.016"), "TZCopyProtection (Unconfirmed - Please report to us on Github)"),
// "Ghost" file used by newer versions of TZCopyProtection.
new PathMatchSet(new PathMatch("ZakMcCrack.Ghost", useEndsWith: true), "TZCopyProtection V1.11+"),
new(new FilePathMatch("ZakMcCrack.Ghost"), "TZCopyProtection V1.11+"),
// Newer versions of TZCopyProtection also create files with a TZC extension, though their purpose is currently unknown.
};
@@ -75,10 +81,10 @@ namespace BinaryObjectScanner.Protection
var matchers = new List<PathMatchSet>
{
// Unconfirmed, not sure where this is supposed to be found.
new PathMatchSet(new PathMatch("_742893.016", useEndsWith: true), "TZCopyProtection (Unconfirmed - Please report to us on Github)"),
new(new FilePathMatch("_742893.016"), "TZCopyProtection (Unconfirmed - Please report to us on Github)"),
// "Ghost" file used by newer versions of TZCopyProtection.
new PathMatchSet(new PathMatch("ZakMcCrack.Ghost", useEndsWith: true), "TZCopyProtection V1.11+"),
new(new FilePathMatch("ZakMcCrack.Ghost"), "TZCopyProtection V1.11+"),
// Newer versions of TZCopyProtection also create files with a TZC extension, though their purpose is currently unknown.
};

View File

@@ -1,5 +1,7 @@
using System;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
@@ -50,11 +52,11 @@ namespace BinaryObjectScanner.ProtectionType
var matchers = new List<ContentMatchSet>
{
// (char)0xE8 + u + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8 + ?? + ?? + (char)0xFF + (char)0xFF + "h"
new ContentMatchSet(new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8, null, null, 0xFF, 0xFF, 0x68 }, GetVersion, "TAGES"),
new(new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8, null, null, 0xFF, 0xFF, 0x68 }, GetVersion, "TAGES"),
};
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
if (!string.IsNullOrEmpty(match))
return match;
}
@@ -62,92 +64,96 @@ namespace BinaryObjectScanner.ProtectionType
}
/// <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>
{
// So far, only known to exist in early versions of "Moto Racer 3" (Redump entries 31578 and 34669).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// d37f70489207014d7d0fbaa43b081a93e8030498
new PathMatch(Path.Combine("Sys", "Devx.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("Sys", "Devx.sys").Replace("\\", "/"), useEndsWith: true),
// a0acbc2f8e321e4f30c913c095e28af444058249
new PathMatch(Path.Combine("Sys", "VtPr.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("Sys", "VtPr.sys").Replace("\\", "/"), useEndsWith: true),
// SHA-1 is variable, file size is 81,920 bytes
new PathMatch("Wave.aif", useEndsWith: true),
new FilePathMatch("Wave.aif"),
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch("Wave.alf", useEndsWith: true),
new FilePathMatch("Wave.alf"),
// 0351d0f3d4166362a1a9d838c9390a3d92945a44
new PathMatch("Wave.apt", useEndsWith: true),
new FilePathMatch("Wave.apt"),
// SHA-1 is variable, file size is 61,440 bytes
new PathMatch("Wave.axt", useEndsWith: true),
new FilePathMatch("Wave.axt"),
}, "TAGES"),
// Currently only found in "Robocop" (Redump entry 35932).
// Found in a directory named "System", with an executable named "Setup.exe".
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch(Path.Combine("9x", "Tamlx.alf").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("9x", "Tamlx.alf").Replace("\\", "/"), useEndsWith: true),
// 933c004d3043863f019f5ffaf63402a30e65026c
new PathMatch(Path.Combine("9x", "Tamlx.apt").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("9x", "Tamlx.apt").Replace("\\", "/"), useEndsWith: true),
// d45745fa6b0d23fe0ee12e330ab85d5bf4e0e776
new PathMatch(Path.Combine("NT", "enodpl.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("NT", "enodpl.sys").Replace("\\", "/"), useEndsWith: true),
// f111eba05ca6e9061c557547420847d7fdee657d
new PathMatch(Path.Combine("NT", "litdpl.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("NT", "litdpl.sys").Replace("\\", "/"), useEndsWith: true),
}, "TAGES"),
// Currently only known to exist in "XIII" and "Beyond Good & Evil" (Redump entries 8774-8776, 45940-45941, 18690-18693, and presumably 21320, 21321, 21323, and 36124).
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
new PathMatch("enodpl.sys", useEndsWith: true),
new PathMatch("ENODPL.VXD", useEndsWith: true),
new PathMatch("tandpl.sys", useEndsWith: true),
new PathMatch("TANDPL.VXD", useEndsWith: true),
new FilePathMatch("enodpl.sys"),
new FilePathMatch("ENODPL.VXD"),
new FilePathMatch("tandpl.sys"),
new FilePathMatch("TANDPL.VXD"),
}, "TAGES"),
// The directory of these files has been seen to be named two different things, with two different accompanying executables in the root of the directory.
// In the example where the directory is named "Drivers", the executable is named "Silent.exe" (Redump entry 51763).
// In the example where the directory is named "ELBdrivers", the executable is name "ELBDrivers.exe" (Redump entry 91090).
// The name and file size of the included executable vary, but there should always be one here.
new PathMatchSet(new List<PathMatch>
new(new List<PathMatch>
{
// 40826e95f3ad8031b6debe15aca052c701288e04
new PathMatch(Path.Combine("9x", "hwpsgt.vxd").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("9x", "hwpsgt.vxd").Replace("\\", "/"), useEndsWith: true),
// f82339d797be6da92f5d9dadeae9025385159057
new PathMatch(Path.Combine("9x", "lemsgt.vxd").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("9x", "lemsgt.vxd").Replace("\\", "/"), useEndsWith: true),
// 43f407ecdc0d87a3713126b757ccaad07ade285f
new PathMatch(Path.Combine("NT", "hwpsgt.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("NT", "hwpsgt.sys").Replace("\\", "/"), useEndsWith: true),
// 548dd6359abbcc8c84ce346d078664eeedc716f7
new PathMatch(Path.Combine("NT", "lemsgt.sys").Replace("\\", "/"), useEndsWith: true),
new(Path.Combine("NT", "lemsgt.sys").Replace("\\", "/"), useEndsWith: true),
}, "TAGES"),
// The following files are supposed to only be found inside the driver setup executables, and are present in at least version 5.2.0.1 (Redump entry 15976).
new PathMatchSet(new PathMatch("ithsgt.sys", useEndsWith: true), "TAGES Driver"),
new PathMatchSet(new PathMatch("lilsgt.sys", useEndsWith: true), "TAGES Driver"),
new(new FilePathMatch("ithsgt.sys"), "TAGES Driver"),
new(new FilePathMatch("lilsgt.sys"), "TAGES Driver"),
// The following files are supposed to only be found inside the driver setup executables in versions 5.5.0.1+.
new PathMatchSet(new PathMatch("atksgt.sys", useEndsWith: true), "TAGES Driver"),
new PathMatchSet(new PathMatch("lirsgt.sys", useEndsWith: true), "TAGES Driver"),
new(new FilePathMatch("atksgt.sys"), "TAGES Driver"),
new(new FilePathMatch("lirsgt.sys"), "TAGES Driver"),
// The following files appear to be container formats for TAGES, but little is currently known about them (Redump entries 85313 and 85315).
new PathMatchSet(new PathMatch("GameModule.elb", useEndsWith: true), "TAGES/SolidShield Game Executable Container"),
new PathMatchSet(new PathMatch("InstallModule.elb", useEndsWith: true), "TAGES/SolidShield Installer Container"),
new(new FilePathMatch("GameModule.elb"), "TAGES/SolidShield Game Executable Container"),
new(new FilePathMatch("InstallModule.elb"), "TAGES/SolidShield Installer Container"),
// Not much is known about this file, but it seems to be related to what PiD reports as "protection level: Tages BASIC" (Redump entry 85313).
// Seems to always be found with other KWN files.
new PathMatchSet(new PathMatch("GAME.KWN", useEndsWith: true), "TAGES (BASIC?)"),
new(new FilePathMatch("GAME.KWN"), "TAGES (BASIC?)"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
@@ -159,52 +165,52 @@ namespace BinaryObjectScanner.ProtectionType
var matchers = new List<PathMatchSet>
{
// So far, only known to exist in early versions of "Moto Racer 3" (Redump entries 31578 and 34669).
new PathMatchSet(new PathMatch("Devx.sys", useEndsWith: true), "TAGES Driver"),
new PathMatchSet(new PathMatch("VtPr.sys", useEndsWith: true), "TAGES Driver"),
new(new FilePathMatch("Devx.sys"), "TAGES Driver"),
new(new FilePathMatch("VtPr.sys"), "TAGES Driver"),
// These are removed because they can potentially overmatch
// new PathMatchSet(new PathMatch("Wave.aif", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.alf", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.apt", useEndsWith: true), "TAGES Driver"),
// new PathMatchSet(new PathMatch("Wave.axt", useEndsWith: true), "TAGES Driver"),
// new(new FilePathMatch("Wave.aif"), "TAGES Driver"),
// new(new FilePathMatch("Wave.alf"), "TAGES Driver"),
// new(new FilePathMatch("Wave.apt"), "TAGES Driver"),
// new(new FilePathMatch("Wave.axt"), "TAGES Driver"),
// Currently only found in "Robocop" (Redump entry 35932).
// Found in a directory named "System", with an executable named "Setup.exe".
new PathMatchSet(new PathMatch("Tamlx.apt", useEndsWith: true), "TAGES 9x Driver"),
new PathMatchSet(new PathMatch("Tamlx.alf", useEndsWith: true), "TAGES 9x Driver"),
new PathMatchSet(new PathMatch("enodpl.sys", useEndsWith: true), "TAGES NT Driver"),
new PathMatchSet(new PathMatch("litdpl.sys", useEndsWith: true), "TAGES NT Driver"),
new(new FilePathMatch("Tamlx.apt"), "TAGES 9x Driver"),
new(new FilePathMatch("Tamlx.alf"), "TAGES 9x Driver"),
new(new FilePathMatch("enodpl.sys"), "TAGES NT Driver"),
new(new FilePathMatch("litdpl.sys"), "TAGES NT Driver"),
// Currently only known to exist in "XIII" and "Beyond Good & Evil" (Redump entries 8774-8776, 45940-45941, 18690-18693, and presumably 21320, 21321, 21323, and 36124).
new PathMatchSet(new PathMatch("enodpl.sys", useEndsWith: true), "TAGES NT Driver"),
new PathMatchSet(new PathMatch("ENODPL.VXD", useEndsWith: true), "TAGES 9x Driver"),
new PathMatchSet(new PathMatch("tandpl.sys", useEndsWith: true), "TAGES NT Driver"),
new PathMatchSet(new PathMatch("TANDPL.VXD", useEndsWith: true), "TAGES 9x Driver"),
new(new FilePathMatch("enodpl.sys"), "TAGES NT Driver"),
new(new FilePathMatch("ENODPL.VXD"), "TAGES 9x Driver"),
new(new FilePathMatch("tandpl.sys"), "TAGES NT Driver"),
new(new FilePathMatch("TANDPL.VXD"), "TAGES 9x Driver"),
// The directory of these files has been seen to be named two different things, with two different accompanying executables in the root of the directory.
// In the example where the directory is named "Drivers", the executable is named "Silent.exe" (Redump entry 51763).
// In the example where the directory is named "ELBdrivers", the executable is name "ELBDrivers.exe" (Redump entry 91090).
// The name and file size of the included executable vary, but there should always be one here.
new PathMatchSet(new PathMatch("hwpsgt.vxd", useEndsWith: true), "TAGES 9x Driver"),
new PathMatchSet(new PathMatch("lemsgt.vxd", useEndsWith: true), "TAGES 9x Driver"),
new PathMatchSet(new PathMatch("hwpsgt.sys", useEndsWith: true), "TAGES NT Driver"),
new PathMatchSet(new PathMatch("lemsgt.sys", useEndsWith: true), "TAGES NT Driver"),
new(new FilePathMatch("hwpsgt.vxd"), "TAGES 9x Driver"),
new(new FilePathMatch("lemsgt.vxd"), "TAGES 9x Driver"),
new(new FilePathMatch("hwpsgt.sys"), "TAGES NT Driver"),
new(new FilePathMatch("lemsgt.sys"), "TAGES NT Driver"),
// The following files are supposed to only be found inside the driver setup executables, and are present in at least version 5.2.0.1 (Redump entry 15976).
new PathMatchSet(new PathMatch("ithsgt.sys", useEndsWith: true), "TAGES Driver"),
new PathMatchSet(new PathMatch("lilsgt.sys", useEndsWith: true), "TAGES Driver"),
new(new FilePathMatch("ithsgt.sys"), "TAGES Driver"),
new(new FilePathMatch("lilsgt.sys"), "TAGES Driver"),
// The following files are supposed to only be found inside the driver setup executables in versions 5.5.0.1+.
new PathMatchSet(new PathMatch("atksgt.sys", useEndsWith: true), "TAGES Driver"),
new PathMatchSet(new PathMatch("lirsgt.sys", useEndsWith: true), "TAGES Driver"),
new(new FilePathMatch("atksgt.sys"), "TAGES Driver"),
new(new FilePathMatch("lirsgt.sys"), "TAGES Driver"),
// The following files appear to be container formats for TAGES, but little is currently known about them (Redump entries 85313 and 85315).
new PathMatchSet(new PathMatch("GameModule.elb", useEndsWith: true), "TAGES/SolidShield Game Executable Container"),
new PathMatchSet(new PathMatch("InstallModule.elb", useEndsWith: true), "TAGES/SolidShield Installer Container"),
new(new FilePathMatch("GameModule.elb"), "TAGES/SolidShield Game Executable Container"),
new(new FilePathMatch("InstallModule.elb"), "TAGES/SolidShield Installer Container"),
// Not much is known about this file, but it seems to be related to what PiD reports as "protection level: Tages BASIC" (Redump entry 85313).
// Seems to always be found with other KWN files.
new PathMatchSet(new PathMatch("GAME.KWN", useEndsWith: true), "TAGES (BASIC?)"),
new(new FilePathMatch("GAME.KWN"), "TAGES (BASIC?)"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
@@ -230,19 +236,14 @@ namespace BinaryObjectScanner.ProtectionType
byte typeByte = fileContent[positions[0] + 6];
byte versionByte = fileContent[positions[0] + 7];
switch (versionByte)
return versionByte switch
{
case 0x1E:
return "5.2";
case 0x1B:
return "5.3-5.4";
case 0x14:
return "5.5.0";
case 0x04:
return "5.5.2";
default:
return string.Empty;
}
0x1E => "5.2",
0x1B => "5.3-5.4",
0x14 => "5.5.0",
0x04 => "5.5.2",
_ => string.Empty,
};
}
}
}

View File

@@ -1,4 +1,6 @@
using System.Collections.Concurrent;
#if NET40_OR_GREATER || NETCOREAPP
using System.Collections.Concurrent;
#endif
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
@@ -12,11 +14,15 @@ namespace BinaryObjectScanner.Protection
public class TivolaRingProtection : IPathCheck
{
/// <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>
{
new PathMatchSet(Path.Combine("ZDAT", "webmast.dxx").Replace("\\", "/"), "Tivola Ring Protection [Check disc for physical ring]"),
new(Path.Combine("ZDAT", "webmast.dxx").Replace("\\", "/"), "Tivola Ring Protection [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
@@ -27,7 +33,7 @@ namespace BinaryObjectScanner.Protection
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(Path.Combine("ZDAT", "webmast.dxx").Replace("\\", "/"), "Tivola Ring Protection [Check disc for physical ring]"),
new(Path.Combine("ZDAT", "webmast.dxx").Replace("\\", "/"), "Tivola Ring Protection [Check disc for physical ring]"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

Some files were not shown because too many files have changed in this diff Show More