mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-09-23 15:24:45 +00:00
Fix templated nullability issues
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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}";
|
||||
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")))
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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()}";
|
||||
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -32,7 +32,11 @@ namespace BinaryObjectScanner.Protection
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
#if NET48
|
||||
public string CheckFilePath(string path)
|
||||
#else
|
||||
public string? CheckFilePath(string path)
|
||||
#endif
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user