Support ancient .NET

This commit is contained in:
Matt Nadareski
2023-11-14 16:10:10 -05:00
parent e823cbaee5
commit 9421249b8e
92 changed files with 512 additions and 148 deletions

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>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>
<LangVersion>latest</LangVersion>
@@ -32,7 +32,7 @@
</PropertyGroup>
<!-- Exclude all external modules for .NET Core and modern .NET -->
<PropertyGroup Condition="!$(TargetFramework.StartsWith(`net4`))">
<PropertyGroup Condition="!$(TargetFramework.StartsWith(`net4`)) OR $(TargetFramework.StartsWith(`net40`))">
<DefaultItemExcludes>
$(DefaultItemExcludes);
_EXTERNAL\**;
@@ -40,7 +40,7 @@
</PropertyGroup>
<!-- These are needed for dealing with native Windows DLLs -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<Content Include="*.dll">
<Pack>true</Pack>
<PackagePath>contentFiles;content</PackagePath>
@@ -55,19 +55,22 @@
<ItemGroup>
<PackageReference Include="OpenMcdf" Version="2.3.0" />
<PackageReference Include="SabreTools.Compression" Version="0.1.1" />
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
<PackageReference Include="SabreTools.Matching" Version="1.1.1" />
<PackageReference Include="SabreTools.Models" Version="1.1.5" />
<PackageReference Include="SabreTools.Serialization" Version="1.1.7" />
<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" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="SharpCompress" Version="0.34.1" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="UnshieldSharp" Version="1.6.9" />
<PackageReference Include="WiseUnpacker" Version="1.0.4" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Compressors;
using SharpCompress.Compressors.Deflate;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -48,7 +50,7 @@ namespace BinaryObjectScanner.FileType
return null;
}
}
/// <summary>
/// Extract all files from the BFPK to an output directory
/// </summary>
@@ -121,12 +123,14 @@ namespace BinaryObjectScanner.FileType
{
fs.Write(data, 0, compressedSize);
}
#if NET462_OR_GREATER
else
{
MemoryStream ms = new MemoryStream(data);
ZlibStream zs = new ZlibStream(ms, CompressionMode.Decompress);
zs.CopyTo(fs);
}
#endif
}
return true;

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Compressors;
using SharpCompress.Compressors.BZip2;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -29,6 +31,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -51,6 +54,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -214,7 +214,11 @@ namespace BinaryObjectScanner.FileType
byte[] fileContent = new byte[0];
try
{
#if NET40
using (BinaryReader br = new BinaryReader(stream, Encoding.Default))
#else
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
#endif
{
fileContent = br.ReadBytes((int)stream.Length);
if (fileContent == null)
@@ -408,10 +412,14 @@ 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
#endregion
#region Helpers

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -29,6 +31,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -62,6 +65,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -37,13 +37,13 @@ namespace BinaryObjectScanner.FileType
{
try
{
string tempFile = Path.Combine(tempPath, cfile.FullPath);
string tempFile = Path.Combine(tempPath, cfile.FullPath!);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
(byte[] fileContents, string error) = archive.Extract(cfile.FullPath);
if (!string.IsNullOrWhiteSpace(error))
(byte[]? fileContents, string? error) = archive.Extract(cfile.FullPath!);
if (fileContents == null || !string.IsNullOrWhiteSpace(error))
continue;
using (FileStream fs = File.OpenWrite(tempFile))

View File

@@ -60,7 +60,10 @@ namespace BinaryObjectScanner.FileType
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
InstallShieldCabinet cabfile = InstallShieldCabinet.Open(file);
var cabfile = InstallShieldCabinet.Open(file);
if (cabfile == null)
return null;
for (int i = 0; i < cabfile.FileCount; i++)
{
try
@@ -72,8 +75,8 @@ namespace BinaryObjectScanner.FileType
string tempFile;
try
{
string filename = cabfile.FileName(i);
tempFile = Path.Combine(tempPath, filename);
string? filename = cabfile.FileName(i);
tempFile = Path.Combine(tempPath, filename ?? string.Empty);
}
catch
{

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET48
#if NETFRAMEWORK && !NET40
using StormLibSharp;
#endif
@@ -28,7 +28,7 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NETCOREAPP || NET5_0_OR_GREATER
#if NET40 || NETCOREAPP || NET5_0_OR_GREATER
// Not supported for .NET Core and modern .NET due to Windows DLL requirements
return null;
#else

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -29,6 +31,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -65,6 +68,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -29,6 +31,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -62,6 +65,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using ICSharpCode.SharpZipLib.Zip.Compression;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -141,17 +143,10 @@ namespace BinaryObjectScanner.FileType
var folder = default(object);
switch (item.Model.Header?.MajorVersion)
{
#if NET48
case 4: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Folders?.FirstOrDefault(f => index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 5: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Folders?.FirstOrDefault(f => index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 6: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Folders?.FirstOrDefault(f => index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 7: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Folders?.FirstOrDefault(f => index >= f.FileStartIndex && index <= f.FileEndIndex); break;
#else
case 4: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory4)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 5: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory5)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 6: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory6)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
case 7: folder = (item.Model.Directory as SabreTools.Models.SGA.Directory7)?.Folders?.FirstOrDefault(f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex); break;
#endif
default: return false;
}
@@ -229,10 +224,14 @@ namespace BinaryObjectScanner.FileType
else
{
// Decompress the data
#if NET462_OR_GREATER
data = new byte[outputFileSize];
Inflater inflater = new Inflater();
inflater.SetInput(compressedData);
inflater.Inflate(data);
#else
data = new byte[outputFileSize];
#endif
}
// If we have an invalid output directory

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -26,6 +28,7 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -59,6 +62,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -29,6 +31,7 @@ namespace BinaryObjectScanner.FileType
if (stream == null)
return null;
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -62,6 +65,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -33,7 +33,11 @@ namespace BinaryObjectScanner.FileType
{
// Load the current file content
var fileContent = string.Empty;
#if 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))
#endif
{
fileContent = sr.ReadToEnd();
}

View File

@@ -1,7 +1,9 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using SharpCompress.Compressors.Xz;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -25,6 +27,7 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
try
{
// Create a temp output directory
@@ -47,6 +50,9 @@ namespace BinaryObjectScanner.FileType
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -185,7 +185,11 @@ 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

View File

@@ -0,0 +1,19 @@
#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

@@ -56,12 +56,12 @@ namespace BinaryObjectScanner.Packer
// Check the product version explicitly
var version = pex.ProductVersion;
if (!string.IsNullOrEmpty(version))
return version;
return version!;
// Check the internal versions
version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;
return version!;
return "(Unknown Version)";
}

View File

@@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
#if NET462_OR_GREATER
using ICSharpCode.SharpZipLib.Zip.Compression;
#endif
using SabreTools.Matching;
using SabreTools.Serialization.Wrappers;
@@ -88,6 +90,7 @@ namespace BinaryObjectScanner.Packer
try
{
// Inflate the data into the buffer
#if NET462_OR_GREATER
Inflater inflater = new Inflater();
inflater.SetInput(payload);
data = new byte[payload.Length * 4];
@@ -95,6 +98,9 @@ namespace BinaryObjectScanner.Packer
// Trim the buffer to the proper size
data = new ReadOnlySpan<byte>(data, 0, read).ToArray();
#else
data = null;
#endif
}
catch
{

View File

@@ -51,7 +51,7 @@ namespace BinaryObjectScanner.Packer
// Check the internal versions
var version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;
return version!;
return "(Unknown Version)";
}

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.IsNullOrWhiteSpace(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

@@ -61,12 +61,12 @@ namespace BinaryObjectScanner.Packer
// Check the product version explicitly
var version = pex.ProductVersion;
if (!string.IsNullOrEmpty(version))
return version;
return version!;
// Check the internal versions
version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;
return version!;
return "(Unknown Version)";
}

View File

@@ -3,9 +3,11 @@ using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Readers;
#endif
namespace BinaryObjectScanner.Packer
{
@@ -45,6 +47,7 @@ namespace BinaryObjectScanner.Packer
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
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.
@@ -81,6 +84,9 @@ namespace BinaryObjectScanner.Packer
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -4,8 +4,10 @@ using System.Linq;
using System.Text;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
#if NET462_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
#endif
namespace BinaryObjectScanner.Packer
{
@@ -75,6 +77,7 @@ namespace BinaryObjectScanner.Packer
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET462_OR_GREATER
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.
@@ -111,6 +114,9 @@ namespace BinaryObjectScanner.Packer
if (includeDebug) Console.WriteLine(ex);
return null;
}
#else
return null;
#endif
}
/// <summary>

View File

@@ -0,0 +1,110 @@
#if NET40
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
using System.Diagnostics;
namespace System
{
/// <summary>
/// Provides an IProgress{T} that invokes callbacks for each reported progress value.
/// </summary>
/// <typeparam name="T">Specifies the type of the progress report value.</typeparam>
/// <remarks>
/// Any handler provided to the constructor or event handlers registered with
/// the <see cref="ProgressChanged"/> event are invoked through a
/// <see cref="SynchronizationContext"/> instance captured
/// when the instance is constructed. If there is no current SynchronizationContext
/// at the time of construction, the callbacks will be invoked on the ThreadPool.
/// </remarks>
/// <see href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Progress.cs"/>
public class Progress<T> : IProgress<T> where T : EventArgs
{
/// <summary>The synchronization context captured upon construction. This will never be null.</summary>
private readonly SynchronizationContext _synchronizationContext;
/// <summary>The handler specified to the constructor. This may be null.</summary>
private readonly Action<T>? _handler;
/// <summary>A cached delegate used to post invocation to the synchronization context.</summary>
private readonly SendOrPostCallback _invokeHandlers;
/// <summary>Initializes the <see cref="Progress{T}"/>.</summary>
public Progress()
{
// Capture the current synchronization context.
// If there is no current context, we use a default instance targeting the ThreadPool.
_synchronizationContext = SynchronizationContext.Current ?? ProgressStatics.DefaultContext;
Debug.Assert(_synchronizationContext != null);
_invokeHandlers = new SendOrPostCallback(InvokeHandlers);
}
/// <summary>Initializes the <see cref="Progress{T}"/> with the specified callback.</summary>
/// <param name="handler">
/// A handler to invoke for each reported progress value. This handler will be invoked
/// in addition to any delegates registered with the <see cref="ProgressChanged"/> event.
/// Depending on the <see cref="SynchronizationContext"/> instance captured by
/// the <see cref="Progress{T}"/> at construction, it's possible that this handler instance
/// could be invoked concurrently with itself.
/// </param>
/// <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;
}
/// <summary>Raised for each reported progress value.</summary>
/// <remarks>
/// Handlers registered with this event will be invoked on the
/// <see cref="SynchronizationContext"/> captured when the instance was constructed.
/// </remarks>
public event EventHandler<T>? ProgressChanged;
/// <summary>Reports a progress change.</summary>
/// <param name="value">The value of the updated progress.</param>
protected virtual void OnReport(T value)
{
// If there's no handler, don't bother going through the sync context.
// Inside the callback, we'll need to check again, in case
// an event handler is removed between now and then.
Action<T>? handler = _handler;
EventHandler<T>? changedEvent = ProgressChanged;
if (handler != null || changedEvent != null)
{
// Post the processing to the sync context.
// (If T is a value type, it will get boxed here.)
_synchronizationContext.Post(_invokeHandlers, value);
}
}
/// <summary>Reports a progress change.</summary>
/// <param name="value">The value of the updated progress.</param>
void IProgress<T>.Report(T value) { OnReport(value); }
/// <summary>Invokes the action and event callbacks.</summary>
/// <param name="state">The progress value.</param>
private void InvokeHandlers(object? state)
{
T value = (T)state!;
Action<T>? handler = _handler;
EventHandler<T>? changedEvent = ProgressChanged;
handler?.Invoke(value);
changedEvent?.Invoke(this, value);
}
}
/// <summary>Holds static values for <see cref="Progress{T}"/>.</summary>
/// <remarks>This avoids one static instance per type T.</remarks>
internal static class ProgressStatics
{
/// <summary>A default synchronization context that targets the ThreadPool.</summary>
internal static readonly SynchronizationContext DefaultContext = new SynchronizationContext();
}
}
#endif

View File

@@ -80,7 +80,7 @@ namespace BinaryObjectScanner.Protection
// These files are "Asc001.dll", "Asc002.dll", "Asc003.dll", "Asc005.dll", and "Asc006.exe" (Found in Redump entry 73521/IA item "Nova_HoyleCasino99USA").
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -23,7 +23,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("PlayDVD.exe", useEndsWith: true), "Alpha-DVD (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Protection
}, "Bitpool"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -140,7 +140,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("Byteshield.ini", useEndsWith: true), "ByteShield"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -199,7 +199,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch(".Qz", matchExact: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
@@ -228,7 +228,13 @@ namespace BinaryObjectScanner.Protection
if (fileContent == null)
return null;
#if NET40
byte[] versionBytes = new byte[4];
Array.Copy(fileContent, positions[0] + 15, versionBytes, 0, 4);
char[] version = versionBytes.Select(b => (char)b).ToArray();
#else
char[] version = new ArraySegment<byte>(fileContent, positions[0] + 15, 4).Select(b => (char)b).ToArray();
#endif
if (version[0] == 0x00)
return string.Empty;

View File

@@ -63,7 +63,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("cdguard.dll", useEndsWith: true), "CD-Guard Copy Protection System"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -73,7 +73,7 @@ namespace BinaryObjectScanner.Protection
// 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).
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -35,7 +35,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("Track#1 - Track#2 Cd-Protector.wav", useEndsWith: true), "CD-Protector"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("CHKCDXNT.DLL", useEndsWith: true), "CD-X (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("cenega.dll", useEndsWith: true), "Cenega ProtectDVD"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -65,7 +65,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("Code-Lock Wizard.exe", useEndsWith: true), "ChosenBytes Code-Lock"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -39,7 +39,7 @@ namespace BinaryObjectScanner.Protection
//new PathMatchSet(new PathMatch("Autorun.dat", useEndsWith: true), "CopyKiller"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -15,7 +15,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("DvdCrypt.pdb", useEndsWith: true), "DVD Crypt (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -270,7 +270,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("Denuvo Anti-Cheat Installer.exe", useEndsWith: true), "Denuvo Anti-Cheat"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -63,7 +63,7 @@ namespace BinaryObjectScanner.Protection
// There are at least two additional specifically named DecryptWrap files, "DecryptWrapTW2000.exe" and "DecryptWrapTW2KCode.exe" in IA item "Nova_DellBigWIGDVD_USA"/Redump entry 108588.
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch(Path.Combine("XCONTROL", "COMPSCO._01").Replace("\\", "/"), useEndsWith: true), "Dinamic Multimedia Protection/LockBlocks [Check disc for 2 physical rings]"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -163,7 +163,7 @@ namespace BinaryObjectScanner.Protection
}, "DiscGuard"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>
@@ -188,7 +188,7 @@ namespace BinaryObjectScanner.Protection
// Check the internal versions
var version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;
return version!;
return "(Unknown Version)";
}
@@ -201,14 +201,14 @@ namespace BinaryObjectScanner.Protection
return null;
// Check the internal versions
string version = GetInternalVersion(file, Array.Empty<string>());
string version = GetInternalVersion(file);
if (!string.IsNullOrEmpty(version))
return version;
return string.Empty;
}
private string GetInternalVersion(string firstMatchedString, IEnumerable<string> files)
private string GetInternalVersion(string firstMatchedString)
{
try
{

View File

@@ -31,17 +31,17 @@ namespace BinaryObjectScanner.Protection
var name = pex.FileDescription;
// Found in "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam).
if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
return "Easy Anti-Cheat (EOS Version)";
// Found in "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "EasyAntiCheat_EOS.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Service (EOS)"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat Service (EOS)"))
return "Easy Anti-Cheat (EOS Version)";
// These two generic checks are both general enough to detect the majority of files known to contain Easy Anti-Cheat, as well as specific enough to avoid false positives.
else if (!string.IsNullOrEmpty(name) && name.Contains("EasyAntiCheat"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("EasyAntiCheat"))
return "Easy Anti-Cheat";
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat"))
return "Easy Anti-Cheat";
// For documentation, known exact File Descriptions and their associated files are listed below:
@@ -57,17 +57,17 @@ namespace BinaryObjectScanner.Protection
name = pex.ProductName;
// Found in multiple files, including "VideoHorrorSociety.exe" ("Video Horror Society", Patch 1.0.70309, Steam) and "start_protected_game.exe" ("VRChat", Version 2022.2.2p2, Oculus).
if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat Bootstrapper (EOS)"))
return "Easy Anti-Cheat (EOS Version)";
// Found in multiple files, including "EasyAntiCheat_EOS_Setup.exe" ("Video Horror Society", Patch 1.0.70309, Steam; "VRChat", Version 2022.2.2p2, Oculus) and "EasyAntiCheat.exe", which is found installed in "Program Files (x86)\EasyAntiCheat_EOS".
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat Service (EOS)"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat Service (EOS)"))
return "Easy Anti-Cheat (EOS Version)";
// These two generic checks are both general enough to detect the majority of files known to contain Easy Anti-Cheat, as well as specific enough to avoid false positives.
else if (!string.IsNullOrEmpty(name) && name.Contains("EasyAntiCheat"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("EasyAntiCheat"))
return "Easy Anti-Cheat";
else if (!string.IsNullOrEmpty(name) && name.Contains("Easy Anti-Cheat"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Easy Anti-Cheat"))
return "Easy Anti-Cheat";
// For documentation, known exact Product Names and their associated files are listed below:
@@ -123,7 +123,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("easyanticheat_x64.so", useEndsWith: true), "Easy Anti-Cheat"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -58,7 +58,7 @@ namespace BinaryObjectScanner.Protection
// The file "engine32.dll" is present in every known instance of this DRM, but isn't being checked for currently due to the generic file name.
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -48,7 +48,7 @@ namespace BinaryObjectScanner.Protection
}, "Freelock 1.3"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -46,7 +46,7 @@ namespace BinaryObjectScanner.ProtectionType
new PathMatchSet(new PathMatch("XLiveRedist.msi", useEndsWith: true), "Games for Windows LIVE"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -46,7 +46,7 @@ namespace BinaryObjectScanner.Protection
// Possibly related file "31AD0095.fil" that appears to contain intentional errors found in Redump entry 93700.
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -99,7 +99,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("HCPSMng.exe", useEndsWith: true), "HexaLock AutoLock 4.5"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("ReactorActivate.exe", useEndsWith: true), GetInternalVersion, "Stardock Product Activation"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
@@ -77,7 +77,7 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
private string GetInternalVersion(string firstMatchedString, IEnumerable<string> files)
private string? GetInternalVersion(string firstMatchedString, IEnumerable<string>? files)
{
try
{

View File

@@ -21,7 +21,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("INDYMP3.idt", useEndsWith: true), "IndyVCD (Unconfirmed - Please report to us on Github)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -73,7 +73,13 @@ namespace BinaryObjectScanner.Protection
return null;
int position = positions[0];
#if NET40
byte[] versionBytes = new byte[8];
Array.Copy(fileContent, position + 67, versionBytes, 0, 8);
char[] version = versionBytes.Select(b => (char)b).ToArray();
#else
char[] version = new ArraySegment<byte>(fileContent, position + 67, 8).Select(b => (char)b).ToArray();
#endif
return new string(version);
}
}

View File

@@ -69,7 +69,7 @@ namespace BinaryObjectScanner.Protection
}, "LabelGate CD2"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -128,7 +128,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("laserlok.out", useEndsWith: true), "LaserLok [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
@@ -169,20 +169,44 @@ namespace BinaryObjectScanner.Protection
if (versionTwo)
{
int index = position + 14;
#if NET40
byte[] temp = new byte[2];
Array.Copy(sectionContent, index, temp, 0, 2);
day = new string(temp.Select(b => (char)b).ToArray());
index += 3;
Array.Copy(sectionContent, index, temp, 0, 2);
month = new string(temp.Select(b => (char)b).ToArray());
index += 3;
Array.Copy(sectionContent, index, temp, 0, 2);
year = "20" + new string(temp.Select(b => (char)b).ToArray());
#else
day = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
index += 3;
month = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
index += 3;
year = "20" + new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
#endif
}
else
{
int index = position + 13;
#if NET40
byte[] temp = new byte[2];
Array.Copy(sectionContent, index, temp, 0, 2);
day = new string(temp.Select(b => (char)b).ToArray());
index += 3;
Array.Copy(sectionContent, index, temp, 0, 2);
month = new string(temp.Select(b => (char)b).ToArray());
index += 3;
Array.Copy(sectionContent, index, temp, 0, 2);
year = "20" + new string(temp.Select(b => (char)b).ToArray());
#else
day = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
index += 3;
month = new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
index += 3;
year = "20" + new string(new ArraySegment<byte>(sectionContent, index, 2).Select(b => (char)b).ToArray());
#endif
}
return $"(Build {year}-{month}-{day})";
@@ -194,10 +218,16 @@ namespace BinaryObjectScanner.Protection
if (sectionContent == null)
return null;
#if NET40
byte[] temp = new byte[4];
Array.Copy(sectionContent, position + 76, temp, 0, 4);
return new string(temp.Select(b => (char)b).ToArray());
#else
return new string(new ArraySegment<byte>(sectionContent, position + 76, 4).Select(b => (char)b).ToArray());
#endif
}
public static string GetVersion16Bit(string firstMatchedString, IEnumerable<string> files)
public static string? GetVersion16Bit(string firstMatchedString, IEnumerable<string>? files)
{
if (!File.Exists(firstMatchedString))
return string.Empty;
@@ -211,7 +241,13 @@ namespace BinaryObjectScanner.Protection
private static string GetVersion16Bit(byte[] fileContent)
{
#if NET40
byte[] temp = new byte[7];
Array.Copy(fileContent, 71, temp, 0, 7);
char[] version = temp.Select(b => (char)b).ToArray();
#else
char[] version = new ArraySegment<byte>(fileContent, 71, 7).Select(b => (char)b).ToArray();
#endif
if (char.IsNumber(version[0]) && char.IsNumber(version[2]) && char.IsNumber(version[3]))
{
if (char.IsNumber(version[5]) && char.IsNumber(version[6]))

View File

@@ -187,7 +187,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("CDILLA16.EXE", useEndsWith: true), "C-Dilla License Management System"),
};
return MatchUtil.GetAllMatches(files ?? Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>

View File

@@ -87,7 +87,7 @@ namespace BinaryObjectScanner.Protection
// Due to this file being used in both protections, this file is detected within the general Macrovision checks.
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>

View File

@@ -71,7 +71,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("9KMJ9G4I.EXE", useEndsWith: true), "RipGuard (Unconfirmed - Please report to us on GitHub)"),
};
return MatchUtil.GetAllMatches(files ?? Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>

View File

@@ -183,7 +183,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("CDAC13BA.EXE", useEndsWith: true), "SafeCast"),
};
return MatchUtil.GetAllMatches(files ?? Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>

View File

@@ -214,7 +214,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(".SafeDiscDVD.bundle", "SafeDisc for Macintosh"),
};
return MatchUtil.GetAllMatches(files ?? Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
@@ -294,7 +294,7 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
internal static string GetSafeDiscCLCD16Version(string firstMatchedString, IEnumerable<string> files)
internal static string GetSafeDiscCLCD16Version(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
@@ -318,7 +318,7 @@ namespace BinaryObjectScanner.Protection
}
}
internal static string GetSafeDiscCLCD32Version(string firstMatchedString, IEnumerable<string> files)
internal static string GetSafeDiscCLCD32Version(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
@@ -407,7 +407,7 @@ namespace BinaryObjectScanner.Protection
}
}
internal static string GetSafeDiscCLOKSPLVersion(string firstMatchedString, IEnumerable<string> files)
internal static string GetSafeDiscCLOKSPLVersion(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
@@ -501,7 +501,7 @@ namespace BinaryObjectScanner.Protection
}
}
internal static string GetSafeDiscDPlayerXVersion(string firstMatchedString, IEnumerable<string> files)
internal static string GetSafeDiscDPlayerXVersion(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
@@ -563,7 +563,7 @@ namespace BinaryObjectScanner.Protection
}
}
internal static string GetSafeDiscDrvmgtVersion(string firstMatchedString, IEnumerable<string> files)
internal static string GetSafeDiscDrvmgtVersion(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;

View File

@@ -252,7 +252,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new FilePathMatch("secdrv.sys"), GetSecdrvFileSizeVersion, "Macrovision Security Driver"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="IPathCheck.CheckFilePath(string)"/>
@@ -267,7 +267,7 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
internal static string Get00000001TMPVersion(string firstMatchedString, IEnumerable<string> files)
internal static string? Get00000001TMPVersion(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;
@@ -293,7 +293,7 @@ namespace BinaryObjectScanner.Protection
}
// 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+.
internal static string GetSecdrvFileSizeVersion(string firstMatchedString, IEnumerable<string> files)
internal static string? GetSecdrvFileSizeVersion(string firstMatchedString, IEnumerable<string>? files)
{
if (string.IsNullOrEmpty(firstMatchedString) || !File.Exists(firstMatchedString))
return string.Empty;

View File

@@ -47,7 +47,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("scvfy.exe", useEndsWith: true), "MediaCloQ"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -86,7 +86,7 @@ namespace BinaryObjectScanner.Protection
}, "MediaMax CD-3"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -43,7 +43,7 @@ namespace BinaryObjectScanner.Protection
// Found in "NeacSafe64.sys" and "NeacSafe.sys".
// TODO: Fix Product Name not being properly grabbed from the file.
if (!string.IsNullOrEmpty(name) && name.Contains("neacsafe"))
if (!string.IsNullOrEmpty(name) && name!.Contains("neacsafe"))
return "NEAC Protect";
return null;
@@ -65,7 +65,7 @@ namespace BinaryObjectScanner.Protection
// Known associated log files: "NeacSafe.log", "Neac.log", "NeacDll.log", "NeacLoader.log", and "NeacBak.log".
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -87,7 +87,7 @@ namespace BinaryObjectScanner.Protection
}, "OpenMG"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -36,7 +36,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("OriginSetup.exe", useEndsWith: true), "Origin"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -53,7 +53,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("PJSTREAM.DLL", useEndsWith: true), "PlayJ Music Player Component"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -136,12 +136,24 @@ namespace BinaryObjectScanner.Protection
int index = positions[0] - 12;
// Version 6-7 with Build Number in plain text
#if NET40
byte[] temp = new byte[4];
Array.Copy(fileContent, index, temp, 0, 4);
if (temp.SequenceEqual(new byte[] { 0x0A, 0x0D, 0x0A, 0x0D }))
#else
if (new ArraySegment<byte>(fileContent, index, 4).SequenceEqual(new byte[] { 0x0A, 0x0D, 0x0A, 0x0D }))
#endif
{
index = positions[0] - 12 - 6;
// Version 7
#if NET40
temp = new byte[6];
Array.Copy(fileContent, index, temp, 0, 6);
if (new string(temp.Select(b => (char)b).ToArray()) == "Henrik")
#else
if (new string(new ArraySegment<byte>(fileContent, index, 6).Select(b => (char)b).ToArray()) == "Henrik")
#endif
{
version = "7.1-7.5";
index = positions[0] - 12 - 6 - 6;
@@ -164,7 +176,13 @@ namespace BinaryObjectScanner.Protection
index -= 5;
}
#if NET40
temp = new byte[6];
Array.Copy(fileContent, index, temp, 0, 6);
char[] arrBuild = temp.Select(b => (char)b).ToArray();
#else
char[] arrBuild = new ArraySegment<byte>(fileContent, index, 6).Select(b => (char)b).ToArray();
#endif
if (!Int32.TryParse(new string(arrBuild), out int intBuild))
strBuild = $"[Build {new string(arrBuild).Trim()}]";
else

View File

@@ -126,7 +126,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("SX32W.DLL", useEndsWith: true), "Rainbow Sentinel"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -42,7 +42,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("protect.pro", useEndsWith: true), "Ring PROTECH / ProRing [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -102,7 +102,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new FilePathMatch("svkpnd.dll"), "SVKP"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -32,7 +32,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("SafeLock.256", useEndsWith: true), "SafeLock"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -65,7 +65,11 @@ namespace BinaryObjectScanner.Protection
if (nthSection == null)
continue;
#if NET40 || NET452
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? []).TrimEnd('\0');
#else
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? Array.Empty<byte>()).TrimEnd('\0');
#endif
if (nthSectionName != ".idata" && nthSectionName != ".rsrc")
{
var nthSectionData = pex.GetFirstSectionData(nthSectionName);
@@ -130,7 +134,7 @@ namespace BinaryObjectScanner.Protection
}, "SecuROM 7.01"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
@@ -217,7 +221,12 @@ namespace BinaryObjectScanner.Protection
private static string GetV7Version(PortableExecutable pex)
{
int index = 172; // 64 bytes for DOS stub, 236 bytes in total
#if NETFRAMEWORK
byte[] bytes = new byte[4];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 4);
#else
byte[] bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 4).ToArray();
#endif
//SecuROM 7 new and 8
if (bytes[3] == 0x5C) // if (bytes[0] == 0xED && bytes[3] == 0x5C {
@@ -229,7 +238,12 @@ namespace BinaryObjectScanner.Protection
else
{
index = 58; // 64 bytes for DOS stub, 122 bytes in total
#if NETFRAMEWORK
bytes = new byte[2];
Array.Copy(pex.StubExecutableData, index, bytes, 0, 2);
#else
bytes = new ReadOnlySpan<byte>(pex.StubExecutableData, index, 2).ToArray();
#endif
return $"7.{bytes[0] ^ 0x10:00}.{bytes[1] ^ 0x10:0000}"; //return "7.01-7.10"
}
}
@@ -258,7 +272,13 @@ namespace BinaryObjectScanner.Protection
if (!success)
return "8";
byte[] bytes = new ReadOnlySpan<byte>(dataSectionRaw, position + 0xAC, 3).ToArray();
#if NETFRAMEWORK
byte[] bytes = new byte[3];
Array.Copy(dataSectionRaw, position + 0xAC, bytes, 0, 3);
#else
byte[] bytes = new ReadOnlySpan<byte>(dataSectionRaw, position + 0xAC, 3).ToArray();
#endif
return $"{bytes[0] ^ 0xCA}.{bytes[1] ^ 0x39:00}.{bytes[2] ^ 0x51:0000}";
}
}

View File

@@ -40,7 +40,7 @@ namespace BinaryObjectScanner.Protection
}, "SmartE"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -93,7 +93,7 @@ namespace BinaryObjectScanner.Protection
}, "SoftLock"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -125,7 +125,7 @@ namespace BinaryObjectScanner.ProtectionType
};
// TODO: Verify if these are OR or AND
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
@@ -149,8 +149,21 @@ namespace BinaryObjectScanner.ProtectionType
return null;
int position = positions[0];
#if NET40
byte[] id1 = new byte[3];
Array.Copy(fileContent, position + 5, id1, 0, 3);
byte[] id2 = new byte[4];
Array.Copy(fileContent, position + 16, id2, 0, 3);
#else
var id1 = new ArraySegment<byte>(fileContent, position + 5, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 16, 4);
#endif
if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
return "v1";
else if (id1.SequenceEqual(new byte[] { 0x2E, 0x6F, 0x26 }) && id2.SequenceEqual(new byte[] { 0xDB, 0xC5, 0x20, 0x3A })) // new byte[] { 0xDB, 0xC5, 0x20, 0x3A, 0xB9 }
return "v2"; // TODO: Verify against other SolidShield 2 discs
if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 }))
return "v1";
@@ -167,8 +180,15 @@ namespace BinaryObjectScanner.ProtectionType
return null;
int position = positions[0];
#if NET40
byte[] id1 = new byte[3];
Array.Copy(fileContent, position + 4, id1, 0, 3);
byte[] id2 = new byte[4];
Array.Copy(fileContent, position + 15, id2, 0, 3);
#else
var id1 = new ArraySegment<byte>(fileContent, position + 4, 3);
var id2 = new ArraySegment<byte>(fileContent, position + 15, 4);
#endif
if ((fileContent[position + 3] == 0x04 || fileContent[position + 3] == 0x05)
&& id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 })

View File

@@ -132,7 +132,7 @@ namespace BinaryObjectScanner.Protection
}, "StarForce"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -17,21 +17,21 @@ namespace BinaryObjectScanner.Protection
return null;
var name = pex.FileDescription;
if (!string.IsNullOrEmpty(name) && name.Contains("Steam Autorun Setup"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Autorun Setup"))
return "Steam";
else if (!string.IsNullOrEmpty(name) && name.Contains("Steam Client API"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client API"))
return "Steam";
else if (!string.IsNullOrEmpty(name) && name.Contains("Steam Client Engine"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Engine"))
return $"Steam Client Engine {pex.GetInternalVersion()}";
else if (!string.IsNullOrEmpty(name) && name.Contains("Steam Client Service"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Service"))
return "Steam";
name = pex.ProductName;
if (!string.IsNullOrEmpty(name) && name.Contains("Steam Autorun Setup"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Autorun Setup"))
return "Steam";
else if (!string.IsNullOrEmpty(name) && name.Contains("Steam Client API"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client API"))
return "Steam";
else if (!string.IsNullOrEmpty(name) && name.Contains("Steam Client Service"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Service"))
return "Steam";
/// TODO: Add entry point checks
@@ -83,7 +83,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("steamxboxutil64.exe", useEndsWith: true), "Steam"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -66,7 +66,7 @@ namespace BinaryObjectScanner.Protection
// Newer versions of TZCopyProtection also create files with a TZC extension, though their purpose is currently unknown.
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -150,7 +150,7 @@ namespace BinaryObjectScanner.ProtectionType
new PathMatchSet(new PathMatch("GAME.KWN", useEndsWith: true), "TAGES (BASIC?)"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>
@@ -215,7 +215,7 @@ namespace BinaryObjectScanner.ProtectionType
// Check the internal versions
var version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;
return version!;
return "(Unknown Version)";
}

View File

@@ -19,7 +19,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(Path.Combine("ZDAT", "webmast.dxx").Replace("\\", "/"), "Tivola Ring Protection [Check disc for physical ring]"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -18,26 +18,26 @@ namespace BinaryObjectScanner.Protection
return null;
var name = pex.FileDescription;
if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Connect Installer"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect Installer"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Connect Service"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect Service"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Connect WebCore"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect WebCore"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Crash Reporter"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Crash Reporter"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Game Launcher"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Game Launcher"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Uplay Installer"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Uplay Installer"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Uplay launcher"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Uplay launcher"))
return "Uplay / Ubisoft Connect";
// There's also a variant that looks like "Uplay <version> installer"
name = pex.ProductName;
if (!string.IsNullOrEmpty(name) && name.Contains("Ubisoft Connect"))
if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect"))
return "Uplay / Ubisoft Connect";
else if (!string.IsNullOrEmpty(name) && name.Contains("Uplay"))
else if (!string.IsNullOrEmpty(name) && name!.Contains("Uplay"))
return "Uplay / Ubisoft Connect";
return null;
@@ -59,7 +59,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new FilePathMatch("UplayWebCore.exe"), "Uplay / Ubisoft Connect"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -56,7 +56,7 @@ namespace BinaryObjectScanner.Protection
}, "Windows Media Data Session DRM"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection
}, "WTM Protection Viewer"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: false);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("WinLock.PSX", useEndsWith: true), "WinLock"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -18,7 +18,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet($"Zzxzz/", "Zzxzz"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -93,7 +93,7 @@ namespace BinaryObjectScanner.Protection
new PathMatchSet(new PathMatch("npkpdb.dll", useEndsWith: true), "nProtect KeyCrypt"),
};
return MatchUtil.GetAllMatches(files ?? System.Array.Empty<string>(), matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>

View File

@@ -3,12 +3,16 @@
/// <summary>
/// Struct representing protection scanning progress
/// </summary>
#if NET40
public class ProtectionProgress : System.EventArgs
#else
public struct ProtectionProgress
#endif
{
/// <summary>
/// Filename to report progress for
/// </summary>
#if NETFRAMEWORK
#if NETFRAMEWORK || NETCOREAPP3_1
public string? Filename { get; private set; }
#else
public string? Filename { get; init; }
@@ -17,7 +21,7 @@
/// <summary>
/// Value between 0 and 1 representign the percentage completed
/// </summary>
#if NETFRAMEWORK
#if NETFRAMEWORK || NETCOREAPP3_1
public float Percentage { get; private set; }
#else
public float Percentage { get; init; }
@@ -26,7 +30,7 @@
/// <summary>
/// Protection information to report
/// </summary>
#if NETFRAMEWORK
#if NETFRAMEWORK || NETCOREAPP3_1
public string? Protection { get; private set; }
#else
public string? Protection { get; init; }

View File

@@ -71,8 +71,10 @@ namespace BinaryObjectScanner
this._fileProgress = fileProgress;
#if NET462_OR_GREATER
// Register the codepages
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
#endif
}
#region Scanning