Fix templated nullability issues

This commit is contained in:
Matt Nadareski
2023-09-17 22:37:01 -04:00
parent 1bd9f3fd88
commit a0b13a6e6f
120 changed files with 1390 additions and 442 deletions

View File

@@ -270,7 +270,11 @@ namespace BinaryObjectScanner.FileType
Parallel.ForEach(ContentCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
#if NET48
string protection = checkClass.CheckContents(file, fileContent, includeDebug);
#else
string? protection = checkClass.CheckContents(file, fileContent, includeDebug);
#endif
if (string.IsNullOrWhiteSpace(protection))
return;
@@ -304,7 +308,11 @@ namespace BinaryObjectScanner.FileType
Parallel.ForEach(LinearExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
#if NET48
string protection = checkClass.CheckLinearExecutable(file, lex, includeDebug);
#else
string? protection = checkClass.CheckLinearExecutable(file, lex, includeDebug);
#endif
if (string.IsNullOrWhiteSpace(protection))
return;
@@ -338,7 +346,11 @@ namespace BinaryObjectScanner.FileType
Parallel.ForEach(MSDOSExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
#if NET48
string protection = checkClass.CheckMSDOSExecutable(file, mz, includeDebug);
#else
string? protection = checkClass.CheckMSDOSExecutable(file, mz, includeDebug);
#endif
if (string.IsNullOrWhiteSpace(protection))
return;
@@ -372,7 +384,11 @@ namespace BinaryObjectScanner.FileType
Parallel.ForEach(NewExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
#if NET48
string protection = checkClass.CheckNewExecutable(file, nex, includeDebug);
#else
string? protection = checkClass.CheckNewExecutable(file, nex, includeDebug);
#endif
if (string.IsNullOrWhiteSpace(protection))
return;
@@ -406,7 +422,11 @@ namespace BinaryObjectScanner.FileType
Parallel.ForEach(PortableExecutableCheckClasses, checkClass =>
{
// Get the protection for the class, if possible
#if NET48
string protection = checkClass.CheckPortableExecutable(file, pex, includeDebug);
#else
string? protection = checkClass.CheckPortableExecutable(file, pex, includeDebug);
#endif
if (string.IsNullOrWhiteSpace(protection))
return;
@@ -449,9 +469,10 @@ namespace BinaryObjectScanner.FileType
private static IEnumerable<T>? InitCheckClasses<T>(Assembly assembly)
#endif
{
return assembly.GetTypes()
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)
.Select(t => (T)Activator.CreateInstance(t));
return assembly.GetTypes()?
.Where(t => t.IsClass && t.GetInterface(typeof(T).Name) != null)?
.Select(t => (T)Activator.CreateInstance(t))
.Cast<T>() ?? Array.Empty<T>();
}
#endregion
@@ -464,7 +485,7 @@ namespace BinaryObjectScanner.FileType
/// <param name="impl">Implementation that was last used to check</param>
private static bool CheckIfGameEngine(object impl)
{
return impl.GetType().Namespace.ToLowerInvariant().Contains("gameengine");
return impl?.GetType()?.Namespace?.ToLowerInvariant()?.Contains("gameengine") ?? false;
}
/// <summary>
@@ -473,7 +494,7 @@ namespace BinaryObjectScanner.FileType
/// <param name="impl">Implementation that was last used to check</param>
private static bool CheckIfPacker(object impl)
{
return impl.GetType().Namespace.ToLowerInvariant().Contains("packer");
return impl.GetType()?.Namespace?.ToLowerInvariant()?.Contains("packer") ?? false;
}
#endregion

View File

@@ -18,10 +18,14 @@ namespace BinaryObjectScanner.GameEngine
public class RenderWare : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -12,6 +12,10 @@
/// <param name="fileContent">Byte array representing the file contents</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>String containing any protections found in the file</returns>
#if NET48
string CheckContents(string file, byte[] fileContent, bool includeDebug);
#else
string? CheckContents(string file, byte[] fileContent, bool includeDebug);
#endif
}
}

View File

@@ -14,6 +14,10 @@ namespace BinaryObjectScanner.Interfaces
/// <param name="lex">LinearExecutable representing the read-in file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>String containing any protections found in the file</returns>
#if NET48
string CheckLinearExecutable(string file, LinearExecutable lex, bool includeDebug);
#else
string? CheckLinearExecutable(string file, LinearExecutable lex, bool includeDebug);
#endif
}
}

View File

@@ -14,6 +14,10 @@ namespace BinaryObjectScanner.Interfaces
/// <param name="mz">MSDOS representing the read-in file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>String containing any protections found in the file</returns>
#if NET48
string CheckMSDOSExecutable(string file, MSDOS mz, bool includeDebug);
#else
string? CheckMSDOSExecutable(string file, MSDOS mz, bool includeDebug);
#endif
}
}

View File

@@ -14,6 +14,10 @@ namespace BinaryObjectScanner.Interfaces
/// <param name="nex">NewExecutable representing the read-in file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>String containing any protections found in the file</returns>
#if NET48
string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug);
#else
string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug);
#endif
}
}

View File

@@ -24,6 +24,10 @@ namespace BinaryObjectScanner.Interfaces
/// </summary>
/// <param name="path">Path to check for protection indicators</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 NET48
string CheckFilePath(string path);
#else
string? CheckFilePath(string path);
#endif
}
}

View File

@@ -14,6 +14,10 @@ namespace BinaryObjectScanner.Interfaces
/// <param name="pex">PortableExecutable representing the read-in file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>String containing any protections found in the file</returns>
#if NET48
string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug);
#else
string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug);
#endif
}
}

View File

@@ -11,10 +11,14 @@ namespace BinaryObjectScanner.Packer
public class ASPack : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -28,7 +32,7 @@ namespace BinaryObjectScanner.Packer
// if (pex.EntryPointRaw != null)
// {
// var matchers = GenerateMatchers();
// string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// return match;
// }
@@ -37,11 +41,15 @@ namespace BinaryObjectScanner.Packer
var adataSection = pex.GetFirstSection(".adata", exact: false);
if (adataSection != null)
{
#if NET48
var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name));
#else
var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name!));
#endif
if (adataSectionRaw != null)
{
var matchers = GenerateMatchers();
string match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class AdvancedInstaller : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .rdata section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".rdata");
var strs = pex.GetFirstSectionStrings(".rdata");
if (strs != null)
{
if (strs.Any(s => s.Contains("Software\\Caphyon\\Advanced Installer")))

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
@@ -12,10 +11,14 @@ namespace BinaryObjectScanner.Packer
public class Armadillo : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -25,14 +28,17 @@ namespace BinaryObjectScanner.Packer
return "Armadillo";
// Loop through all "extension" sections -- usually .data1 or .text1
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
if (pex.SectionNames != null)
{
// Get the section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(sectionName);
if (strs != null)
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
{
if (strs.Any(s => s.Contains("ARMDEBUG")))
return "Armadillo";
// Get the section strings, if they exist
var strs = pex.GetFirstSectionStrings(sectionName);
if (strs != null)
{
if (strs.Any(s => s.Contains("ARMDEBUG")))
return "Armadillo";
}
}
}

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class AutoPlayMediaStudio : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Known to detect versions 5.0.0.3 - 8.1.0.0
string name = pex.ProductName;
var name = pex.ProductName;
if (name?.StartsWith("AutoPlay Media Studio", StringComparison.OrdinalIgnoreCase) == true)
return $"AutoPlay Media Studio {GetVersion(pex)}";
@@ -58,11 +62,15 @@ namespace BinaryObjectScanner.Packer
{
return null;
}
private string GetVersion(PortableExecutable pex)
{
// Check the product version explicitly
#if NET48
string version = pex.ProductVersion;
#else
string? version = pex.ProductVersion;
#endif
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -16,10 +16,14 @@ namespace BinaryObjectScanner.Packer
public class CExe : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -27,7 +31,9 @@ namespace BinaryObjectScanner.Packer
if (pex.FindResourceByNamedType("99, ").Count() == 2)
return "CExe";
var matchers = new List<ContentMatchSet>
if (pex.StubExecutableData != null)
{
var matchers = new List<ContentMatchSet>
{
new ContentMatchSet(new byte?[]
{
@@ -40,9 +46,10 @@ namespace BinaryObjectScanner.Packer
}, "CExe")
};
string match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
return null;
}
@@ -73,12 +80,12 @@ namespace BinaryObjectScanner.Packer
try
{
// Parse into an executable again for easier extraction
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex == null)
return null;
// Get the first resource of type 99 with index 2
byte[] payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
var payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
if (payload == null || payload.Length == 0)
return null;
@@ -86,7 +93,7 @@ namespace BinaryObjectScanner.Packer
bool zlib = pex.FindResourceByNamedType("99, 1").Any();
// Create the output data buffer
byte[] data;
var data = new byte[0];
// If we had the decompression DLL included, it's zlib
if (zlib)

View File

@@ -13,7 +13,11 @@ namespace BinaryObjectScanner.Packer
public class EXEStealth : IContentCheck, IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -38,10 +42,14 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -14,10 +14,14 @@ namespace BinaryObjectScanner.Packer
public class EmbeddedExecutable : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -54,14 +58,15 @@ namespace BinaryObjectScanner.Packer
try
{
// Parse into an executable again for easier extraction
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex?.ResourceData == null)
return null;
// Get the resources that have an executable signature
var resources = pex.ResourceData
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
.Where(kvp => (kvp.Value as byte[]).StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
.Select(kvp => kvp.Value as byte[])
.Where(b => b != null && b.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
.ToList();
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
@@ -72,17 +77,19 @@ namespace BinaryObjectScanner.Packer
try
{
// Get the resource data
var resource = resources[i];
byte[] data = resource.Value as byte[];
var data = resources[i];
if (data == null)
continue;
// Create the temp filename
string tempFile = $"embedded_resource_{i}.bin";
tempFile = Path.Combine(tempPath, tempFile);
// Write the resource data to a temp file
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
using (var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
tempStream.Write(data, 0, data.Length);
if (tempStream != null)
tempStream.Write(data, 0, data.Length);
}
}
catch (Exception ex)

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class GenteeInstaller : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("Gentee installer")))

View File

@@ -13,17 +13,21 @@ namespace BinaryObjectScanner.Packer
public class HyperTechCrackProof : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// This check may be overly limiting, as it excludes the sample provided to DiE (https://github.com/horsicq/Detect-It-Easy/issues/102).
// TODO: Find further samples and invesitgate if the "peC" section is only present on specific versions.
bool peCSection = pex.ContainsSection("peC", exact: true);
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte.Name == "KeRnEl32.dLl") ?? false);
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "KeRnEl32.dLl") ?? false);
if (peCSection && importTableMatch)
return "HyperTech CrackProof";

View File

@@ -12,14 +12,14 @@ namespace BinaryObjectScanner.Packer
public class InnoSetup : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// Check for "Inno" in the reserved words
if (nex.Model.Stub?.Header?.Reserved2[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2[5] == 0x6F6E)
if (nex.Model.Stub?.Header?.Reserved2?[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2?[5] == 0x6F6E)
{
string version = GetOldVersion(file, nex);
if (!string.IsNullOrWhiteSpace(version))
@@ -32,18 +32,22 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
string str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
var str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
if (str != null)
{
return str.Replace("Inno Setup Setup Data", "Inno Setup")

View File

@@ -10,14 +10,18 @@ namespace BinaryObjectScanner.Packer
public class InstallAnywhere : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name= pex.FileDescription;
if (name?.StartsWith("InstallAnywhere Self Extractor", StringComparison.OrdinalIgnoreCase) == true)
return $"InstallAnywhere {GetVersion(pex)}";
@@ -57,7 +61,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the internal versions
string version = pex.GetInternalVersion();
var version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -12,15 +12,19 @@ namespace BinaryObjectScanner.Packer
{
//TODO: Add exact version detection for Windows builds, make sure versions before 3.X are detected as well, and detect the Mac builds.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("ViseMain")))

View File

@@ -9,14 +9,18 @@ namespace BinaryObjectScanner.Packer
public class IntelInstallationFramework : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name= pex.FileDescription;
if (name?.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true
|| name?.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true)
{

View File

@@ -12,14 +12,18 @@ namespace BinaryObjectScanner.Packer
public class MicrosoftCABSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.InternalName;
var name= pex.InternalName;
if (name?.Equals("Wextract", StringComparison.OrdinalIgnoreCase) == true)
return $"Microsoft CAB SFX {GetVersion(pex)}";
@@ -28,7 +32,7 @@ namespace BinaryObjectScanner.Packer
return $"Microsoft CAB SFX {GetVersion(pex)}";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("wextract_cleanup")))
@@ -77,7 +81,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the internal versions
string version = pex.GetInternalVersion();
var version = pex.GetInternalVersion();
if (!string.IsNullOrWhiteSpace(version))
return $"v{version}";

View File

@@ -10,19 +10,23 @@ namespace BinaryObjectScanner.Packer
public class NSIS : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string description = pex.AssemblyDescription;
var description = pex.AssemblyDescription;
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
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("NullsoftInst")))

View File

@@ -18,10 +18,14 @@ namespace BinaryObjectScanner.Packer
{
// TODO: Find samples of NeoLite 1.X.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class PECompact : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class PEtite : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class SetupFactory : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Known to detect versions 7.0.5.1 - 9.1.0.0
string name = pex.LegalCopyright;
var name = pex.LegalCopyright;
if (name?.StartsWith("Setup Engine", StringComparison.OrdinalIgnoreCase) == true)
return $"Setup Factory {GetVersion(pex)}";
@@ -67,7 +71,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the product version explicitly
string version = pex.ProductVersion;
var version = pex.ProductVersion;
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class SevenZipSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class Shrinker : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -17,17 +17,21 @@ namespace BinaryObjectScanner.Packer
private static readonly Regex _upxVersionMatch = new Regex(@"^([0-9]\.[0-9]{2})$", RegexOptions.Compiled);
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Check header padding strings
if (pex.HeaderPaddingStrings?.Any() == true)
{
string match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
var match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
//if (match != null)
// return "UPX";
@@ -42,7 +46,7 @@ namespace BinaryObjectScanner.Packer
}
match = pex.HeaderPaddingStrings.FirstOrDefault(s => _upxVersionMatch.IsMatch(s));
if (pex.HeaderPaddingStrings.Any(s => s == "UPX!" && match != null))
if (match != null && pex.HeaderPaddingStrings.Any(s => s == "UPX!"))
{
var regexMatch = _upxVersionMatch.Match(match);
if (regexMatch.Success)
@@ -50,7 +54,7 @@ namespace BinaryObjectScanner.Packer
else
return "UPX (Unknown Version)";
}
else if (pex.HeaderPaddingStrings.Any(s => s == "NOS " && match != null))
else if (match != null && pex.HeaderPaddingStrings.Any(s => s == "NOS "))
{
var regexMatch = _upxVersionMatch.Match(match);
if (regexMatch.Success)

View File

@@ -12,14 +12,18 @@ namespace BinaryObjectScanner.Packer
public class WinRARSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.AssemblyDescription;
var name = pex.AssemblyDescription;
if (name?.Contains("WinRAR archiver") == true)
return "WinRAR SFX";

View File

@@ -12,19 +12,19 @@ namespace BinaryObjectScanner.Packer
public class WinZipSFX : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// If the resident-name table doesnt exist
if (nex.Model.ResidentNameTable == null)
return null;
// Check for the WinZip name string
bool winZipNameFound = nex.Model.ResidentNameTable.Where(rnte => rnte?.NameString != null)
.Select(rnte => Encoding.ASCII.GetString(rnte.NameString))
bool winZipNameFound = nex.Model.ResidentNameTable
.Select(rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString))
.Any(s => s.Contains("WZ-SE-01"));
// If we didn't find it
@@ -32,7 +32,7 @@ namespace BinaryObjectScanner.Packer
return null;
// Try to get a known version
string version = GetNEHeaderVersion(nex);
var version = GetNEHeaderVersion(nex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
@@ -40,17 +40,21 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Check the export directory table, if it exists
if (pex.Model.ExportTable?.ExportDirectoryTable != null)
{
string version = GetPEExportDirectoryVersion(pex);
var version = GetPEExportDirectoryVersion(pex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
}
@@ -130,7 +134,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// TODO: Reduce the checks to only the ones that differ between versions
/// TODO: Research to see if the versions are embedded elsewhere in these files
#if NET48
private string GetNEHeaderVersion(NewExecutable nex)
#else
private string? GetNEHeaderVersion(NewExecutable nex)
#endif
{
#region 2.0 Variants
@@ -688,10 +696,14 @@ namespace BinaryObjectScanner.Packer
/// Get the version from the PE export directory table value combinations
/// </summary>
/// TODO: Research to see if the versions are embedded elsewhere in these files
#if NET48
private string GetPEExportDirectoryVersion(PortableExecutable pex)
#else
private string? GetPEExportDirectoryVersion(PortableExecutable pex)
#endif
{
string sfxFileName = pex.Model.ExportTable.ExportDirectoryTable.Name;
uint sfxTimeDateStamp = pex.Model.ExportTable.ExportDirectoryTable.TimeDateStamp;
string sfxFileName = pex.Model.ExportTable?.ExportDirectoryTable?.Name ?? string.Empty;
uint sfxTimeDateStamp = pex.Model.ExportTable?.ExportDirectoryTable?.TimeDateStamp ?? uint.MaxValue;
string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version";
// Standard

View File

@@ -14,12 +14,12 @@ namespace BinaryObjectScanner.Packer
public class WiseInstaller : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
/// Check we have a valid executable
if (nex == null)
return null;
// If we match a known header
if (MatchesNEVersion(nex) != null)
return "Wise Installation Wizard Module";
@@ -44,10 +44,14 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -58,7 +62,7 @@ namespace BinaryObjectScanner.Packer
// TODO: Investigate STUB32.EXE in export directory table
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("WiseMain")))
@@ -102,12 +106,12 @@ namespace BinaryObjectScanner.Packer
try
{
// Try to parse as a New Executable
NewExecutable nex = NewExecutable.Create(stream);
var nex = NewExecutable.Create(stream);
if (nex != null)
return ExtractNewExecutable(nex, file, includeDebug);
// Try to parse as a Portable Executable
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex != null)
return ExtractPortableExecutable(pex, file, includeDebug);
@@ -125,7 +129,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// <param name="nex">New executable to check</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private FormatProperty MatchesNEVersion(NewExecutable nex)
#else
private FormatProperty? MatchesNEVersion(NewExecutable nex)
#endif
{
// TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this.
switch (nex.Model.Stub?.Header?.NewExeHeaderAddr)
@@ -182,7 +190,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// <param name="pex">Portable executable to check</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private FormatProperty GetPEFormat(PortableExecutable pex)
#else
private FormatProperty? GetPEFormat(PortableExecutable pex)
#endif
{
if (pex.OverlayAddress == 0x6e00
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4
@@ -229,7 +241,11 @@ namespace BinaryObjectScanner.Packer
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private string ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
#else
private string? ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
#endif
{
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -268,7 +284,11 @@ namespace BinaryObjectScanner.Packer
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private string ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
#else
private string? ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
#endif
{
try
{
@@ -279,7 +299,7 @@ namespace BinaryObjectScanner.Packer
// Get the overlay data for easier reading
int overlayOffset = 0, dataStart = 0;
byte[] overlayData = pex.OverlayData;
var overlayData = pex.OverlayData;
if (overlayData == null)
return null;
@@ -333,8 +353,8 @@ namespace BinaryObjectScanner.Packer
int offsetReal = overlayOffset;
// If the first entry is PKZIP, we assume it's an embedded zipfile
byte[] magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
bool pkzip = magic.StartsWith(new byte?[] { (byte)'P', (byte)'K' });
var magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
bool pkzip = magic?.StartsWith(new byte?[] { (byte)'P', (byte)'K' }) ?? false;
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);

View File

@@ -10,15 +10,19 @@ namespace BinaryObjectScanner.Packer
public class dotFuscator : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .text section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".text");
var strs = pex.GetFirstSectionStrings(".text");
if (strs != null)
{
if (strs.Any(s => s.Contains("DotfuscatorAttribute")))

View File

@@ -11,7 +11,11 @@ namespace BinaryObjectScanner.Protection
public class ActiveMARK : IContentCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -34,10 +38,14 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -78,7 +86,7 @@ namespace BinaryObjectScanner.Protection
}
// Get the .data section strings, if they exist
List<string> strs = pex.GetLastSectionStrings(".data");
var strs = pex.GetLastSectionStrings(".data");
if (strs != null)
{
if (strs.Any(s => s.Contains("MPRMMGVA"))
@@ -92,8 +100,8 @@ namespace BinaryObjectScanner.Protection
var resources = pex.FindResourceByNamedType("REGISTRY, AMINTERNETPROTOCOL");
if (resources.Any())
{
bool match = resources.Where(r => r != null)
.Select(r => Encoding.ASCII.GetString(r))
bool match = resources
.Select(r => r == null ? string.Empty : Encoding.ASCII.GetString(r))
.Any(r => r.Contains("ActiveMARK"));
if (match)
return "ActiveMARK";

View File

@@ -20,10 +20,14 @@ namespace BinaryObjectScanner.Protection
public class AegiSoft : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -58,7 +62,7 @@ namespace BinaryObjectScanner.Protection
}, "AegiSoft License Manager"),
};
string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
@@ -84,7 +88,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -27,7 +27,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -44,18 +44,22 @@ namespace BinaryObjectScanner.Protection
public class AlphaROM : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
// TODO: Add version detection for Alpha-ROM.
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("\\SETTEC")))

View File

@@ -38,7 +38,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -41,15 +41,19 @@ namespace BinaryObjectScanner.Protection
public class ByteShield : IPortableExecutableCheck, IPathCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "LineRider2.exe" in Redump entry 6236
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Equals("ByteShield Client") == true)
return $"ByteShield Activation Client {pex.GetInternalVersion()}";
@@ -91,7 +95,7 @@ namespace BinaryObjectScanner.Protection
return "ByteShield";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in "LineRider2.exe" in Redump entry 6236
@@ -128,7 +132,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
@@ -144,7 +148,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#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.

View File

@@ -6,14 +6,18 @@ namespace BinaryObjectScanner.Protection
public class CDCheck : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.Comments;
var name = pex.Comments;
if (name?.Contains("CDCheck utlity for Microsoft Game Studios") == true)
return "Microsoft Game Studios CD Check";

View File

@@ -43,7 +43,11 @@ namespace BinaryObjectScanner.Protection
{
// TODO: Investigate reference to "CD32COPS.DLL" in "WETFLIPP.QZ_" in IA item "Triada_Russian_DVD_Complete_Collection_of_Erotic_Games".
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -73,12 +77,12 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// TODO: Don't read entire file
var data = nex.ReadArbitraryRange();
if (data == null)
@@ -96,7 +100,7 @@ namespace BinaryObjectScanner.Protection
}, GetVersion, "CD-Cops"),
};
string match = MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
var match = MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
if (!string.IsNullOrEmpty(match))
return match;
@@ -104,8 +108,7 @@ namespace BinaryObjectScanner.Protection
// Found in "h3blade.exe" in Redump entry 85077.
bool importedNameTableEntries = nex.Model.ImportedNameTable?
.Select(kvp => kvp.Value)
.Where(inte => inte.NameString != null)
.Select(inte => Encoding.ASCII.GetString(inte.NameString))
.Select(inte => inte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(inte.NameString))
.Any(s => s.Contains("CDCOPS")) ?? false;
if (importedNameTableEntries)
return "CD-Cops";
@@ -113,8 +116,7 @@ namespace BinaryObjectScanner.Protection
// Check the nonresident-name table
// Found in "CDCOPS.DLL" in Redump entry 85077.
bool nonresidentNameTableEntries = nex.Model.NonResidentNameTable?
.Where(nrnte => nrnte.NameString != null)
.Select(nrnte => Encoding.ASCII.GetString(nrnte.NameString))
.Select(nrnte => nrnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(nrnte.NameString))
.Any(s => s.Contains("CDcops assembly-language DLL")) ?? false;
if (nonresidentNameTableEntries)
return "CD-Cops";
@@ -123,10 +125,14 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -161,7 +167,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -24,10 +24,14 @@ namespace BinaryObjectScanner.Protection
public class CDGuard : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -46,7 +50,7 @@ namespace BinaryObjectScanner.Protection
if (pex.Model.ImportTable?.ImportDirectoryTable != null)
{
// Found in "Randevu.exe" in Redump entry 97142.
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte.Name?.Equals("cdguard.dll", StringComparison.OrdinalIgnoreCase) == true);
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name != null && idte.Name.Equals("cdguard.dll", StringComparison.OrdinalIgnoreCase));
if (match)
return "CD-Guard Copy Protection System";
}
@@ -67,7 +71,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -7,14 +7,18 @@ namespace BinaryObjectScanner.Protection
public class CDKey : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.InternalName;
var name = pex.InternalName;
if (name?.Equals("CDKey", StringComparison.OrdinalIgnoreCase) == true)
return "CD-Key / Serial";

View File

@@ -27,10 +27,14 @@ namespace BinaryObjectScanner.Protection
public class CDLock : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -52,7 +56,7 @@ namespace BinaryObjectScanner.Protection
}, "CD-Lock"),
};
string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
@@ -77,7 +81,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -39,7 +39,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -8,10 +8,14 @@ namespace BinaryObjectScanner.Protection
public class CDSHiELDSE : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -25,7 +29,7 @@ namespace BinaryObjectScanner.Protection
//}
// Get the code/CODE section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE");
if (strs != null)
{
if (strs.Any(s => s.Contains("~0017.tmp")))

View File

@@ -22,7 +22,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -8,7 +8,11 @@ namespace BinaryObjectScanner.Protection
public class CactusDataShield : IContentCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Limit these checks to Mac binaries
// TODO: Obtain a sample to find where this string is in a typical executable

View File

@@ -15,10 +15,14 @@ namespace BinaryObjectScanner.Protection
public class CengaProtectDVD : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -66,7 +70,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -23,21 +23,25 @@ namespace BinaryObjectScanner.Protection
public class ChosenBytesCodeLock : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "Code-Lock.ocx" in Code-Lock version 2.35.
// Also worth noting is the File Description for this file, which is "A future for you, a challenge for the rest.".
string name = pex.ProductName;
var name = pex.ProductName;
if (name?.StartsWith("Code-Lock", StringComparison.OrdinalIgnoreCase) == true)
return $"ChosenBytes Code-Lock {pex.ProductVersion}";
// Get the .text section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".text");
var strs = pex.GetFirstSectionStrings(".text");
if (strs != null)
{
if (strs.Any(s => s.Contains("CODE-LOCK.OCX")))
@@ -69,7 +73,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -8,7 +8,11 @@ namespace BinaryObjectScanner.Protection
public class CopyKiller : IContentCheck, IPathCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -43,7 +47,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#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

View File

@@ -23,17 +23,21 @@ namespace BinaryObjectScanner.Protection
public class CopyLok : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// If there are more than 2 icd-prefixed sections, then we have a match
// Though this is the same name that SafeDisc uses for protected executables, this seems to be a coincidence.
// Found in Redump entries 31557, 31674, 31675, 31708, 38239, 44210, and 53929.
int icdSectionCount = pex.SectionNames.Count(s => s.StartsWith("icd"));
int icdSectionCount = pex.SectionNames?.Count(s => s.StartsWith("icd")) ?? 0;
if (icdSectionCount >= 2)
return "CopyLok / CodeLok";

View File

@@ -10,10 +10,14 @@ namespace BinaryObjectScanner.Protection
public class CrypKey : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -21,7 +25,7 @@ namespace BinaryObjectScanner.Protection
string version = pex.GetVersionInfoString("CrypKey Version") ?? string.Empty;
// Found in 'cki32k.dll'
string name = pex.CompanyName;
var name = pex.CompanyName;
if (name?.StartsWith("CrypKey") == true)
return $"CrypKey {version}".TrimEnd();

View File

@@ -12,30 +12,40 @@ namespace BinaryObjectScanner.Protection
public class Cucko : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .text section, if it exists
if (!pex.ContainsSection(".text"))
return null;
var matchers = new List<ContentMatchSet>
if (pex.ContainsSection(".text"))
{
// 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?[]
var textData = pex.GetFirstSectionData(".text");
if (textData != null)
{
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,
0x54, 0x1E, 0x01, 0x0F
}, "Cucko (EA Custom)")
};
var matchers = new List<ContentMatchSet>
{
// 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?[]
{
0x8A, 0x55, 0x89, 0x38, 0x14, 0x1E, 0x0F, 0x85,
0x99, 0x00, 0x00, 0x00, 0x8A, 0x55, 0x8A, 0x38,
0x54, 0x1E, 0x01, 0x0F
}, "Cucko (EA Custom)")
};
return MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug);
return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug);
}
}
return null;
}
}
}

View File

@@ -19,7 +19,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -20,6 +20,9 @@ namespace BinaryObjectScanner.Protection
for (int i = 0; i < bupfiles.Length; i++)
{
FileInfo 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"));
if (bupfile.Length != ifofile.Length)
{
@@ -33,7 +36,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
return null;
}

View File

@@ -31,17 +31,21 @@ namespace BinaryObjectScanner.Protection
// https://www.pcgamingwiki.com/wiki/Denuvo#Redeem.exe
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// All current checks for Denuvo Anti-Cheat come from Doom Eternal Update 1 (Steam Depot 782332, Manifest 7064393210727378308).
// Found in "denuvo-anti-cheat.sys".
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Equals("Denuvo Anti-Cheat Driver", StringComparison.OrdinalIgnoreCase) == true)
return $"Denuvo Anti-Cheat";
@@ -157,7 +161,7 @@ namespace BinaryObjectScanner.Protection
// "Denuvo v3.0b (x64)"),
// };
// string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// return match;
@@ -223,7 +227,7 @@ namespace BinaryObjectScanner.Protection
// "Denuvo v2.0 (x86)"),
// };
// string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// return match;
@@ -253,7 +257,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
@@ -274,7 +278,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -42,7 +42,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -38,15 +38,19 @@ namespace BinaryObjectScanner.Protection
{
// TODO: Add checks for the game executables, which seem likely to contain some kind of indicators that can be checked for. The game executables all seem to import "Ord(1)" from one of the varying DLLs present.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "IOSLinksys.dll" (Redump entries 31914, 46743, 46961, 79284, and 79374).
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("IOSLinkNT", StringComparison.OrdinalIgnoreCase) == true)
return "DiscGuard";
@@ -75,58 +79,62 @@ namespace BinaryObjectScanner.Protection
// Get the .vbn section, if it exists
if (pex.ContainsSection(".vbn"))
{
var matchers = new List<ContentMatchSet>
var vbnData = pex.GetFirstSectionData(".vbn");
if (vbnData != null)
{
// 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?[]
var matchers = new List<ContentMatchSet>
{
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xF5, 0x6A, 0x6E, 0x35,
0x4D, 0x5A, 0x8B, 0xF4, 0x12, 0x15, 0x23, 0xC8, 0xE9, 0x80, 0x01, 0x10,
0xFE, 0xDB, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0xF5, 0x9A, 0x07, 0xE7,
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0x4B, 0x6C, 0xD2, 0x82,
0x0D, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x78, 0x1D, 0x69, 0x1E,
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
0xA4, 0x41, 0x81
}, GetVersion, "DiscGuard"),
// 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?[]
{
0x7B, 0x39, 0x8F, 0x07, 0x47, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xF5, 0x6A, 0x6E, 0x35,
0x4D, 0x5A, 0x8B, 0xF4, 0x12, 0x15, 0x23, 0xC8, 0xE9, 0x80, 0x01, 0x10,
0xFE, 0xDB, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0xF5, 0x9A, 0x07, 0xE7,
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0x4B, 0x6C, 0xD2, 0x82,
0x0D, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x78, 0x1D, 0x69, 0x1E,
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
0xA4, 0x41, 0x81
}, 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?[]
{
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xC6, 0xEB, 0x6E, 0x35,
0xED, 0xD0, 0x8B, 0xF4, 0x15, 0x12, 0x3D, 0xF3, 0x65, 0xF7, 0x01, 0x10,
0xF8, 0xFA, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0x41, 0x9A, 0x07, 0xE7,
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0xAF, 0x69, 0xD2, 0x82,
0x67, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x04, 0x19, 0x69, 0x1E,
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
0xA4, 0x41, 0x81, 0xAF, 0xB8, 0xCB, 0x46, 0xE3, 0xDA, 0x05, 0x36, 0xEA,
0x05, 0xF5, 0xB9, 0xCE, 0x5F, 0x9A, 0xF5, 0x7D, 0x9E, 0x64, 0x66, 0xF9,
0xA5, 0x7C, 0x4D, 0x1D, 0x1D, 0x95, 0x02, 0x52, 0x66, 0x23, 0xEF, 0xFF,
0xEC, 0x63, 0x11, 0xEB, 0xF6, 0x66, 0x8F, 0x2B, 0xCF, 0x07, 0x50, 0x18,
0xBE, 0x58, 0xCA, 0x08, 0x24, 0xAD, 0x81, 0x1A, 0xAB, 0x0E, 0x2D, 0x16,
0x38, 0xAB, 0x22, 0xB5, 0xA8, 0xF0, 0x7D, 0x2E, 0xAF, 0x5E, 0xEA, 0x02,
0x72, 0x20, 0x14, 0x19, 0x0E, 0x31, 0xF3, 0xD0, 0x40, 0xAE, 0xA2, 0xD5,
0x0A, 0xA7, 0xB7, 0xAE, 0x02, 0xCF, 0xAC, 0x5F, 0xB8, 0x03, 0x15, 0x80,
0x9A, 0x58, 0x5C, 0x03, 0x28, 0x31, 0x9E, 0xB8, 0x21, 0x5D, 0x07, 0xB3,
0xB9, 0xEC, 0x75, 0xBA, 0xC2, 0xC8, 0x9D, 0x6F, 0x7A, 0xA1, 0x00, 0x8A
}, 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?[]
{
0x7B, 0x39, 0x8F, 0x07, 0x45, 0xE9, 0x96, 0x8C, 0xCA, 0xB2, 0x5C, 0x50,
0xC7, 0x5A, 0x18, 0xBD, 0x75, 0xB5, 0x68, 0x6A, 0x78, 0xB5, 0xCF, 0xF2,
0xBE, 0xB3, 0xDB, 0xE9, 0x4E, 0x87, 0x8D, 0x46, 0x63, 0x0A, 0x54, 0xB8,
0x4F, 0x85, 0x60, 0x2C, 0x06, 0xEC, 0xBD, 0x75, 0xC6, 0xEB, 0x6E, 0x35,
0xED, 0xD0, 0x8B, 0xF4, 0x15, 0x12, 0x3D, 0xF3, 0x65, 0xF7, 0x01, 0x10,
0xF8, 0xFA, 0xC6, 0x70, 0x1D, 0xC1, 0x4D, 0xAE, 0x9E, 0xE1, 0x01, 0xAA,
0x9E, 0x50, 0x50, 0xC5, 0x66, 0x80, 0xC0, 0xA2, 0x2F, 0xA9, 0x7A, 0x3B,
0x48, 0x74, 0x9D, 0x17, 0x33, 0x5D, 0x4C, 0x84, 0xD9, 0x54, 0xC4, 0x08,
0xCC, 0x10, 0x2A, 0xF6, 0x91, 0x40, 0x51, 0xD3, 0x41, 0x9A, 0x07, 0xE7,
0xAB, 0xE9, 0x0B, 0xAD, 0xD4, 0x3A, 0xEC, 0xBA, 0xAF, 0x69, 0xD2, 0x82,
0x67, 0xF5, 0x49, 0x83, 0x8E, 0xAB, 0x85, 0x92, 0x04, 0x19, 0x69, 0x1E,
0x44, 0xC6, 0xF6, 0xB4, 0x5F, 0x5F, 0xC2, 0x48, 0x5A, 0xED, 0x43, 0xD3,
0xA4, 0x41, 0x81, 0xAF, 0xB8, 0xCB, 0x46, 0xE3, 0xDA, 0x05, 0x36, 0xEA,
0x05, 0xF5, 0xB9, 0xCE, 0x5F, 0x9A, 0xF5, 0x7D, 0x9E, 0x64, 0x66, 0xF9,
0xA5, 0x7C, 0x4D, 0x1D, 0x1D, 0x95, 0x02, 0x52, 0x66, 0x23, 0xEF, 0xFF,
0xEC, 0x63, 0x11, 0xEB, 0xF6, 0x66, 0x8F, 0x2B, 0xCF, 0x07, 0x50, 0x18,
0xBE, 0x58, 0xCA, 0x08, 0x24, 0xAD, 0x81, 0x1A, 0xAB, 0x0E, 0x2D, 0x16,
0x38, 0xAB, 0x22, 0xB5, 0xA8, 0xF0, 0x7D, 0x2E, 0xAF, 0x5E, 0xEA, 0x02,
0x72, 0x20, 0x14, 0x19, 0x0E, 0x31, 0xF3, 0xD0, 0x40, 0xAE, 0xA2, 0xD5,
0x0A, 0xA7, 0xB7, 0xAE, 0x02, 0xCF, 0xAC, 0x5F, 0xB8, 0x03, 0x15, 0x80,
0x9A, 0x58, 0x5C, 0x03, 0x28, 0x31, 0x9E, 0xB8, 0x21, 0x5D, 0x07, 0xB3,
0xB9, 0xEC, 0x75, 0xBA, 0xC2, 0xC8, 0x9D, 0x6F, 0x7A, 0xA1, 0x00, 0x8A
}, GetVersion, "DiscGuard"),
};
string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".vbn"), matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
}
return null;
@@ -163,7 +171,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -182,7 +194,11 @@ namespace BinaryObjectScanner.Protection
private string GetVersion(PortableExecutable pex)
{
// Check the internal versions
#if NET48
string version = pex.GetInternalVersion();
#else
string? version = pex.GetInternalVersion();
#endif
if (!string.IsNullOrEmpty(version))
return version;
@@ -193,7 +209,7 @@ namespace BinaryObjectScanner.Protection
private string GetVersion(string file, byte[] fileContent, List<int> positions)
{
// Check the internal versions
string version = GetInternalVersion(file, null);
string version = GetInternalVersion(file, Array.Empty<string>());
if (!string.IsNullOrEmpty(version))
return version;
@@ -207,7 +223,7 @@ namespace BinaryObjectScanner.Protection
using (Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var pex = PortableExecutable.Create(fileStream);
return pex.GetInternalVersion();
return pex?.GetInternalVersion() ?? string.Empty;
}
}
catch

View File

@@ -22,14 +22,18 @@ namespace BinaryObjectScanner.Protection
{
// TODO: Add support for detecting older versions, especially versions made before Easy Anti-Cheat was purchased by Epic Games.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
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)"))
return "Easy Anti-Cheat (EOS Version)";
@@ -127,7 +131,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#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>

View File

@@ -9,14 +9,18 @@ namespace BinaryObjectScanner.Protection
public class ElectronicArts : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Contains("EReg MFC Application") == true)
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
else if (name?.Contains("Registration code installer program") == true)
@@ -31,10 +35,10 @@ namespace BinaryObjectScanner.Protection
if (pex.FindDialogByTitle("About CDKey").Any())
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
else if (pex.FindGenericResource("About CDKey").Any())
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
return $"EA CdKey Registration Module {pex.GetInternalVersion()}";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("EReg Config Form")))

View File

@@ -16,10 +16,14 @@ namespace BinaryObjectScanner.Protection
public class Engine32 : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -28,8 +32,8 @@ namespace BinaryObjectScanner.Protection
// Detects Engine32 within the game executables that contain it.
if (pex.Model.ImportTable?.ImportDirectoryTable != null && pex.Model.ImportTable?.HintNameTable != null)
{
bool importDirectoryTableMatch = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte.Name?.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase) == true);
bool hintNameTableMatch = pex.Model.ImportTable?.HintNameTable.Any(ihne => ihne.Name == "InitEngine") ?? false;
bool importDirectoryTableMatch = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name != null && idte.Name.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase));
bool hintNameTableMatch = pex.Model.ImportTable?.HintNameTable.Any(ihne => ihne?.Name == "InitEngine") ?? false;
// The Hint/Name Table Entry "DeinitEngine" is present in every tested sample, aside from TOCA Race Driver 2 (Redump entries 104593-104596).
@@ -62,7 +66,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -52,7 +52,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -11,14 +11,18 @@ namespace BurnOutSharp.ProtectionType
public class GFWL : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("Games for Windows - LIVE Zero Day Piracy Protection", StringComparison.OrdinalIgnoreCase) == true)
return $"Games for Windows LIVE - Zero Day Piracy Protection Module {pex.GetInternalVersion()}";
else if (name?.StartsWith("Games for Windows", StringComparison.OrdinalIgnoreCase) == true)
@@ -27,7 +31,7 @@ namespace BurnOutSharp.ProtectionType
// Get the import directory table
if (pex.Model.ImportTable?.ImportDirectoryTable != null)
{
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte.Name == "xlive.dll");
bool match = pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name == "xlive.dll");
if (match)
return "Games for Windows LIVE";
}
@@ -50,7 +54,11 @@ namespace BurnOutSharp.ProtectionType
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -20,17 +20,25 @@ namespace BinaryObjectScanner.Protection
public class Gefest : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the header padding strings, if it exists
if (pex.HeaderPaddingStrings != null)
{
#if NET48
string match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("Gefest Protection System"));
#else
string? match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("Gefest Protection System"));
#endif
if (match != null)
return $"Gefest Protection System {GetVersion(match)}";
}
@@ -50,7 +58,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -33,16 +33,20 @@ namespace BinaryObjectScanner.Protection
public class HexalockAutoLock : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// TODO: Fix the following checks, as this information is visible via Windows Explorer but isn't currently being seen by BOS.
// Found in "HCPSMng.exe".
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("HCPS Manager", StringComparison.OrdinalIgnoreCase) == true)
return $"Hexalock AutoLock 4.5";
@@ -56,7 +60,7 @@ namespace BinaryObjectScanner.Protection
return $"Hexalock AutoLock 4.5";
// Get the .text section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".text");
var strs = pex.GetFirstSectionStrings(".text");
if (strs != null)
{
// Found in "The Sudoku Challenge Collection.exe" in "The Sudoku Challenge! Collection" by Play at Joe's.
@@ -103,7 +107,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -13,14 +13,18 @@ namespace BinaryObjectScanner.Protection
public class ImpulseReactor : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Contains("ImpulseReactor Dynamic Link Library") == true)
return $"Impulse Reactor Core Module {pex.GetInternalVersion()}";
@@ -37,7 +41,7 @@ namespace BinaryObjectScanner.Protection
bool containsCheck2 = false;
// Get the .rdata section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".rdata");
var strs = pex.GetFirstSectionStrings(".rdata");
if (strs != null)
{
containsCheck2 = strs.Any(s => s.EndsWith("ATTLIST"))
@@ -66,7 +70,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -84,7 +92,7 @@ namespace BinaryObjectScanner.Protection
using (Stream fileStream = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var pex = PortableExecutable.Create(fileStream);
return pex.GetInternalVersion();
return pex?.GetInternalVersion() ?? string.Empty;
}
}
catch

View File

@@ -25,7 +25,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -23,10 +23,14 @@ namespace BinaryObjectScanner.Protection
*/
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -13,23 +13,30 @@ namespace BinaryObjectScanner.Protection
public class JoWood : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .ext section, if it exists
if (pex.ContainsSection(".ext ", exact: true))
{
bool importTableMatches = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte.Name == "kernel32.dll") ?? false)
&& (pex.Model.ImportTable?.HintNameTable?.Any(s => s.Name == "VirtualProtect") ?? false);
bool importTableMatches = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "kernel32.dll") ?? false)
&& (pex.Model.ImportTable?.HintNameTable?.Any(s => s?.Name == "VirtualProtect") ?? false);
// Get the .dcrtext section, if it exists
if (pex.ContainsSection(".dcrtext") && importTableMatches)
{
var matchers = new List<ContentMatchSet>
var dcrtextData = pex.GetFirstSectionData(".dcrtext");
if (dcrtextData != null)
{
var matchers = new List<ContentMatchSet>
{
// kernel32.dll + (char)0x00 + (char)0x00 + (char)0x00 + VirtualProtect
new ContentMatchSet(new byte?[]
@@ -41,9 +48,10 @@ namespace BinaryObjectScanner.Protection
}, GetVersion, "JoWood X-Prot"),
};
string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".dcrtext"), matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
var match = MatchUtil.GetFirstMatch(file, dcrtextData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
}
return "JoWood X-Prot v1.0-v1.3";

View File

@@ -7,7 +7,11 @@ namespace BinaryObjectScanner.Protection
public class KeyLock : IContentCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)

View File

@@ -20,15 +20,19 @@ namespace BinaryObjectScanner.Protection
public class LabelGate : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Should be present on all LabelGate CD2 discs (Redump entry 95010 and product ID SVWC-7185).
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("MAGIQLIP2 Installer", StringComparison.OrdinalIgnoreCase) == true)
return $"LabelGate CD2 Media Player";
@@ -37,7 +41,7 @@ namespace BinaryObjectScanner.Protection
return $"LabelGate CD2 Media Player";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in "START.EXE" (Redump entry 95010 and product ID SVWC-7185).
@@ -73,7 +77,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -12,7 +12,11 @@ namespace BinaryObjectScanner.Protection
public class LaserLok : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// TODO: Add entry point check
// https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Laserlok.2.sg
@@ -49,7 +53,7 @@ namespace BinaryObjectScanner.Protection
// }, "LaserLok 5"),
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -64,13 +68,14 @@ namespace BinaryObjectScanner.Protection
0x2E, 0x50, 0x45
};
int endDosStub = (int)(pex.Model.Stub?.Header?.NewExeHeaderAddr ?? 0);
bool containsCheck = pex.StubExecutableData.FirstPosition(check, out int position);
int position = -1;
bool containsCheck = pex.StubExecutableData?.FirstPosition(check, out position) ?? false;
// Check the executable tables
bool containsCheck2 = (pex.Model.ImportTable?.HintNameTable.Any(hnte => hnte.Name == "GetModuleHandleA") ?? false)
&& (pex.Model.ImportTable?.HintNameTable.Any(hnte => hnte.Name == "GetProcAddress") ?? false)
&& (pex.Model.ImportTable?.HintNameTable.Any(hnte => hnte.Name == "LoadLibraryA") ?? false)
&& (pex.Model.ImportTable?.ImportDirectoryTable.Any(idte => idte.Name == "KERNEL32.dll") ?? false);
bool containsCheck2 = (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "GetModuleHandleA") ?? false)
&& (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "GetProcAddress") ?? false)
&& (pex.Model.ImportTable?.HintNameTable?.Any(hnte => hnte?.Name == "LoadLibraryA") ?? false)
&& (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "KERNEL32.dll") ?? false);
int position2 = -1;
@@ -90,7 +95,7 @@ namespace BinaryObjectScanner.Protection
0x45, 0x4C, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C,
0x00, 0xEB, 0x79, 0x01, null, null, null, null,
};
containsCheck2 = pex.GetFirstSectionData(".text").FirstPosition(check2, out position2);
containsCheck2 = pex.GetFirstSectionData(".text")?.FirstPosition(check2, out position2) ?? false;
}
else
{
@@ -131,7 +136,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -150,7 +159,11 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
#if NET48
private static string GetBuild(byte[] sectionContent, bool versionTwo)
#else
private static string GetBuild(byte[]? sectionContent, bool versionTwo)
#endif
{
if (sectionContent == null)
return "(Build unknown)";
@@ -187,7 +200,11 @@ namespace BinaryObjectScanner.Protection
return $"(Build {year}-{month}-{day})";
}
#if NET48
private static string GetVersion(byte[] sectionContent, int position)
#else
private static string? GetVersion(byte[]? sectionContent, int position)
#endif
{
// If we have invalid data
if (sectionContent == null)

View File

@@ -8,14 +8,18 @@ namespace BinaryObjectScanner.Protection
public class MGIRegistration : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.ProductName;
var name = pex.ProductName;
// Found in "Register.dll" in IA item "MGIPhotoSuite4.0AndPhotoVista2.02001".
if (name?.Equals("MGI Registration Utility", StringComparison.Ordinal) == true)

View File

@@ -34,13 +34,13 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.INewExecutableCheck.CheckNewExecutable(string, NewExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.INewExecutableCheck.CheckNewExecutable(string, NewExecutable, bool)"/>
#if NET48
internal string CDillaCheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
internal string? CDillaCheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// TODO: Implement NE checks for "CDILLA05", "CDILLA10", "CDILLA16", and "CDILLA40".
// TODO: Implement the following NE checks:
@@ -64,15 +64,19 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string CDillaCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
#else
internal string? CDillaCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
// Found in in "cdilla52.dll" from C-Dilla LMS version 3.24.010.
if (name?.Equals("32-bit C-Dilla DLL", StringComparison.OrdinalIgnoreCase) == true)
@@ -138,7 +142,7 @@ namespace BinaryObjectScanner.Protection
return $"C-Dilla License Management System";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in "DJMixStation\DJMixStation.exe" in IA item "ejay_nestle_trial".
@@ -151,7 +155,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
internal ConcurrentQueue<string> CDillaCheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
@@ -194,8 +198,12 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckFilePath(string)"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string CDillaCheckFilePath(string path)
#else
internal string? CDillaCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -30,16 +30,20 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string CactusDataShieldCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? CactusDataShieldCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("\\*.CDS")))
@@ -52,18 +56,18 @@ 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.
var resources = pex.FindGenericResource("CactusPJ");
if (resources.Any())
if (resources != null && resources.Any())
return "PlayJ Music Player (Cactus Data Shield 200)";
// Found in various files in "Les Paul & Friends" (Barcode 4 98806 834170).
string name = pex.ProductName;
var name = pex.ProductName;
if (name?.Equals("CDS300", StringComparison.OrdinalIgnoreCase) == true)
return $"Cactus Data Shield 300";
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
internal ConcurrentQueue<string> CactusDataShieldCheckDirectoryPath(string path, IEnumerable<string> files)
{
// TODO: Verify if these are OR or AND
@@ -90,8 +94,12 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckFilePath(string)"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string CactusDataShieldCheckFilePath(string path)
#else
internal string? CactusDataShieldCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -119,10 +127,18 @@ namespace BinaryObjectScanner.Protection
public static string GetCactusDataShieldVersion(string firstMatchedString, IEnumerable<string> files)
{
// Find the version.txt file first
#if NET48
string versionPath = files.FirstOrDefault(f => Path.GetFileName(f).Equals("version.txt", StringComparison.OrdinalIgnoreCase));
#else
string? versionPath = files.FirstOrDefault(f => Path.GetFileName(f).Equals("version.txt", StringComparison.OrdinalIgnoreCase));
#endif
if (!string.IsNullOrWhiteSpace(versionPath))
{
#if NET48
string version = GetCactusDataShieldInternalVersion(versionPath);
#else
string? version = GetCactusDataShieldInternalVersion(versionPath);
#endif
if (!string.IsNullOrWhiteSpace(version))
return version;
}
@@ -130,7 +146,11 @@ namespace BinaryObjectScanner.Protection
return "200";
}
#if NET48
private static string GetCactusDataShieldInternalVersion(string path)
#else
private static string? GetCactusDataShieldInternalVersion(string path)
#endif
{
if (!File.Exists(path))
return null;
@@ -139,7 +159,15 @@ namespace BinaryObjectScanner.Protection
{
using (var sr = new StreamReader(path, Encoding.Default))
{
return $"{sr.ReadLine().Substring(3)} ({sr.ReadLine()})";
#if NET48
string line = sr.ReadLine();
#else
string? line = sr.ReadLine();
#endif
if (line == null)
return null;
return $"{line.Substring(3)} ({sr.ReadLine()})";
}
}
catch

View File

@@ -8,16 +8,20 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string FLEXnetCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? FLEXnetCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "IsSvcInstDanceEJay7.dll" in IA item "computer200709dvd" (Dance eJay 7).
string name = pex.ProductName;
var name = pex.ProductName;
if (name?.Equals("FLEXnet Activation Toolkit", StringComparison.OrdinalIgnoreCase) == true)
return $"FLEXnet";

View File

@@ -18,16 +18,20 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string RipGuardCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? RipGuardCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "RGASDEV.SYS" in the Black Lagoon Season 1 DVD Steelbook box set (Geneon ID 12970).
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Equals("rgasdev", StringComparison.OrdinalIgnoreCase) == true)
return "RipGuard";
@@ -45,7 +49,11 @@ namespace BinaryObjectScanner.Protection
// So far, every seemingly-randomly named EXE on RipGuard discs have a consistent hash.
if (fi.Length == 49_152)
{
#if NET48
string sha1 = GetFileSHA1(file);
#else
string? sha1 = GetFileSHA1(file);
#endif
if (sha1 == "6A7B8545800E0AB252773A8CD0A2185CA2497938")
return "RipGuard";
}
@@ -58,7 +66,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
internal ConcurrentQueue<string> RipGuardCheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
@@ -74,8 +82,12 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckFilePath(string)"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string RipGuardCheckFilePath(string path)
#else
internal string? RipGuardCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -37,20 +37,23 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.INewExecutableCheck.CheckNewExecutable(string, NewExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.INewExecutableCheck.CheckNewExecutable(string, NewExecutable, bool)"/>
#if NET48
internal string SafeCastCheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
internal string? SafeCastCheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable.
if (nex == null)
return null;
// Check for the CDAC01AA name string.
bool cdac01aaNameFound = nex.Model.ResidentNameTable.Where(rnte => rnte?.NameString != null)
.Select(rnte => Encoding.ASCII.GetString(rnte.NameString))
if (nex.Model.ResidentNameTable != null)
{
bool cdac01aaNameFound = nex.Model.ResidentNameTable
.Select(rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString))
.Any(s => s.Contains("CDAC01AA"));
if (cdac01aaNameFound)
return "SafeCast";
if (cdac01aaNameFound)
return "SafeCast";
}
// TODO: Don't read entire file
var data = nex.ReadArbitraryRange();
@@ -61,17 +64,21 @@ 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 ContentMatchSet(new byte?[] { 0x53, 0x61, 0x66, 0x65, 0x43, 0x61, 0x73, 0x74 }, "SafeCast"),
};
return MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string SafeCastCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? SafeCastCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -81,7 +88,7 @@ namespace BinaryObjectScanner.Protection
// Get the import directory table, if it exists
if (pex.Model.ImportTable?.ImportDirectoryTable != null)
{
if (pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte.Name?.Equals("CdaC14BA.dll", StringComparison.OrdinalIgnoreCase) == true))
if (pex.Model.ImportTable.ImportDirectoryTable.Any(idte => idte?.Name != null && idte.Name.Equals("CdaC14BA.dll", StringComparison.OrdinalIgnoreCase)))
return "SafeCast";
}
@@ -92,7 +99,7 @@ namespace BinaryObjectScanner.Protection
return "SafeCast";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in "DJMixStation\DJMixStation.exe" in IA item "ejay_nestle_trial".
@@ -101,7 +108,7 @@ namespace BinaryObjectScanner.Protection
}
// Found in "32bit\Tax02\cdac14ba.dll" in IA item "TurboTax Deluxe Tax Year 2002 for Wndows (2.00R)(Intuit)(2002)(352282)".
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Equals("SafeCast2", StringComparison.OrdinalIgnoreCase) == true)
return "SafeCast";
@@ -144,7 +151,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
internal ConcurrentQueue<string> SafeCastCheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
@@ -187,8 +194,12 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckFilePath(string)"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string SafeCastCheckFilePath(string path)
#else
internal string? SafeCastCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -41,26 +41,30 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string SafeDiscCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? SafeDiscCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in Redump entry 57986.
bool hintNameTableMatch = pex.Model.ImportTable?.HintNameTable?.Any(ihne => ihne.Name == "LTDLL_Authenticate") ?? false;
bool hintNameTableMatch = pex.Model.ImportTable?.HintNameTable?.Any(ihne => ihne?.Name == "LTDLL_Authenticate") ?? false;
if (hintNameTableMatch)
return "SafeDisc Lite";
// Found in Redump entry 57986.
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte.Name == "ltdll.dll") ?? false);
bool importTableMatch = pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "ltdll.dll") ?? false;
if (importTableMatch)
return "SafeDisc Lite";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in Redump entries 14928, 25579, 32751.
@@ -72,7 +76,7 @@ namespace BinaryObjectScanner.Protection
return "SafeDisc Lite";
}
string name = pex.FileDescription;
var name = pex.FileDescription;
// Present in "Diag.exe" files from SafeDisc 4.50.000+.
if (name?.Equals("SafeDisc SRV Tool APP", StringComparison.OrdinalIgnoreCase) == true)
return $"SafeDisc SRV Tool APP {GetSafeDiscDiagExecutableVersion(pex)}";
@@ -109,7 +113,7 @@ namespace BinaryObjectScanner.Protection
return null;
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckDirectoryPath(string, IEnumerable{string})"/>
internal ConcurrentQueue<string> SafeDiscCheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
@@ -217,8 +221,12 @@ namespace BinaryObjectScanner.Protection
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPathCheck.CheckFilePath(string)"/>
/// <inheritdoc cref="Interfaces.IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string SafeDiscCheckFilePath(string path)
#else
internal string? SafeDiscCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -300,7 +308,11 @@ namespace BinaryObjectScanner.Protection
return string.Empty;
// 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.
#if NET48
string sha1 = GetFileSHA1(firstMatchedString);
#else
string? sha1 = GetFileSHA1(firstMatchedString);
#endif
switch (sha1)
{
// Found in Redump entries 61731 and 66005.
@@ -324,7 +336,11 @@ namespace BinaryObjectScanner.Protection
return string.Empty;
// 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.
#if NET48
string sha1 = GetFileSHA1(firstMatchedString);
#else
string? sha1 = GetFileSHA1(firstMatchedString);
#endif
switch (sha1)
{
// Found in Redump entry 66005.
@@ -424,7 +440,11 @@ namespace BinaryObjectScanner.Protection
// The hash of every "CLOKSPL.EXE" correlates directly to a specific SafeDisc version.
#if NET48
string sha1 = GetFileSHA1(firstMatchedString);
#else
string? sha1 = GetFileSHA1(firstMatchedString);
#endif
switch (sha1)
{
// Found in Redump entry 66005.
@@ -572,7 +592,11 @@ namespace BinaryObjectScanner.Protection
// There are occasionaly inconsistencies, even within the well detected version range. This seems to me to mostly happen with later (3.20+) games, and seems to me to be an example of the SafeDisc distribution becoming more disorganized with time.
// 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.
#if NET48
string sha1 = GetFileSHA1(firstMatchedString);
#else
string? sha1 = GetFileSHA1(firstMatchedString);
#endif
switch (sha1)
{
// Found in Redump entry 102979.
@@ -721,7 +745,11 @@ namespace BinaryObjectScanner.Protection
}
}
#if NET48
private string GetVersionFromSHA1Hash(string sha1Hash)
#else
private string? GetVersionFromSHA1Hash(string sha1Hash)
#endif
{
switch (sha1Hash.ToLowerInvariant())
{
@@ -772,7 +800,11 @@ namespace BinaryObjectScanner.Protection
private string GetSafeDiscDiagExecutableVersion(PortableExecutable pex)
{
// Different versions of this executable correspond to different SafeDisc versions.
#if NET48
string version = pex.FileVersion;
#else
string? version = pex.FileVersion;
#endif
if (!string.IsNullOrEmpty(version))
{
switch (version)

View File

@@ -34,8 +34,12 @@ namespace BinaryObjectScanner.Protection
/// </summary>
public partial class Macrovision
{
/// <inheritdoc cref="BinaryObjectScanner.Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
/// <inheritdoc cref="Interfaces.IPortableExecutableCheck.CheckPortableExecutable(string, PortableExecutable, bool)"/>
#if NET48
internal string SafeWrapCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
internal string? SafeWrapCheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// TODO: Figure out what SafeWrap is exactly, and add checks.

View File

@@ -21,21 +21,29 @@ namespace BinaryObjectScanner.Protection
public partial class Macrovision : IPathCheck, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
List<string> resultsList = new List<string>();
var resultsList = new List<string>();
// Run C-Dilla NE checks
#if NET48
string cDilla = CDillaCheckNewExecutable(file, nex, includeDebug);
#else
string? cDilla = CDillaCheckNewExecutable(file, nex, includeDebug);
#endif
if (!string.IsNullOrWhiteSpace(cDilla))
resultsList.Add(cDilla);
// Run SafeCast NE checks
#if NET48
string safeCast = SafeCastCheckNewExecutable(file, nex, includeDebug);
#else
string? safeCast = SafeCastCheckNewExecutable(file, nex, includeDebug);
#endif
if (!string.IsNullOrWhiteSpace(safeCast))
resultsList.Add(safeCast);
@@ -46,18 +54,22 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Check for specific indications for individual Macrovision protections.
List<string> resultsList = new List<string>();
var resultsList = new List<string>();
// Check for generic indications of Macrovision protections first.
string name = pex.FileDescription;
var name = pex.FileDescription;
// Present in "secdrv.sys" files found in SafeDisc 2.80.010+.
if (name?.Equals("Macrovision SECURITY Driver", StringComparison.OrdinalIgnoreCase) == true)
@@ -76,7 +88,11 @@ namespace BinaryObjectScanner.Protection
if (stxt371Section || stxt774Section)
{
// Check the header padding for protected sections.
#if NET48
string sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, true);
#else
string? sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, true);
#endif
if (!string.IsNullOrWhiteSpace(sectionMatch))
{
resultsList.Add(sectionMatch);
@@ -90,7 +106,11 @@ namespace BinaryObjectScanner.Protection
}
int entryPointIndex = pex.FindEntryPointSectionIndex();
#if NET48
string entryPointSectionName = pex.SectionNames[entryPointIndex];
#else
string? entryPointSectionName = pex.SectionNames?[entryPointIndex];
#endif
switch (entryPointSectionName)
{
@@ -113,7 +133,11 @@ namespace BinaryObjectScanner.Protection
else
{
// Check the header padding for protected sections.
#if NET48
string sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, false);
#else
string? sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, false);
#endif
if (!string.IsNullOrWhiteSpace(sectionMatch))
{
resultsList.Add(sectionMatch);
@@ -128,7 +152,11 @@ namespace BinaryObjectScanner.Protection
}
// Run Cactus Data Shield PE checks
#if NET48
string match = CactusDataShieldCheckPortableExecutable(file, pex, includeDebug);
#else
string? match = CactusDataShieldCheckPortableExecutable(file, pex, includeDebug);
#endif
if (!string.IsNullOrWhiteSpace(match))
resultsList.Add(match);
@@ -168,7 +196,7 @@ namespace BinaryObjectScanner.Protection
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
ConcurrentQueue<string> results = new ConcurrentQueue<string>();
var results = new ConcurrentQueue<string>();
// Run Macrovision directory checks
var macrovision = MacrovisionCheckDirectoryPath(path, files);
@@ -203,41 +231,69 @@ namespace BinaryObjectScanner.Protection
if (results != null && results.Count > 0)
return results;
return null;
return new ConcurrentQueue<string>();
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
List<string> resultsList = new List<string>();
// Run Macrovision file checks
#if NET48
string macrovision = MacrovisionCheckFilePath(path);
#else
string? macrovision = MacrovisionCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(macrovision))
resultsList.Add(macrovision);
// Run Cactus Data Shield file checks
#if NET48
string cactusDataShield = CactusDataShieldCheckFilePath(path);
#else
string? cactusDataShield = CactusDataShieldCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(cactusDataShield))
resultsList.Add(cactusDataShield);
// Run C-Dilla file checks
#if NET48
string cDilla = CDillaCheckFilePath(path);
#else
string? cDilla = CDillaCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(cDilla))
resultsList.Add(cDilla);
// Run RipGuard file checks
#if NET48
string ripGuard = RipGuardCheckFilePath(path);
#else
string? ripGuard = RipGuardCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(ripGuard))
resultsList.Add(ripGuard);
// Run SafeCast file checks
#if NET48
string safeCast = SafeCastCheckFilePath(path);
#else
string? safeCast = SafeCastCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(safeCast))
resultsList.Add(safeCast);
// Run SafeDisc file checks
#if NET48
string safeDisc = SafeDiscCheckFilePath(path);
#else
string? safeDisc = SafeDiscCheckFilePath(path);
#endif
if (!string.IsNullOrWhiteSpace(safeDisc))
resultsList.Add(safeDisc);
@@ -260,7 +316,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc cref="IPathCheck.CheckFilePath(string)"/>
#if NET48
internal string MacrovisionCheckFilePath(string path)
#else
internal string? MacrovisionCheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -377,7 +437,11 @@ namespace BinaryObjectScanner.Protection
{
// Different versions of this driver correspond to different SafeDisc versions.
// TODO: Check if earlier versions of this driver contain the version string in a less obvious place.
#if NET48
string version = pex.FileVersion;
#else
string? version = pex.FileVersion;
#endif
if (!string.IsNullOrEmpty(version))
{
switch (version)
@@ -415,33 +479,43 @@ namespace BinaryObjectScanner.Protection
return "Unknown Version (Report this to us on GitHub)";
}
#if NET48
private string CheckSectionForProtection(string file, bool includeDebug, List<string> sectionStrings, byte[] sectionRaw, bool newVersion)
#else
private string? CheckSectionForProtection(string file, bool includeDebug, List<string>? sectionStrings, byte[]? sectionRaw, bool newVersion)
#endif
{
// Get the section strings, if they exist
if (sectionStrings == null)
return null;
// If we don't have the "BoG_" string, the section isn't protected.
if (!sectionStrings.Any(s => s.Contains("BoG_")))
return null;
// If we have the "BoG_" string but not the full "BoG_ *90.0&!! Yy>" string, the section has had the portion of the section that included the version number removed or obfuscated (Redump entry 40337).
if (!sectionStrings.Any(s => s.Contains("BoG_ *90.0&!! Yy>")))
return newVersion ? "Macrovision Protected Application [Version Expunged]" : null;
// TODO: Add more checks to help differentiate between SafeDisc and SafeCast.
var matchers = new List<ContentMatchSet>
if (sectionStrings != null)
{
// BoG_ *90.0&!! Yy>
new ContentMatchSet(new byte?[]
{
0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30,
0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59,
0x79, 0x3E
}, GetMacrovisionVersion, string.Empty),
};
// If we don't have the "BoG_" string, the section isn't protected.
if (!sectionStrings.Any(s => s.Contains("BoG_")))
return null;
return MatchUtil.GetFirstMatch(file, sectionRaw, matchers, includeDebug);
// If we have the "BoG_" string but not the full "BoG_ *90.0&!! Yy>" string, the section has had the portion of the section that included the version number removed or obfuscated (Redump entry 40337).
if (!sectionStrings.Any(s => s.Contains("BoG_ *90.0&!! Yy>")))
return newVersion ? "Macrovision Protected Application [Version Expunged]" : null;
}
// Get the section data, if it exists
if (sectionRaw != null)
{
// TODO: Add more checks to help differentiate between SafeDisc and SafeCast.
var matchers = new List<ContentMatchSet>
{
// BoG_ *90.0&!! Yy>
new ContentMatchSet(new byte?[]
{
0x42, 0x6F, 0x47, 0x5F, 0x20, 0x2A, 0x39, 0x30,
0x2E, 0x30, 0x26, 0x21, 0x21, 0x20, 0x20, 0x59,
0x79, 0x3E
}, GetMacrovisionVersion, string.Empty),
};
return MatchUtil.GetFirstMatch(file, sectionRaw, matchers, includeDebug);
}
return null;
}
internal static string GetMacrovisionVersion(string file, byte[] fileContent, List<int> positions)
@@ -573,7 +647,11 @@ namespace BinaryObjectScanner.Protection
}
}
#if NET48
private List<string> CleanResultList(List<string> resultsList)
#else
private List<string>? CleanResultList(List<string>? resultsList)
#endif
{
// If we have an invalid result list
if (resultsList == null || resultsList.Count == 0)

View File

@@ -16,15 +16,19 @@ namespace BinaryObjectScanner.Protection
// TODO: "Karaoke Spotlight Series - Pop Hits - Vol. 132" - Sound Choice (SC8732)" is currently undetected, due to there seeming to be no reference to MediaCloQ in the disc's contents.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in scvfy.exe on "Charley Pride - A Tribute to Jim Reeves" (barcode "7 816190222-2 4").
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("scvfy MFC Application", StringComparison.OrdinalIgnoreCase) == true)
return $"MediaCloQ";
@@ -51,7 +55,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -17,15 +17,19 @@ namespace BinaryObjectScanner.Protection
public class MediaMaxCD3 : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Used to detect "LicGen.exe", found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6)
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("LicGen Module", StringComparison.OrdinalIgnoreCase) == true)
return $"MediaMax CD-3";
@@ -36,7 +40,7 @@ namespace BinaryObjectScanner.Protection
var cd3CtrlResources = pex.FindGenericResource("Cd3Ctl");
if (cd3CtrlResources.Any())
return $"MediaMax CD-3";
var limitedProductionResources = pex.FindDialogBoxByItemTitle("This limited production advanced CD is not playable on your computer. It is solely intended for playback on standard CD players.");
if (limitedProductionResources.Any())
return $"MediaMax CD-3";
@@ -45,7 +49,7 @@ namespace BinaryObjectScanner.Protection
// "This limited production advanced CD is not playable on your computer. It is solely intended for playback on standard CD players."
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("CD3 Launch Error")))
@@ -90,7 +94,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -22,11 +22,15 @@ namespace BinaryObjectScanner.Protection
public class NEACProtect : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Most of the relevant executables are highly obfuscated, making executable detection mostly impractical.
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -39,7 +43,7 @@ namespace BinaryObjectScanner.Protection
if (neac0Section || neac1Section)
return "NEAC Protect";
string name = pex.ProductName;
var name = pex.ProductName;
// Found in "NeacSafe64.sys" and "NeacSafe.sys".
// TODO: Fix Product Name not being properly grabbed from the file.
@@ -69,7 +73,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -7,15 +7,19 @@ namespace BurnOutSharp.ProtectionType
public class OnlineRegistration : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// TODO: Is this too broad in general?
string name = pex.InternalName;
var name = pex.InternalName;
if (name?.StartsWith("EReg", StringComparison.OrdinalIgnoreCase) == true)
return $"Executable-Based Online Registration {pex.GetInternalVersion()}";

View File

@@ -17,15 +17,19 @@ namespace BinaryObjectScanner.Protection
public class OpenMG : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in many different OpenMG related files ("Touch" by Amerie).
string name = pex.LegalTrademarks;
var name = pex.LegalTrademarks;
if (name?.StartsWith("OpenMG", StringComparison.OrdinalIgnoreCase) == true)
return $"OpenMG";
@@ -91,7 +95,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -10,14 +10,18 @@ namespace BinaryObjectScanner.Protection
public class Origin : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Equals("Origin", StringComparison.OrdinalIgnoreCase) == true)
return "Origin";
@@ -40,7 +44,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -10,7 +10,11 @@ namespace BinaryObjectScanner.Protection
// For now, this means that the CheckContents check is redundant for external
// use through other programs
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Detect Red Hand protection
var contentMatchSets = new List<ContentMatchSet>

View File

@@ -14,23 +14,27 @@ namespace BinaryObjectScanner.Protection
public class PlayJ : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "PlayJ.exe" (https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe) and "CACTUSPJ.exe" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])).
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.StartsWith("PlayJ Music Player", StringComparison.OrdinalIgnoreCase) == true)
return $"PlayJ Music Player";
// Found in "PJSTREAM.DLL" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])).
name = pex.FileDescription;
if (name?.StartsWith("EVAUX32 Module", StringComparison.OrdinalIgnoreCase) == true)
return $"PlayJ Music Player Component";
// Found in "PlayJ.exe" (https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe) and "CACTUSPJ.exe" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])).
name = pex.ProductName;
if (name?.StartsWith("PlayJ", StringComparison.OrdinalIgnoreCase) == true)
@@ -57,7 +61,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -32,7 +32,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
return null;
}

View File

@@ -11,10 +11,14 @@ namespace BinaryObjectScanner.Protection
public class ProtectDISC : IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -31,7 +35,7 @@ namespace BinaryObjectScanner.Protection
new ContentMatchSet(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDISC"),
};
string match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
@@ -46,7 +50,7 @@ namespace BinaryObjectScanner.Protection
new ContentMatchSet(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
};
string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
@@ -55,10 +59,14 @@ namespace BinaryObjectScanner.Protection
if (sections.Length > 1)
{
// Get the n - 1 section strings, if they exist
List<string> strs = pex.GetSectionStrings(sections.Length - 2);
var strs = pex.GetSectionStrings(sections.Length - 2);
if (strs != null)
{
#if NET48
string str = strs.FirstOrDefault(s => s.Contains("VOB ProtectCD"));
#else
string? str = strs.FirstOrDefault(s => s.Contains("VOB ProtectCD"));
#endif
if (str != null)
return $"VOB ProtectCD {GetOldVersion(str)}";
}
@@ -67,7 +75,10 @@ namespace BinaryObjectScanner.Protection
// Get the last section (example names: ACE5, akxpxgcv, and piofinqb)
if (sections.Length > 0)
{
var matchers = new List<ContentMatchSet>
var lastSectionData = pex.GetSectionData(sections.Length - 1);
if (lastSectionData != null)
{
var matchers = new List<ContentMatchSet>
{
// HúMETINF
new ContentMatchSet(new byte?[] { 0x48, 0xFA, 0x4D, 0x45, 0x54, 0x49, 0x4E, 0x46 }, GetVersion76till10, "ProtectDISC"),
@@ -76,9 +87,10 @@ namespace BinaryObjectScanner.Protection
new ContentMatchSet(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"),
};
string match = MatchUtil.GetFirstMatch(file, pex.GetSectionData(sections.Length - 1), matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
var match = MatchUtil.GetFirstMatch(file, lastSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
}
// Get the .vob.pcd section, if it exists

View File

@@ -24,15 +24,19 @@ namespace BinaryObjectScanner.Protection
public class RainbowSentinel : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
// Found in "ADESKSYS.DLL"/"WINADMIN.EXE"/"WINQUERY.EXE" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\netsetup\SUPPORT\IPX".
@@ -57,7 +61,7 @@ namespace BinaryObjectScanner.Protection
// TODO: Figure out why resources for "RNBOVTMP.DLL", "SENTTEMP.DLL", "SNTI386.DLL", and "SX32W.DL_"/"SX32W.DLL" aren't getting read properly, causing checks for these files to not work.
string name = pex.FileDescription;
var name = pex.FileDescription;
// Found in "RNBOVTMP.DLL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (name?.Equals("Rainbow Technologies Virtual Device Driver", StringComparison.OrdinalIgnoreCase) == true)
@@ -130,7 +134,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -10,7 +10,11 @@ namespace BinaryObjectScanner.Protection
public class RingPROTECH : IContentCheck, IPathCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -46,7 +50,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -24,10 +24,14 @@ namespace BinaryObjectScanner.Protection
// TODO: Find 1.4+ samples.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -106,7 +110,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -36,7 +36,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -13,14 +13,18 @@ namespace BinaryObjectScanner.Protection
public class SecuROM : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name = pex.FileDescription;
if (name?.Contains("SecuROM PA") == true)
return $"SecuROM Product Activation v{pex.GetInternalVersion()}";
@@ -62,27 +66,30 @@ namespace BinaryObjectScanner.Protection
for (int i = 4; i < sections.Length; i++)
{
var nthSection = sections[i];
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name).TrimEnd('\0');
if (nthSection != null && nthSectionName != ".idata" && nthSectionName != ".rsrc")
if (nthSection == null)
continue;
string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? Array.Empty<byte>()).TrimEnd('\0');
if (nthSectionName != ".idata" && nthSectionName != ".rsrc")
{
var nthSectionData = pex.GetFirstSectionData(nthSectionName);
if (nthSectionData != null)
{
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"),
};
if (nthSectionData == null)
continue;
string match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
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"),
};
var match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
}
// Get the .rdata section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".rdata");
var strs = pex.GetFirstSectionStrings(".rdata");
if (strs != null)
{
// Both have the identifier found within `.rdata` but the version is within `.data`
@@ -131,7 +138,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{
@@ -156,7 +167,11 @@ namespace BinaryObjectScanner.Protection
private static string GetV4Version(PortableExecutable pex)
{
int index = 8; // Begin reading after "AddD"
#if NET48
char version = (char)pex.OverlayData[index];
#else
char version = (char)pex.OverlayData![index];
#endif
index += 2;
string subVersion = Encoding.ASCII.GetString(pex.OverlayData, index, 2);
@@ -229,9 +244,9 @@ namespace BinaryObjectScanner.Protection
private static string GetV8WhiteLabelVersion(PortableExecutable pex)
{
// Get the .data/DATA section, if it exists
// Get the .data/DATA section, if it exists
var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA");
if (dataSectionRaw != null)
if (dataSectionRaw == null)
return "8";
// Search .data for the version indicator

View File

@@ -10,15 +10,19 @@ namespace BinaryObjectScanner.Protection
public class SmartE : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the last section strings, if they exist
List<string> strs = pex.GetSectionStrings(sections.Length - 1);
var strs = pex.GetSectionStrings(sections.Length - 1);
if (strs != null)
{
if (strs.Any(s => s.Contains("BITARTS")))
@@ -44,7 +48,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

View File

@@ -15,15 +15,19 @@ namespace BinaryObjectScanner.Protection
public class SoftLock : IPortableExecutableCheck, IPathCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Found in "IALib.DLL" in IA item "TAFSEERVER4SETUP"
string name = pex.InternalName;
var name = pex.InternalName;
if (name?.Equals("Softlock Protected Application") == true)
return "SoftLock";
@@ -97,7 +101,11 @@ namespace BinaryObjectScanner.Protection
}
/// <inheritdoc/>
#if NET48
public string CheckFilePath(string path)
#else
public string? CheckFilePath(string path)
#endif
{
var matchers = new List<PathMatchSet>
{

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