From 9e205ddf2afa897deed8f7c0666d01dea65b3579 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 21 Nov 2024 01:32:30 -0500 Subject: [PATCH] More incidental cleanup --- BinaryObjectScanner/Packer/ASPack.cs | 11 +- .../Packer/AutoPlayMediaStudio.cs | 4 +- BinaryObjectScanner/Packer/CExe.cs | 27 +- BinaryObjectScanner/Packer/DotNetReactor.cs | 110 +++--- BinaryObjectScanner/Packer/EXEStealth.cs | 44 ++- .../Packer/HyperTechCrackProof.cs | 3 +- BinaryObjectScanner/Packer/InnoSetup.cs | 20 +- BinaryObjectScanner/Packer/InstallAnywhere.cs | 2 +- BinaryObjectScanner/Packer/MicrosoftCABSFX.cs | 2 +- BinaryObjectScanner/Packer/NSIS.cs | 6 +- BinaryObjectScanner/Packer/NeoLite.cs | 3 +- BinaryObjectScanner/Packer/PECompact.cs | 5 +- BinaryObjectScanner/Packer/Petite.cs | 3 +- BinaryObjectScanner/Packer/SetupFactory.cs | 2 +- BinaryObjectScanner/Packer/Shrinker.cs | 4 +- BinaryObjectScanner/Packer/UPX.cs | 20 +- BinaryObjectScanner/Packer/WinZipSFX.cs | 15 +- BinaryObjectScanner/Packer/WiseInstaller.cs | 4 +- BinaryObjectScanner/Protection/ActiveMARK.cs | 27 +- BinaryObjectScanner/Protection/AlphaROM.cs | 2 + BinaryObjectScanner/Protection/Armadillo.cs | 5 +- BinaryObjectScanner/Protection/CDDVDCops.cs | 66 ++-- .../Protection/CactusDataShield.cs | 23 +- .../Protection/CenegaProtectDVD.cs | 14 +- BinaryObjectScanner/Protection/Cucko.cs | 27 +- BinaryObjectScanner/Protection/Denuvo.cs | 343 +++++++++--------- BinaryObjectScanner/Protection/DiscGuard.cs | 103 +++--- .../Protection/{Doc.loc.cs => DocLoc.cs} | 0 BinaryObjectScanner/Protection/Engine32.cs | 7 +- .../Protection/ImpulseReactor.cs | 6 +- BinaryObjectScanner/Protection/JoWood.cs | 8 +- BinaryObjectScanner/Protection/KeyLock.cs | 25 +- BinaryObjectScanner/Protection/LaserLok.cs | 46 +-- .../Protection/Macrovision.CDilla.cs | 8 +- .../Macrovision.CactusDataShield.cs | 6 +- .../Protection/Macrovision.FLEXnet.cs | 6 +- .../Protection/Macrovision.RipGuard.cs | 10 +- .../Protection/Macrovision.SafeCast.cs | 8 +- .../Protection/Macrovision.SafeDisc.cs | 34 +- BinaryObjectScanner/Protection/Macrovision.cs | 42 +-- BinaryObjectScanner/Protection/NEACProtect.cs | 6 +- BinaryObjectScanner/Protection/ProtectDisc.cs | 18 +- BinaryObjectScanner/Protection/RingPROTECH.cs | 25 +- BinaryObjectScanner/Protection/SVKP.cs | 3 +- BinaryObjectScanner/Protection/SecuROM.cs | 21 +- BinaryObjectScanner/Protection/SoftLock.cs | 2 +- BinaryObjectScanner/Protection/SolidShield.cs | 30 +- BinaryObjectScanner/Protection/StarForce.cs | 6 +- BinaryObjectScanner/Protection/Steam.cs | 14 +- BinaryObjectScanner/Protection/Tages.cs | 6 +- BinaryObjectScanner/Protection/Themida.cs | 5 +- BinaryObjectScanner/Protection/Uplay.cs | 18 +- 52 files changed, 591 insertions(+), 664 deletions(-) rename BinaryObjectScanner/Protection/{Doc.loc.cs => DocLoc.cs} (100%) diff --git a/BinaryObjectScanner/Packer/ASPack.cs b/BinaryObjectScanner/Packer/ASPack.cs index ec909726..cc4f3dee 100644 --- a/BinaryObjectScanner/Packer/ASPack.cs +++ b/BinaryObjectScanner/Packer/ASPack.cs @@ -19,8 +19,7 @@ namespace BinaryObjectScanner.Packer return null; // Get the .aspack section, if it exists - bool aspackSection = pex.ContainsSection(".aspack", exact: true); - if (aspackSection) + if (pex.ContainsSection(".aspack", exact: true)) return "ASPack 2.29"; // TODO: Re-enable all Entry Point checks after implementing @@ -60,10 +59,10 @@ namespace BinaryObjectScanner.Packer /// Generate the set of matchers used for each section /// /// - private List GenerateMatchers() + private static List GenerateMatchers() { - return new List - { + return + [ #region No Wildcards (Long) new(new byte?[] @@ -641,7 +640,7 @@ namespace BinaryObjectScanner.Packer new(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"), #endregion - }; + ]; } } } diff --git a/BinaryObjectScanner/Packer/AutoPlayMediaStudio.cs b/BinaryObjectScanner/Packer/AutoPlayMediaStudio.cs index e326b502..0b35d138 100644 --- a/BinaryObjectScanner/Packer/AutoPlayMediaStudio.cs +++ b/BinaryObjectScanner/Packer/AutoPlayMediaStudio.cs @@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Packer name = Utilities.GetLegalCopyright(pex); if (name?.StartsWith("Runtime Engine", StringComparison.OrdinalIgnoreCase) == true) return $"AutoPlay Media Studio {GetVersion(pex)}"; - */ + */ return null; } @@ -38,7 +38,7 @@ namespace BinaryObjectScanner.Packer return false; } - private string GetVersion(PortableExecutable pex) + private static string GetVersion(PortableExecutable pex) { // Check the product version explicitly var version = pex.ProductVersion; diff --git a/BinaryObjectScanner/Packer/CExe.cs b/BinaryObjectScanner/Packer/CExe.cs index 4adc5ed5..85533927 100644 --- a/BinaryObjectScanner/Packer/CExe.cs +++ b/BinaryObjectScanner/Packer/CExe.cs @@ -29,17 +29,17 @@ namespace BinaryObjectScanner.Packer if (pex.StubExecutableData != null) { var matchers = new List - { - new(new byte?[] { - 0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92, - 0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92, - 0x61, 0x36, 0x00, 0x92, 0x7B, 0x36, 0x01, 0x92, - 0x03, 0x29, 0x12, 0x92, 0x66, 0x36, 0x01, 0x92, - 0x89, 0x29, 0x0A, 0x92, 0x60, 0x36, 0x01, 0x92, - 0xD9, 0x30, 0x07, 0x92, 0x60, 0x36, 0x01, 0x92 - }, "CExe") - }; + new(new byte?[] + { + 0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92, + 0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92, + 0x61, 0x36, 0x00, 0x92, 0x7B, 0x36, 0x01, 0x92, + 0x03, 0x29, 0x12, 0x92, 0x66, 0x36, 0x01, 0x92, + 0x89, 0x29, 0x0A, 0x92, 0x60, 0x36, 0x01, 0x92, + 0xD9, 0x30, 0x07, 0x92, 0x60, 0x36, 0x01, 0x92 + }, "CExe") + }; var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug); if (!string.IsNullOrEmpty(match)) @@ -64,14 +64,11 @@ namespace BinaryObjectScanner.Packer if (payload == null || payload.Length == 0) return false; - // Determine which compression was used - bool zlib = pex.FindResourceByNamedType("99, 1").Count > 0; - // Create the output data buffer - var data = new byte[0]; + byte[]? data = []; // If we had the decompression DLL included, it's zlib - if (zlib) + if (pex.FindResourceByNamedType("99, 1").Count > 0) { try { diff --git a/BinaryObjectScanner/Packer/DotNetReactor.cs b/BinaryObjectScanner/Packer/DotNetReactor.cs index a36b14c4..398ca1dd 100644 --- a/BinaryObjectScanner/Packer/DotNetReactor.cs +++ b/BinaryObjectScanner/Packer/DotNetReactor.cs @@ -28,71 +28,67 @@ namespace BinaryObjectScanner.Packer return null; // Get the .text section, if it exists - if (pex.ContainsSection(".text")) + var textData = pex.GetFirstSectionData(".text"); + if (textData != null) { - var textData = pex.GetFirstSectionData(".text"); - if (textData != null) + var matchers = new List { - var matchers = new List + // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. + // {[8]-[4]-[4]-[4]-[12]} + new(new byte?[] { - // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. - // {[8]-[4]-[4]-[4]-[12]} - new(new byte?[] - { - 0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E, - 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x7B, null, - null, null, null, null, null, null, null, 0x2D, - null, null, null, null, 0x2D, null, null, null, - null, 0x2D, null, null, null, null, 0x2D, null, - null, null, null, null, null, null, null, null, - null, null, null, 0x7D - }, ".NET Reactor"), + 0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x7B, null, + null, null, null, null, null, null, null, 0x2D, + null, null, null, null, 0x2D, null, null, null, + null, 0x2D, null, null, null, null, 0x2D, null, + null, null, null, null, null, null, null, null, + null, null, null, 0x7D + }, ".NET Reactor"), - // Modified from the previous detection to detect a presumably newer version of .NET Reactor found in "KalypsoLauncher.dll" version 2.0.4.2. - // TODO: Check if this can/should be made more specific. - // .RSA - new(new byte?[] - { - 0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E, - 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x00, 0x52, - 0x53, 0x41 - }, ".NET Reactor"), + // Modified from the previous detection to detect a presumably newer version of .NET Reactor found in "KalypsoLauncher.dll" version 2.0.4.2. + // TODO: Check if this can/should be made more specific. + // .RSA + new(new byte?[] + { + 0x3C, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x49, 0x6D, 0x70, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6C, 0x73, 0x3E, 0x00, 0x52, + 0x53, 0x41 + }, ".NET Reactor"), - // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. - // 3{.[9].-.[9].-.[9].} - new(new byte?[] - { - 0x33, 0x7B, 0x00, null, null, null, null, null, - null, null, null, null, 0x00, 0x2D, 0x00, null, - null, null, null, null, null, null, null, null, - 0x00, 0x2D, 0x00, null, null, null, null, null, - null, null, null, null, 0x00, 0x2D, 0x00, null, - null, null, null, null, null, null, null, null, - 0x00, 0x7D, 0x00 - }, ".NET Reactor (Unconfirmed - Please report to us on GitHub)"), - - // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. - // {[8]-[4]-[4]-[4]-[12]} - new(new byte?[] - { - 0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E, - 0x7B, null, null, null, null, null, null, null, - null, 0x2D, null, null, null, null, 0x2D, null, - null, null, null, 0x2D, null, null, null, null, - 0x2D, null, null, null, null, null, null, null, - null, null, null, null, null, 0x7D - }, ".NET Reactor (Unconfirmed - Please report to us on GitHub)") - }; + // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. + // 3{.[9].-.[9].-.[9].} + new(new byte?[] + { + 0x33, 0x7B, 0x00, null, null, null, null, null, + null, null, null, null, 0x00, 0x2D, 0x00, null, + null, null, null, null, null, null, null, null, + 0x00, 0x2D, 0x00, null, null, null, null, null, + null, null, null, null, 0x00, 0x2D, 0x00, null, + null, null, null, null, null, null, null, null, + 0x00, 0x7D, 0x00 + }, ".NET Reactor (Unconfirmed - Please report to us on GitHub)"), + + // Adapted from https://github.com/cod3nym/detection-rules/blob/main/yara/dotnet/obf_net_reactor.yar and confirmed to work with "KalypsoLauncher.dll" from Redump entry 95617. + // {[8]-[4]-[4]-[4]-[12]} + new(new byte?[] + { + 0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E, + 0x7B, null, null, null, null, null, null, null, + null, 0x2D, null, null, null, null, 0x2D, null, + null, null, null, 0x2D, null, null, null, null, + 0x2D, null, null, null, null, null, null, null, + null, null, null, null, null, 0x7D + }, ".NET Reactor (Unconfirmed - Please report to us on GitHub)") + }; - return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug); - } + return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug); } - return null; } diff --git a/BinaryObjectScanner/Packer/EXEStealth.cs b/BinaryObjectScanner/Packer/EXEStealth.cs index fff20842..701a3d5d 100644 --- a/BinaryObjectScanner/Packer/EXEStealth.cs +++ b/BinaryObjectScanner/Packer/EXEStealth.cs @@ -15,26 +15,25 @@ namespace BinaryObjectScanner.Packer /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List - { - // ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;?? - new(new byte?[] - { - 0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B, - 0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x3F, 0x3B, 0x3F, 0x3F, 0x3B, 0x3F, - 0x3F - }, "EXE Stealth"), - }; + // ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;?? + new(new byte?[] + { + 0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B, + 0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x3F, 0x3B, 0x3F, 0x3F, 0x3B, 0x3F, + 0x3F + }, "EXE Stealth"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } /// @@ -57,18 +56,17 @@ namespace BinaryObjectScanner.Packer // `ExeStealth V2 Shareware not for public - This text not in registered version - www.webtoolmaster.com` // Get the ExeS/EXES section, if it exists - bool exesSection = pex.ContainsSection("ExeS", exact: true) || pex.ContainsSection("EXES", exact: true); - if (exesSection) + if (pex.ContainsSection("ExeS", exact: true)) + return "EXE Stealth 2.41-2.75"; + if (pex.ContainsSection("EXES", exact: true)) return "EXE Stealth 2.41-2.75"; // Get the mtw section, if it exists - bool mtwSection = pex.ContainsSection("mtw", exact: true); - if (mtwSection) + if (pex.ContainsSection("mtw", exact: true)) return "EXE Stealth 1.1"; // Get the rsrr section, if it exists - bool rsrrSection = pex.ContainsSection("rsrr", exact: true); - if (rsrrSection) + if (pex.ContainsSection("rsrr", exact: true)) return "EXE Stealth 2.76"; return null; diff --git a/BinaryObjectScanner/Packer/HyperTechCrackProof.cs b/BinaryObjectScanner/Packer/HyperTechCrackProof.cs index 9dc90394..9f57445b 100644 --- a/BinaryObjectScanner/Packer/HyperTechCrackProof.cs +++ b/BinaryObjectScanner/Packer/HyperTechCrackProof.cs @@ -21,11 +21,10 @@ namespace BinaryObjectScanner.Packer // 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 = Array.Exists(pex.Model.ImportTable?.ImportDirectoryTable ?? [], idte => idte?.Name == "KeRnEl32.dLl"); - if (peCSection && importTableMatch) + if (pex.ContainsSection("peC", exact: true) && importTableMatch) return "HyperTech CrackProof"; return null; diff --git a/BinaryObjectScanner/Packer/InnoSetup.cs b/BinaryObjectScanner/Packer/InnoSetup.cs index 430947c9..34918c1b 100644 --- a/BinaryObjectScanner/Packer/InnoSetup.cs +++ b/BinaryObjectScanner/Packer/InnoSetup.cs @@ -15,13 +15,17 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, NewExecutable nex, bool includeDebug) { // Check for "Inno" in the reserved words - if (nex.Model.Stub?.Header?.Reserved2?[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2?[5] == 0x6F6E) + var reserved2 = nex.Model.Stub?.Header?.Reserved2; + if (reserved2 != null && reserved2.Length > 5) { - string version = GetOldVersion(file, nex); - if (!string.IsNullOrEmpty(version)) - return $"Inno Setup {version}"; - - return "Inno Setup (Unknown Version)"; + if (reserved2[4] == 0x6E49 && reserved2[5] == 0x6F6E) + { + string version = GetOldVersion(file, nex); + if (!string.IsNullOrEmpty(version)) + return $"Inno Setup {version}"; + + return "Inno Setup (Unknown Version)"; + } } return null; @@ -78,8 +82,8 @@ namespace BinaryObjectScanner.Packer return MatchUtil.GetFirstMatch(file, data, matchers, false) ?? "Unknown 1.X"; } - - return "Unknown 1.X"; + + return "Unknown 1.X"; } } } diff --git a/BinaryObjectScanner/Packer/InstallAnywhere.cs b/BinaryObjectScanner/Packer/InstallAnywhere.cs index f10a2326..b4697f81 100644 --- a/BinaryObjectScanner/Packer/InstallAnywhere.cs +++ b/BinaryObjectScanner/Packer/InstallAnywhere.cs @@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Packer return false; } - private string GetVersion(PortableExecutable pex) + private static string GetVersion(PortableExecutable pex) { // Check the internal versions var version = pex.GetInternalVersion(); diff --git a/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs b/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs index 5fa028b9..216a62a8 100644 --- a/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs +++ b/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs @@ -51,7 +51,7 @@ namespace BinaryObjectScanner.Packer return false; } - private string GetVersion(PortableExecutable pex) + private static string GetVersion(PortableExecutable pex) { // Check the internal versions var version = pex.GetInternalVersion(); diff --git a/BinaryObjectScanner/Packer/NSIS.cs b/BinaryObjectScanner/Packer/NSIS.cs index c35efd56..5a329d1d 100644 --- a/BinaryObjectScanner/Packer/NSIS.cs +++ b/BinaryObjectScanner/Packer/NSIS.cs @@ -14,9 +14,9 @@ namespace BinaryObjectScanner.Packer if (sections == null) return null; - var description = pex.AssemblyDescription; - if (!string.IsNullOrEmpty(description) && description!.StartsWith("Nullsoft Install System")) - return $"NSIS {description.Substring("Nullsoft Install System".Length).Trim()}"; + var name = pex.AssemblyDescription; + if (name?.StartsWith("Nullsoft Install System") == true) + return $"NSIS {name.Substring("Nullsoft Install System".Length).Trim()}"; // Get the .data/DATA section strings, if they exist var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); diff --git a/BinaryObjectScanner/Packer/NeoLite.cs b/BinaryObjectScanner/Packer/NeoLite.cs index 049259f5..55658894 100644 --- a/BinaryObjectScanner/Packer/NeoLite.cs +++ b/BinaryObjectScanner/Packer/NeoLite.cs @@ -26,8 +26,7 @@ namespace BinaryObjectScanner.Packer // Get the .neolit section, if it exists. // TODO: Check if this section is also present in NeoLite 1.X. - bool neolitSection = pex.ContainsSection(".neolit", exact: true); - if (neolitSection) + if (pex.ContainsSection(".neolit", exact: true)) return "NeoLite"; // If more specific or additional checks are needed, "NeoLite Executable File Compressor" should be present diff --git a/BinaryObjectScanner/Packer/PECompact.cs b/BinaryObjectScanner/Packer/PECompact.cs index 0adf404d..c0f9059a 100644 --- a/BinaryObjectScanner/Packer/PECompact.cs +++ b/BinaryObjectScanner/Packer/PECompact.cs @@ -23,13 +23,12 @@ namespace BinaryObjectScanner.Packer // on the data in the file. This may be related to information in other fields // Get the pec1 section, if it exists - bool pec1Section = pex.ContainsSection("pec1", exact: true); - if (pec1Section) + if (pex.ContainsSection("pec1", exact: true)) return "PE Compact v1.x"; // Get the PEC2 section, if it exists -- TODO: Verify this comment since it's pulling the .text section var textSection = pex.GetFirstSection(".text", exact: true); - if (textSection != null && textSection.PointerToRelocations == 0x32434550) + if (textSection?.PointerToRelocations == 0x32434550) { if (textSection.PointerToLinenumbers != 0) return $"PE Compact v{textSection.PointerToLinenumbers} (internal version)"; diff --git a/BinaryObjectScanner/Packer/Petite.cs b/BinaryObjectScanner/Packer/Petite.cs index 3c3c9883..6b341fdd 100644 --- a/BinaryObjectScanner/Packer/Petite.cs +++ b/BinaryObjectScanner/Packer/Petite.cs @@ -16,8 +16,7 @@ namespace BinaryObjectScanner.Packer return null; // Get the .petite section, if it exists -- TODO: Is there a version number that can be found? - bool petiteSection = pex.ContainsSection(".petite", exact: true); - if (petiteSection) + if (pex.ContainsSection(".petite", exact: true)) return "PEtite"; return null; diff --git a/BinaryObjectScanner/Packer/SetupFactory.cs b/BinaryObjectScanner/Packer/SetupFactory.cs index 345e12b9..5408fe5a 100644 --- a/BinaryObjectScanner/Packer/SetupFactory.cs +++ b/BinaryObjectScanner/Packer/SetupFactory.cs @@ -43,7 +43,7 @@ namespace BinaryObjectScanner.Packer return false; } - private string GetVersion(PortableExecutable pex) + private static string GetVersion(PortableExecutable pex) { // Check the product version explicitly var version = pex.ProductVersion; diff --git a/BinaryObjectScanner/Packer/Shrinker.cs b/BinaryObjectScanner/Packer/Shrinker.cs index 0085d7e0..4bc25c89 100644 --- a/BinaryObjectScanner/Packer/Shrinker.cs +++ b/BinaryObjectScanner/Packer/Shrinker.cs @@ -16,9 +16,7 @@ namespace BinaryObjectScanner.Packer return null; // Get the .shrink0 and .shrink2 sections, if they exist -- TODO: Confirm if both are needed or either/or is fine - bool shrink0Section = pex.ContainsSection(".shrink0", true); - bool shrink2Section = pex.ContainsSection(".shrink2", true); - if (shrink0Section || shrink2Section) + if (pex.ContainsSection(".shrink0", true) || pex.ContainsSection(".shrink2", true)) return "Shrinker"; return null; diff --git a/BinaryObjectScanner/Packer/UPX.cs b/BinaryObjectScanner/Packer/UPX.cs index 37882892..d091d501 100644 --- a/BinaryObjectScanner/Packer/UPX.cs +++ b/BinaryObjectScanner/Packer/UPX.cs @@ -73,10 +73,13 @@ namespace BinaryObjectScanner.Packer { // Check the normal version location first int index = positions[0] - 5; - string versionString = Encoding.ASCII.GetString(fileContent, index, 4); - if (char.IsNumber(versionString[0])) - return versionString; - + if (index >= 0 && index < fileContent.Length - 4) + { + string versionString = Encoding.ASCII.GetString(fileContent, index, 4); + if (char.IsNumber(versionString[0])) + return versionString; + } + // Check for the old-style string // // Example: @@ -84,9 +87,12 @@ namespace BinaryObjectScanner.Packer // $Id: UPX 1.02 Copyright (C) 1996-2000 the UPX Team. All Rights Reserved. $ // UPX! index = positions[0] - 67; - versionString = Encoding.ASCII.GetString(fileContent, index, 4); - if (char.IsNumber(versionString[0])) - return versionString; + if (index >= 0 && index < fileContent.Length - 4) + { + string versionString = Encoding.ASCII.GetString(fileContent, index, 4); + if (char.IsNumber(versionString[0])) + return versionString; + } return "(Unknown Version)"; } diff --git a/BinaryObjectScanner/Packer/WinZipSFX.cs b/BinaryObjectScanner/Packer/WinZipSFX.cs index 455a9a6f..c5123270 100644 --- a/BinaryObjectScanner/Packer/WinZipSFX.cs +++ b/BinaryObjectScanner/Packer/WinZipSFX.cs @@ -648,8 +648,10 @@ namespace BinaryObjectScanner.Packer string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version"; // Standard - if (sfxFileName == "VW95SE.SFX" || sfxFileName == "ST32E.SFX" - || sfxFileName == "WZIPSE32.exe" || sfxFileName == "SI32LPG.SFX" + if (sfxFileName == "VW95SE.SFX" + || sfxFileName == "ST32E.SFX" + || sfxFileName == "WZIPSE32.exe" + || sfxFileName == "SI32LPG.SFX" || sfxFileName == "ST32E.WZE") { return sfxTimeDateStamp switch @@ -672,8 +674,10 @@ namespace BinaryObjectScanner.Packer } // Personal Edition - if (sfxFileName == "VW95LE.SFX" || sfxFileName == "PE32E.SFX" - || sfxFileName == "wzsepe32.exe" || sfxFileName == "SI32PE.SFX" + if (sfxFileName == "VW95LE.SFX" + || sfxFileName == "PE32E.SFX" + || sfxFileName == "wzsepe32.exe" + || sfxFileName == "SI32PE.SFX" || sfxFileName == "SI32LPE.SFX") { return sfxTimeDateStamp switch @@ -715,7 +719,8 @@ namespace BinaryObjectScanner.Packer } // Software Installation - else if (sfxFileName == "VW95SRE.SFX" || sfxFileName == "SI32E.SFX" + else if (sfxFileName == "VW95SRE.SFX" + || sfxFileName == "SI32E.SFX" || sfxFileName == "SI32E.WZE") { return sfxTimeDateStamp switch diff --git a/BinaryObjectScanner/Packer/WiseInstaller.cs b/BinaryObjectScanner/Packer/WiseInstaller.cs index 45728805..c17ad822 100644 --- a/BinaryObjectScanner/Packer/WiseInstaller.cs +++ b/BinaryObjectScanner/Packer/WiseInstaller.cs @@ -188,7 +188,7 @@ namespace BinaryObjectScanner.Packer /// /// New executable to check /// True if it matches a known version, false otherwise - private FormatProperty? MatchesNEVersion(NewExecutable nex) + private static FormatProperty? MatchesNEVersion(NewExecutable nex) { // TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this. switch (nex.Model.Stub?.Header?.NewExeHeaderAddr) @@ -245,7 +245,7 @@ namespace BinaryObjectScanner.Packer /// /// Portable executable to check /// True if it matches a known version, false otherwise - private FormatProperty? GetPEFormat(PortableExecutable pex) + private static FormatProperty? GetPEFormat(PortableExecutable pex) { if (pex.OverlayAddress == 0x6e00 && pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4 diff --git a/BinaryObjectScanner/Protection/ActiveMARK.cs b/BinaryObjectScanner/Protection/ActiveMARK.cs index d3822b8b..c89b4834 100644 --- a/BinaryObjectScanner/Protection/ActiveMARK.cs +++ b/BinaryObjectScanner/Protection/ActiveMARK.cs @@ -13,24 +13,23 @@ namespace BinaryObjectScanner.Protection /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List + // " " + (char)0xC2 + (char)0x16 + (char)0x00 + (char)0xA8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0xB8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x86 + (char)0xC8 + (char)0x16 + (char)0x00 + (char)0x9A + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x10 + (char)0xC2 + (char)0x16 + (char)0x00 + new(new byte?[] { - // " " + (char)0xC2 + (char)0x16 + (char)0x00 + (char)0xA8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0xB8 + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x86 + (char)0xC8 + (char)0x16 + (char)0x00 + (char)0x9A + (char)0xC1 + (char)0x16 + (char)0x00 + (char)0x10 + (char)0xC2 + (char)0x16 + (char)0x00 - new(new byte?[] - { - 0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00, - 0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00, - 0x9A, 0xC1, 0x16, 0x00, 0x10, 0xC2, 0x16, 0x00 - }, "ActiveMARK 5 (Unconfirmed - Please report to us on Github)"), - }; + 0x20, 0xC2, 0x16, 0x00, 0xA8, 0xC1, 0x16, 0x00, + 0xB8, 0xC1, 0x16, 0x00, 0x86, 0xC8, 0x16, 0x00, + 0x9A, 0xC1, 0x16, 0x00, 0x10, 0xC2, 0x16, 0x00 + }, "ActiveMARK 5 (Unconfirmed - Please report to us on Github)"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } /// diff --git a/BinaryObjectScanner/Protection/AlphaROM.cs b/BinaryObjectScanner/Protection/AlphaROM.cs index 3715cc41..b348ec37 100644 --- a/BinaryObjectScanner/Protection/AlphaROM.cs +++ b/BinaryObjectScanner/Protection/AlphaROM.cs @@ -69,9 +69,11 @@ namespace BinaryObjectScanner.Protection { if (strs.Exists(s => s.Contains("This Game is Japan Only"))) return "Alpha-ROM"; + // Found in "Filechk.exe" in Redump entry 115358. if (strs.Exists(s => s.Contains("AlphaCheck.exe"))) return "Alpha-ROM"; + // Found in "Uninstall.exe" in Redump entry 115358. if (strs.Exists(s => s.Contains("AlphaCheck.dat"))) return "Alpha-ROM"; diff --git a/BinaryObjectScanner/Protection/Armadillo.cs b/BinaryObjectScanner/Protection/Armadillo.cs index 64c7fa89..9ea60168 100644 --- a/BinaryObjectScanner/Protection/Armadillo.cs +++ b/BinaryObjectScanner/Protection/Armadillo.cs @@ -29,14 +29,13 @@ namespace BinaryObjectScanner.Protection return null; // Get the .nicode section, if it exists - bool nicodeSection = pex.ContainsSection(".nicode", exact: true); - if (nicodeSection) + if (pex.ContainsSection(".nicode", exact: true)) return "Armadillo"; // Loop through all "extension" sections -- usually .data1 or .text1 if (pex.SectionNames != null) { - foreach (var sectionName in Array.FindAll(pex.SectionNames, s => s != null && s.EndsWith("1"))) + foreach (var sectionName in Array.FindAll(pex.SectionNames ?? [], s => s != null && s.EndsWith("1"))) { // Get the section strings, if they exist var strs = pex.GetFirstSectionStrings(sectionName); diff --git a/BinaryObjectScanner/Protection/CDDVDCops.cs b/BinaryObjectScanner/Protection/CDDVDCops.cs index dbb1588f..84152581 100644 --- a/BinaryObjectScanner/Protection/CDDVDCops.cs +++ b/BinaryObjectScanner/Protection/CDDVDCops.cs @@ -69,31 +69,30 @@ namespace BinaryObjectScanner.Protection /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List + // TODO: Remove from here once it's confirmed that no PE executables contain this string + // CD-Cops, ver. + new(new byte?[] { - // TODO: Remove from here once it's confirmed that no PE executables contain this string - // CD-Cops, ver. - new(new byte?[] - { - 0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C, - 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 - }, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"), + 0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C, + 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 + }, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"), - // // DVD-Cops, ver. - new(new byte?[] - { - 0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, - 0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 - }, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"), - }; + // // DVD-Cops, ver. + new(new byte?[] + { + 0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, + 0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 + }, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } /// @@ -152,14 +151,14 @@ namespace BinaryObjectScanner.Protection if (pex.StubExecutableData != null) { var matchers = new List - { - // WEBCOPS - // Found in "HyperBowl.C_S" in https://web.archive.org/web/20120616074941/http://icm.games.tucows.com/files2/HyperDemo-109a.exe. - new(new byte?[] { - 0x57, 0x45, 0x42, 0x43, 0x4F, 0x50, 0x53 - }, "WEB-Cops") - }; + // WEBCOPS + // Found in "HyperBowl.C_S" in https://web.archive.org/web/20120616074941/http://icm.games.tucows.com/files2/HyperDemo-109a.exe. + new(new byte?[] + { + 0x57, 0x45, 0x42, 0x43, 0x4F, 0x50, 0x53 + }, "WEB-Cops") + }; var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug); if (!string.IsNullOrEmpty(match)) @@ -168,14 +167,12 @@ namespace BinaryObjectScanner.Protection // Get the .grand section, if it exists // Found in "AGENTHUG.QZ_" in Redump entry 84517 and "h3blade.QZ_" in Redump entry 85077. - bool grandSection = pex.ContainsSection(".grand", exact: true); - if (grandSection) + if (pex.ContainsSection(".grand", exact: true)) return "CD/DVD/WEB-Cops"; // Get the UNICops section, if it exists // Found in "FGP.exe" in IA item "flaklypa-grand-prix-dvd"/Redump entry 108169. - bool UNICopsSection = pex.ContainsSection("UNICops", exact: true); - if (UNICopsSection) + if (pex.ContainsSection("UNICops", exact: true)) return "UNI-Cops"; return null; @@ -228,14 +225,11 @@ namespace BinaryObjectScanner.Protection if (fileContent == null) return null; - byte[] versionBytes = new byte[4]; - Array.Copy(fileContent, positions[0] + 15, versionBytes, 0, 4); - char[] version = Array.ConvertAll(versionBytes, b => (char)b); - + string version = Encoding.ASCII.GetString(fileContent, positions[0] + 15, 4); if (version[0] == 0x00) return string.Empty; - return new string(version); + return version; } } } diff --git a/BinaryObjectScanner/Protection/CactusDataShield.cs b/BinaryObjectScanner/Protection/CactusDataShield.cs index e9d9116d..0d78ea36 100644 --- a/BinaryObjectScanner/Protection/CactusDataShield.cs +++ b/BinaryObjectScanner/Protection/CactusDataShield.cs @@ -10,23 +10,22 @@ namespace BinaryObjectScanner.Protection /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Limit these checks to Mac binaries // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List - { - // CDSPlayer - new([0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72], "Cactus Data Shield 200"), + // CDSPlayer + new([0x43, 0x44, 0x53, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72], "Cactus Data Shield 200"), - // yucca.cds - new([0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73], "Cactus Data Shield 200"), - }; + // yucca.cds + new([0x79, 0x75, 0x63, 0x63, 0x61, 0x2E, 0x63, 0x64, 0x73], "Cactus Data Shield 200"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } } } diff --git a/BinaryObjectScanner/Protection/CenegaProtectDVD.cs b/BinaryObjectScanner/Protection/CenegaProtectDVD.cs index 417e99d4..0b77fa18 100644 --- a/BinaryObjectScanner/Protection/CenegaProtectDVD.cs +++ b/BinaryObjectScanner/Protection/CenegaProtectDVD.cs @@ -32,21 +32,15 @@ namespace BinaryObjectScanner.Protection } // Get the .cenega section, if it exists. Seems to be found in the protected game executable ("game.exe" in Redump entry 31422 and "Classic Car Racing.exe" in IA item "speed-pack"). - bool cenegaSection = pex.ContainsSection(".cenega", exact: true); - if (cenegaSection) + if (pex.ContainsSection(".cenega", exact: true)) return "Cenega ProtectDVD"; // Get the .cenega0 through .cenega2 sections, if they exists. Found in "cenega.dll" in Redump entry 31422 and IA item "speed-pack". - cenegaSection = pex.ContainsSection(".cenega0", exact: true); - if (cenegaSection) + if (pex.ContainsSection(".cenega0", exact: true)) return "Cenega ProtectDVD"; - - cenegaSection = pex.ContainsSection(".cenega1", exact: true); - if (cenegaSection) + if (pex.ContainsSection(".cenega1", exact: true)) return "Cenega ProtectDVD"; - - cenegaSection = pex.ContainsSection(".cenega2", exact: true); - if (cenegaSection) + if (pex.ContainsSection(".cenega2", exact: true)) return "Cenega ProtectDVD"; return null; diff --git a/BinaryObjectScanner/Protection/Cucko.cs b/BinaryObjectScanner/Protection/Cucko.cs index ebea1133..661c9cdf 100644 --- a/BinaryObjectScanner/Protection/Cucko.cs +++ b/BinaryObjectScanner/Protection/Cucko.cs @@ -21,25 +21,22 @@ namespace BinaryObjectScanner.Protection return null; // Get the .text section, if it exists - if (pex.ContainsSection(".text")) + var textData = pex.GetFirstSectionData(".text"); + if (textData != null) { - var textData = pex.GetFirstSectionData(".text"); - if (textData != null) + var matchers = new List { - var matchers = new List + // 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(new byte?[] { - // 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(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)") - }; + 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, textData, matchers, includeDebug); - } + return MatchUtil.GetFirstMatch(file, textData, matchers, includeDebug); } return null; diff --git a/BinaryObjectScanner/Protection/Denuvo.cs b/BinaryObjectScanner/Protection/Denuvo.cs index 241ede08..6756b200 100644 --- a/BinaryObjectScanner/Protection/Denuvo.cs +++ b/BinaryObjectScanner/Protection/Denuvo.cs @@ -5,6 +5,7 @@ using SabreTools.Matching; using SabreTools.Matching.Content; using SabreTools.Matching.Paths; using SabreTools.Serialization.Wrappers; +using OHMN = SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber; namespace BinaryObjectScanner.Protection { @@ -65,199 +66,201 @@ namespace BinaryObjectScanner.Protection // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Denuvo%20protector.2.sg // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/_denuvoComplete.2.sg - // TODO: Re-enable all Entry Point checks after implementing // Denuvo Protector - // if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus && pex.EntryPointRaw != null) - // { - // byte?[] denuvoProtector = new byte?[] - // { - // 0x48, 0x8D, 0x0D, null, null, null, null, null, - // null, null, null, 0xE9, null, null, null, null, - // 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // }; + if (pex.Model.OptionalHeader?.Magic == OHMN.PE32Plus + && pex.EntryPointData != null) + { + byte?[] denuvoProtector = + [ + 0x48, 0x8D, 0x0D, null, null, null, null, null, + null, null, null, 0xE9, null, null, null, null, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; - // if (pex.EntryPointRaw.StartsWith(denuvoProtector)) - // return "Denuvo Protector"; - // } + if (pex.EntryPointData.StartsWith(denuvoProtector)) + return "Denuvo Protector"; + } // Denuvo var timingMatchers = new List { // Denuvo Timing new( - new byte?[] - { + [ 0x44, 0x65, 0x6E, 0x75, 0x76, 0x6F, 0x20, 0x54, 0x69, 0x6D, 0x69, 0x6E, 0x67, - }, "Denuvo") + ], "Denuvo") }; + var timingMatch = MatchUtil.GetFirstMatch(file, pex.EntryPointData, timingMatchers, includeDebug); // TODO: Re-enable all Entry Point checks after implementing - // if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrEmpty(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug))) - // { - // if (pex.OH_Magic == OptionalHeaderType.PE32Plus) - // { - // var matchers = new List - // { - // // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D, - // null, null, null, null, null, 0x4C, 0x8D, null, - // null, null, null, null, 0x4D, 0x29, 0xC1, - // }, - // end: 0 - // ), - // "Denuvo v1.0 (x64)"), + if (pex.ContainsSection(".arch") + || pex.ContainsSection(".srdata") + || !string.IsNullOrEmpty(timingMatch)) + { + if (pex.Model.OptionalHeader?.Magic == OHMN.PE32Plus) + { + var matchers = new List + { + // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider + new( + new ContentMatch( + new byte?[] + { + 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D, + null, null, null, null, null, 0x4C, 0x8D, null, + null, null, null, null, 0x4D, 0x29, 0xC1, + }, + end: 0 + ), + "Denuvo v1.0 (x64)"), - // // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9, - // null, null, null, null, - // }, - // end: 0 - // ), - // "Denuvo v2.0a (x64)"), + // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc + new( + new ContentMatch( + new byte?[] + { + 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9, + null, null, null, null, + }, + end: 0 + ), + "Denuvo v2.0a (x64)"), - // // Yesterday Origins - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x48, 0x89, null, null, null, null, null, 0x48, - // 0x89, null, null, null, null, null, 0x4C, 0x89, - // null, null, null, null, null, 0x4C, 0x89, null, - // null, null, null, null, 0x48, 0x83, 0xFA, 0x01, - // }, - // end: 0 - // ), - // "Denuvo v2.0b (x64)"), + // Yesterday Origins + new( + new ContentMatch( + new byte?[] + { + 0x48, 0x89, null, null, null, null, null, 0x48, + 0x89, null, null, null, null, null, 0x4C, 0x89, + null, null, null, null, null, 0x4C, 0x89, null, + null, null, null, null, 0x48, 0x83, 0xFA, 0x01, + }, + end: 0 + ), + "Denuvo v2.0b (x64)"), - // // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free) - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // null, null, null, null, null, null, null, null, - // 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3, - // }, - // end: 0 - // ), - // "Denuvo v3.0a (x64)"), + // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free) + new( + new ContentMatch( + new byte?[] + { + null, null, null, null, null, null, null, null, + 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3, + }, + end: 0 + ), + "Denuvo v3.0a (x64)"), - // // Train Sim World CSX Heavy Haul - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x4D, 0x8D, null, null, null, null, null, null, - // null, null, null, 0x48, 0x89, null, null, null, - // null, null, 0x48, 0x8D, null, null, 0x48, 0x89, - // null, 0x48, 0x89, null, 0x48, 0x89, - // }, - // end: 0 - // ), - // "Denuvo v3.0b (x64)"), - // }; + // Train Sim World CSX Heavy Haul + new( + new ContentMatch( + new byte?[] + { + 0x4D, 0x8D, null, null, null, null, null, null, + null, null, null, 0x48, 0x89, null, null, null, + null, null, 0x48, 0x8D, null, null, 0x48, 0x89, + null, 0x48, 0x89, null, 0x48, 0x89, + }, + end: 0 + ), + "Denuvo v3.0b (x64)"), + }; - // var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - // if (!string.IsNullOrEmpty(match)) - // return match; + var match = MatchUtil.GetFirstMatch(file, pex.EntryPointData, matchers, includeDebug); + if (!string.IsNullOrEmpty(match)) + return match; - // return "Denuvo (Unknown x64 Version)"; + return "Denuvo (Unknown x64 Version)"; - // //// Check if steam_api64.dll present - // //if (PE.isLibraryPresent("steam_api64.dll")) - // //{ - // // // Override additional info - // // sOptions = "x64 -> Steam"; - // // bDetected = 1; - // //} - // //// Check if uplay_r1_loader64.dll present - // //if (PE.isLibraryPresent("uplay_r1_loader64.dll")) - // //{ - // // // Override additional info - // // sOptions = "x64 -> uPlay"; - // // bDetected = 1; - // //} - // //// Check if uplay_r2_loader64.dll present - // //if (PE.isLibraryPresent("uplay_r2_loader64.dll")) - // //{ - // // // Override additional info - // // sOptions = "x64 -> uPlay"; - // // bDetected = 1; - // //} - // //// Check if Core/Activation64.dll present - // //if (PE.isLibraryPresent("Core/Activation64.dll")) - // //{ - // // // Override additional info - // // sOptions = "x64 -> Origin"; - // // bDetected = 1; - // //} - // } - // else - // { - // var matchers = new List - // { - // // Pro Evolution Soccer 2017, Champions of Anteria - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x55, 0x89, 0xE5, 0x8D, null, null, null, null, - // null, null, 0xE8, null, null, null, null, 0xE8, - // null, null, null, null, 0xE8, null, null, null, - // null, 0xE8, null, null, null, null, - // }, - // end: 0 - // ), - // "Denuvo v1.0 (x86)"), + //// Check if steam_api64.dll present + //if (PE.isLibraryPresent("steam_api64.dll")) + //{ + // // Override additional info + // sOptions = "x64 -> Steam"; + // bDetected = 1; + //} + //// Check if uplay_r1_loader64.dll present + //if (PE.isLibraryPresent("uplay_r1_loader64.dll")) + //{ + // // Override additional info + // sOptions = "x64 -> uPlay"; + // bDetected = 1; + //} + //// Check if uplay_r2_loader64.dll present + //if (PE.isLibraryPresent("uplay_r2_loader64.dll")) + //{ + // // Override additional info + // sOptions = "x64 -> uPlay"; + // bDetected = 1; + //} + //// Check if Core/Activation64.dll present + //if (PE.isLibraryPresent("Core/Activation64.dll")) + //{ + // // Override additional info + // sOptions = "x64 -> Origin"; + // bDetected = 1; + //} + } + else + { + var matchers = new List + { + // Pro Evolution Soccer 2017, Champions of Anteria + new( + new ContentMatch( + new byte?[] + { + 0x55, 0x89, 0xE5, 0x8D, null, null, null, null, + null, null, 0xE8, null, null, null, null, 0xE8, + null, null, null, null, 0xE8, null, null, null, + null, 0xE8, null, null, null, null, + }, + end: 0 + ), + "Denuvo v1.0 (x86)"), - // // Romance of 13 Kingdoms, 2Dark - // new ContentMatchSet( - // new ContentMatch( - // new byte?[] - // { - // 0x8D, null, null, null, null, null, null, 0x89, - // 0x7C, 0x24, 0x04, 0x89, 0xE7, - // }, - // end: 0 - // ), - // "Denuvo v2.0 (x86)"), - // }; + // Romance of 13 Kingdoms, 2Dark + new( + new ContentMatch( + new byte?[] + { + 0x8D, null, null, null, null, null, null, 0x89, + 0x7C, 0x24, 0x04, 0x89, 0xE7, + }, + end: 0 + ), + "Denuvo v2.0 (x86)"), + }; - // var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - // if (!string.IsNullOrEmpty(match)) - // return match; + var match = MatchUtil.GetFirstMatch(file, pex.EntryPointData, matchers, includeDebug); + if (!string.IsNullOrEmpty(match)) + return match; - // //// Check if steam_api64.dll present - // //if (PE.isLibraryPresent("steam_api.dll")) - // //{ - // // // Override additional info - // // sOptions = "x86 -> Steam"; - // // bDetected = 1; - // //} - // //// Check if uplay_r1_loader.dll present - // //if (PE.isLibraryPresent("uplay_r1_loader.dll")) - // //{ - // // // Override additional info - // // sOptions = "x86 -> uPlay"; - // // bDetected = 1; - // //} - // //// Check if Core/Activation.dll present - // //if (PE.isLibraryPresent("Core/Activation.dll")) - // //{ - // // // Override additional info - // // sOptions = "x86 -> Origin"; - // // bDetected = 1; - // //} - // } - // } + //// Check if steam_api64.dll present + //if (PE.isLibraryPresent("steam_api.dll")) + //{ + // // Override additional info + // sOptions = "x86 -> Steam"; + // bDetected = 1; + //} + //// Check if uplay_r1_loader.dll present + //if (PE.isLibraryPresent("uplay_r1_loader.dll")) + //{ + // // Override additional info + // sOptions = "x86 -> uPlay"; + // bDetected = 1; + //} + //// Check if Core/Activation.dll present + //if (PE.isLibraryPresent("Core/Activation.dll")) + //{ + // // Override additional info + // sOptions = "x86 -> Origin"; + // bDetected = 1; + //} + } + } return null; } diff --git a/BinaryObjectScanner/Protection/DiscGuard.cs b/BinaryObjectScanner/Protection/DiscGuard.cs index e37af4ee..ca896970 100644 --- a/BinaryObjectScanner/Protection/DiscGuard.cs +++ b/BinaryObjectScanner/Protection/DiscGuard.cs @@ -76,64 +76,61 @@ namespace BinaryObjectScanner.Protection return "DiscGuard"; // Get the .vbn section, if it exists - if (pex.ContainsSection(".vbn")) + var vbnData = pex.GetFirstSectionData(".vbn"); + if (vbnData != null) { - var vbnData = pex.GetFirstSectionData(".vbn"); - if (vbnData != null) + var matchers = new List { - var matchers = new List + // 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(new byte?[] { - // 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(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"), + 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(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(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"), + }; - var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug); - if (!string.IsNullOrEmpty(match)) - return match; - } + var match = MatchUtil.GetFirstMatch(file, vbnData, matchers, includeDebug); + if (!string.IsNullOrEmpty(match)) + return match; } return null; diff --git a/BinaryObjectScanner/Protection/Doc.loc.cs b/BinaryObjectScanner/Protection/DocLoc.cs similarity index 100% rename from BinaryObjectScanner/Protection/Doc.loc.cs rename to BinaryObjectScanner/Protection/DocLoc.cs diff --git a/BinaryObjectScanner/Protection/Engine32.cs b/BinaryObjectScanner/Protection/Engine32.cs index 8396d9fd..5cafe64f 100644 --- a/BinaryObjectScanner/Protection/Engine32.cs +++ b/BinaryObjectScanner/Protection/Engine32.cs @@ -27,11 +27,12 @@ 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 = Array.Exists(pex.Model.ImportTable.ImportDirectoryTable, idte => idte?.Name != null && idte.Name.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase)); - bool hintNameTableMatch = Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], ihne => ihne?.Name == "InitEngine"); + bool importDirectoryTableMatch = Array.Exists(pex.Model.ImportTable.ImportDirectoryTable, + idte => idte?.Name != null && idte.Name.Equals("ENGINE32.DLL", StringComparison.OrdinalIgnoreCase)); + bool hintNameTableMatch = Array.Exists(pex.Model.ImportTable.HintNameTable, + ihne => ihne?.Name == "InitEngine"); // The Hint/Name Table Entry "DeinitEngine" is present in every tested sample, aside from TOCA Race Driver 2 (Redump entries 104593-104596). - if (hintNameTableMatch && importDirectoryTableMatch) return "Engine32"; } diff --git a/BinaryObjectScanner/Protection/ImpulseReactor.cs b/BinaryObjectScanner/Protection/ImpulseReactor.cs index 3f2c9df1..673ac6eb 100644 --- a/BinaryObjectScanner/Protection/ImpulseReactor.cs +++ b/BinaryObjectScanner/Protection/ImpulseReactor.cs @@ -33,10 +33,12 @@ namespace BinaryObjectScanner.Protection return $"Stardock Product Activation {pex.GetInternalVersion()}"; // TODO: Check for CVP* instead? - bool containsCheck = Array.Exists(pex.Model.ExportTable?.ExportNameTable?.Strings ?? [], s => s?.StartsWith("CVPInitializeClient") ?? false); - bool containsCheck2 = false; + bool containsCheck = false; + if (pex.Model.ExportTable?.ExportNameTable?.Strings != null) + containsCheck = Array.Exists(pex.Model.ExportTable.ExportNameTable.Strings, s => s?.StartsWith("CVPInitializeClient") ?? false); // Get the .rdata section strings, if they exist + bool containsCheck2 = false; var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { diff --git a/BinaryObjectScanner/Protection/JoWood.cs b/BinaryObjectScanner/Protection/JoWood.cs index e9580e0d..736f3032 100644 --- a/BinaryObjectScanner/Protection/JoWood.cs +++ b/BinaryObjectScanner/Protection/JoWood.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; using BinaryObjectScanner.Interfaces; using SabreTools.Matching; using SabreTools.Matching.Content; @@ -72,12 +73,7 @@ namespace BinaryObjectScanner.Protection if (fileContent == null) return null; - int position = positions[0]; - - byte[] versionBytes = new byte[8]; - Array.Copy(fileContent, position + 67, versionBytes, 0, 8); - char[] version = Array.ConvertAll(versionBytes, b => (char)b); - return new string(version); + return Encoding.ASCII.GetString(fileContent, positions[0] + 67, 8); } } } diff --git a/BinaryObjectScanner/Protection/KeyLock.cs b/BinaryObjectScanner/Protection/KeyLock.cs index 1b8ec257..cd72d4c1 100644 --- a/BinaryObjectScanner/Protection/KeyLock.cs +++ b/BinaryObjectScanner/Protection/KeyLock.cs @@ -10,23 +10,22 @@ namespace BinaryObjectScanner.Protection /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List + // KEY-LOCK COMMAND + new(new byte?[] { - // KEY-LOCK COMMAND - new(new byte?[] - { - 0x4B, 0x45, 0x59, 0x2D, 0x4C, 0x4F, 0x43, 0x4B, - 0x20, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44 - }, "Key-Lock (Dongle) (Unconfirmed - Please report to us on Github)"), - }; + 0x4B, 0x45, 0x59, 0x2D, 0x4C, 0x4F, 0x43, 0x4B, + 0x20, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44 + }, "Key-Lock (Dongle) (Unconfirmed - Please report to us on Github)"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } } } diff --git a/BinaryObjectScanner/Protection/LaserLok.cs b/BinaryObjectScanner/Protection/LaserLok.cs index f14d0920..56d9c782 100644 --- a/BinaryObjectScanner/Protection/LaserLok.cs +++ b/BinaryObjectScanner/Protection/LaserLok.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using BinaryObjectScanner.Interfaces; +using SabreTools.IO.Extensions; using SabreTools.Matching; using SabreTools.Matching.Paths; using SabreTools.Serialization.Wrappers; @@ -164,35 +166,11 @@ namespace BinaryObjectScanner.Protection if (!sectionContent.FirstPosition(check, out int position)) return "(Build unknown)"; - string year, month, day; - if (versionTwo) - { - int index = position + 14; + int index = versionTwo ? position + 14 : position + 13; - byte[] temp = new byte[2]; - Array.Copy(sectionContent, index, temp, 0, 2); - day = new string(Array.ConvertAll(temp, b => (char)b)); - index += 3; - Array.Copy(sectionContent, index, temp, 0, 2); - month = new string(Array.ConvertAll(temp, b => (char)b)); - index += 3; - Array.Copy(sectionContent, index, temp, 0, 2); - year = "20" + new string(Array.ConvertAll(temp, b => (char)b)); - } - else - { - int index = position + 13; - - byte[] temp = new byte[2]; - Array.Copy(sectionContent, index, temp, 0, 2); - day = new string(Array.ConvertAll(temp, b => (char)b)); - index += 3; - Array.Copy(sectionContent, index, temp, 0, 2); - month = new string(Array.ConvertAll(temp, b => (char)b)); - index += 3; - Array.Copy(sectionContent, index, temp, 0, 2); - year = "20" + new string(Array.ConvertAll(temp, b => (char)b)); - } + string day = Encoding.ASCII.GetString(sectionContent, index + 0, 2); + string month = Encoding.ASCII.GetString(sectionContent, index + 3, 2); + string year = "20" + Encoding.ASCII.GetString(sectionContent, index + 6, 2); return $"(Build {year}-{month}-{day})"; } @@ -203,9 +181,7 @@ namespace BinaryObjectScanner.Protection if (sectionContent == null) return null; - byte[] temp = new byte[4]; - Array.Copy(sectionContent, position + 76, temp, 0, 4); - return new string(Array.ConvertAll(temp, b => (char)b)); + return Encoding.ASCII.GetString(sectionContent, position + 76, 4); } public static string? GetVersion16Bit(string firstMatchedString, IEnumerable? files) @@ -214,16 +190,12 @@ namespace BinaryObjectScanner.Protection return string.Empty; using var fs = File.Open(firstMatchedString, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using var br = new BinaryReader(fs); - return GetVersion16Bit(br.ReadBytes((int)fs.Length)); + return GetVersion16Bit(fs.ReadBytes((int)fs.Length)); } private static string GetVersion16Bit(byte[] fileContent) { - byte[] temp = new byte[7]; - Array.Copy(fileContent, 71, temp, 0, 7); - char[] version = Array.ConvertAll(temp, b => (char)b); - + string version = Encoding.ASCII.GetString(fileContent, 71, 7); if (char.IsNumber(version[0]) && char.IsNumber(version[2]) && char.IsNumber(version[3])) { if (char.IsNumber(version[5]) && char.IsNumber(version[6])) diff --git a/BinaryObjectScanner/Protection/Macrovision.CDilla.cs b/BinaryObjectScanner/Protection/Macrovision.CDilla.cs index ac47ad20..adcc890d 100644 --- a/BinaryObjectScanner/Protection/Macrovision.CDilla.cs +++ b/BinaryObjectScanner/Protection/Macrovision.CDilla.cs @@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? CDillaCheckExecutable(string file, NewExecutable nex, bool includeDebug) + internal static string? CDillaCheckExecutable(string file, NewExecutable nex, bool includeDebug) { // TODO: Implement NE checks for "CDILLA05", "CDILLA10", "CDILLA16", and "CDILLA40". @@ -60,7 +60,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? CDillaCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? CDillaCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -132,7 +132,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List CDillaCheckDirectoryPath(string path, List? files) + internal static List CDillaCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -175,7 +175,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? CDillaCheckFilePath(string path) + internal static string? CDillaCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs index 59cc12a4..f914c7b9 100644 --- a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs +++ b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs @@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? CactusDataShieldCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? CactusDataShieldCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List CactusDataShieldCheckDirectoryPath(string path, List? files) + internal static List CactusDataShieldCheckDirectoryPath(string path, List? files) { // TODO: Verify if these are OR or AND var matchers = new List @@ -89,7 +89,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? CactusDataShieldCheckFilePath(string path) + internal static string? CactusDataShieldCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs b/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs index ba805f60..daee1321 100644 --- a/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs +++ b/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs @@ -12,7 +12,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? FLEXnetCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? FLEXnetCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -68,7 +68,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List FLEXNetCheckDirectoryPath(string path, List? files) + internal static List FLEXNetCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -88,7 +88,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? FLEXNetCheckFilePath(string path) + internal static string? FLEXNetCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/Macrovision.RipGuard.cs b/BinaryObjectScanner/Protection/Macrovision.RipGuard.cs index c9e82044..f778d194 100644 --- a/BinaryObjectScanner/Protection/Macrovision.RipGuard.cs +++ b/BinaryObjectScanner/Protection/Macrovision.RipGuard.cs @@ -19,7 +19,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? RipGuardCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? RipGuardCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -50,16 +50,14 @@ namespace BinaryObjectScanner.Protection return "RipGuard"; } } - catch - { - } + catch { } } return null; } /// - internal List RipGuardCheckDirectoryPath(string path, List? files) + internal static List RipGuardCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -75,7 +73,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? RipGuardCheckFilePath(string path) + internal static string? RipGuardCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs index 8d4e8bbc..a2f99b8d 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs @@ -40,7 +40,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? SafeCastCheckExecutable(string file, NewExecutable nex, bool includeDebug) + internal static string? SafeCastCheckExecutable(string file, NewExecutable nex, bool includeDebug) { // Check for the CDAC01AA name string. if (nex.Model.ResidentNameTable != null) @@ -67,7 +67,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? SafeCastCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? SafeCastCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -147,7 +147,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List SafeCastCheckDirectoryPath(string path, List? files) + internal static List SafeCastCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -190,7 +190,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? SafeCastCheckFilePath(string path) + internal static string? SafeCastCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs index cbdbc250..ad1b50b4 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs @@ -41,7 +41,7 @@ namespace BinaryObjectScanner.Protection public partial class Macrovision { /// - internal string? SafeDiscCheckExecutable(string file, PortableExecutable pex, bool includeDebug) + internal static string? SafeDiscCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible var sections = pex.Model.SectionTable; @@ -49,12 +49,18 @@ namespace BinaryObjectScanner.Protection return null; // Found in Redump entry 57986. - if (Array.Exists(pex.Model.ImportTable?.HintNameTable ?? [], ihne => ihne?.Name == "LTDLL_Authenticate")) - return "SafeDisc Lite"; + if (pex.Model.ImportTable?.HintNameTable != null) + { + if (Array.Exists(pex.Model.ImportTable.HintNameTable, ihne => ihne?.Name == "LTDLL_Authenticate")) + return "SafeDisc Lite"; + } // Found in Redump entry 57986. - if (Array.Exists(pex.Model.ImportTable?.ImportDirectoryTable ?? [], idte => idte?.Name == "ltdll.dll")) - return "SafeDisc Lite"; + if (pex.Model.ImportTable?.ImportDirectoryTable != null) + { + if (Array.Exists(pex.Model.ImportTable.ImportDirectoryTable, idte => idte?.Name == "ltdll.dll")) + return "SafeDisc Lite"; + } // Get the .data/DATA section strings, if they exist var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); @@ -103,14 +109,10 @@ namespace BinaryObjectScanner.Protection // Found in Redump entries 20729 and 65569. // Get the debug data - try - { - if (pex.FindCodeViewDebugTableByPath("SafeDisc").Count > 0) - return "SafeDisc"; - if (pex.FindCodeViewDebugTableByPath("Safedisk").Count > 0) - return "SafeDisc"; - } - catch { } + if (pex.FindCodeViewDebugTableByPath("SafeDisc").Count > 0) + return "SafeDisc"; + if (pex.FindCodeViewDebugTableByPath("Safedisk").Count > 0) + return "SafeDisc"; // TODO: Investigate various section names: // "STLPORT_" - Found in Redump entry 11638. @@ -126,7 +128,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List SafeDiscCheckDirectoryPath(string path, List? files) + internal static List SafeDiscCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -264,7 +266,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? SafeDiscCheckFilePath(string path) + internal static string? SafeDiscCheckFilePath(string path) { var matchers = new List { @@ -927,7 +929,7 @@ namespace BinaryObjectScanner.Protection // "SPLSH256.BMP": Found in SafeDisc versions 1.00.025-1.01.044 (Redump entries 66005 and 81619). } - private string GetSafeDiscDiagExecutableVersion(PortableExecutable pex) + private static string GetSafeDiscDiagExecutableVersion(PortableExecutable pex) { // Different versions of this executable correspond to different SafeDisc versions. var version = pex.FileVersion; diff --git a/BinaryObjectScanner/Protection/Macrovision.cs b/BinaryObjectScanner/Protection/Macrovision.cs index 1c347dbc..ff9247ad 100644 --- a/BinaryObjectScanner/Protection/Macrovision.cs +++ b/BinaryObjectScanner/Protection/Macrovision.cs @@ -70,23 +70,17 @@ namespace BinaryObjectScanner.Protection // Almost every single sample known has both sections, though one only contains the "stxt371" section. It is unknown if this is intentional, or if the game functions without it. // It is present in the "Texas HoldEm!" game in "boontybox_PCGamer_DVD.exe" in IA items PC_Gamer_Disc_7.55_July_2005 and cdrom-pcgamercd7.58. // Other games in this set also aren't functional despite having the normal layout of stxt sections, and the primary program doesn't install at all due to activation servers being down. - bool stxt371Section = pex.ContainsSection("stxt371", exact: true); - bool stxt774Section = pex.ContainsSection("stxt774", exact: true); - if (stxt371Section || stxt774Section) + if (pex.ContainsSection("stxt371", exact: true) || pex.ContainsSection("stxt774", exact: true)) { // Check the header padding for protected sections. var sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, true); - if (!string.IsNullOrEmpty(sectionMatch)) - { + if (sectionMatch != null) + resultsList.Add(sectionMatch); + + // Get the .data section, if it exists, for protected sections. + sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), true); + if (sectionMatch != null) resultsList.Add(sectionMatch!); - } - else - { - // Get the .data section, if it exists, for protected sections. - sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), true); - if (!string.IsNullOrEmpty(sectionMatch)) - resultsList.Add(sectionMatch!); - } int entryPointIndex = pex.FindEntryPointSectionIndex(); var entryPointSectionName = pex.SectionNames?[entryPointIndex]; @@ -113,17 +107,13 @@ namespace BinaryObjectScanner.Protection { // Check the header padding for protected sections. var sectionMatch = CheckSectionForProtection(file, includeDebug, pex.HeaderPaddingStrings, pex.HeaderPaddingData, false); - if (!string.IsNullOrEmpty(sectionMatch)) - { - resultsList.Add(sectionMatch!); - } - else - { - // Check the .data section, if it exists, for protected sections. - sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), false); - if (!string.IsNullOrEmpty(sectionMatch)) - resultsList.Add(sectionMatch!); - } + if (sectionMatch != null) + resultsList.Add(sectionMatch); + + // Check the .data section, if it exists, for protected sections. + sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), false); + if (sectionMatch != null) + resultsList.Add(sectionMatch); } // Run Cactus Data Shield PE checks @@ -249,7 +239,7 @@ namespace BinaryObjectScanner.Protection } /// - internal List MacrovisionCheckDirectoryPath(string path, List? files) + internal static List MacrovisionCheckDirectoryPath(string path, List? files) { var matchers = new List { @@ -261,7 +251,7 @@ namespace BinaryObjectScanner.Protection } /// - internal string? MacrovisionCheckFilePath(string path) + internal static string? MacrovisionCheckFilePath(string path) { var matchers = new List { diff --git a/BinaryObjectScanner/Protection/NEACProtect.cs b/BinaryObjectScanner/Protection/NEACProtect.cs index df343229..4679caec 100644 --- a/BinaryObjectScanner/Protection/NEACProtect.cs +++ b/BinaryObjectScanner/Protection/NEACProtect.cs @@ -32,11 +32,7 @@ namespace BinaryObjectScanner.Protection // Get the .neac0 and .neac1 sections, if they exist. // Found in "NeacSafe64.sys" and "NeacSafe.sys". - bool neac0Section = pex.ContainsSection(".neac0", exact: true); - bool neac1Section = pex.ContainsSection(".neac1", exact: true); - - // Check if either .neac section is present. - if (neac0Section || neac1Section) + if (pex.ContainsSection(".neac0", exact: true) || pex.ContainsSection(".neac1", exact: true)) return "NEAC Protect"; var name = pex.ProductName; diff --git a/BinaryObjectScanner/Protection/ProtectDisc.cs b/BinaryObjectScanner/Protection/ProtectDisc.cs index d127e536..c858770b 100644 --- a/BinaryObjectScanner/Protection/ProtectDisc.cs +++ b/BinaryObjectScanner/Protection/ProtectDisc.cs @@ -89,8 +89,7 @@ namespace BinaryObjectScanner.Protection } // Get the .vob.pcd section, if it exists - bool vobpcdSection = pex.ContainsSection(".vob.pcd", exact: true); - if (vobpcdSection) + if (pex.ContainsSection(".vob.pcd", exact: true)) return "VOB ProtectCD"; return null; @@ -217,16 +216,22 @@ namespace BinaryObjectScanner.Protection int index = positions[0] + 37; byte subversion = fileContent[index]; + index += 2; byte version = fileContent[index]; + index = positions[0] + 49; int irefBuild = BitConverter.ToInt32(fileContent, index); + index = positions[0] + 53; byte versionindicatorPD9 = fileContent[index]; + index = positions[0] + 0x40; byte subsubversionPD9x = fileContent[index]; + index++; byte subversionPD9x2 = fileContent[index]; + index++; byte subversionPD9x1 = fileContent[index]; @@ -308,10 +313,11 @@ namespace BinaryObjectScanner.Protection // TODO: Ensure that this version finding works for all known versions private static string GetVOBVersion(byte[] fileContent, int position) { - byte version = fileContent[position - 2]; - byte subVersion = (byte)((fileContent[position - 3] & 0xF0) >> 4); - byte subSubVersion = (byte)((fileContent[position - 4] & 0xF0) >> 4); - return $"{version}.{subVersion}.{subSubVersion}"; + byte major = fileContent[position - 2]; + byte minor = (byte)((fileContent[position - 3] & 0xF0) >> 4); + byte patch = (byte)((fileContent[position - 4] & 0xF0) >> 4); + + return $"{major}.{minor}.{patch}"; } } } diff --git a/BinaryObjectScanner/Protection/RingPROTECH.cs b/BinaryObjectScanner/Protection/RingPROTECH.cs index 184a691a..42622401 100644 --- a/BinaryObjectScanner/Protection/RingPROTECH.cs +++ b/BinaryObjectScanner/Protection/RingPROTECH.cs @@ -13,23 +13,22 @@ namespace BinaryObjectScanner.Protection /// public string? CheckContents(string file, byte[] fileContent, bool includeDebug) { + // Only allow during debug + if (!includeDebug) + return null; + // TODO: Obtain a sample to find where this string is in a typical executable - if (includeDebug) + var contentMatchSets = new List { - var contentMatchSets = new List + // (char)0x00 + Allocator + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + new(new byte?[] { - // (char)0x00 + Allocator + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 - new(new byte?[] - { - 0x00, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x61, 0x74, - 0x6F, 0x72, 0x00, 0x00, 0x00, 0x00 - }, "Ring PROTECH / ProRing [Check disc for physical ring] (Unconfirmed - Please report to us on Github)"), - }; + 0x00, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x61, 0x74, + 0x6F, 0x72, 0x00, 0x00, 0x00, 0x00 + }, "Ring PROTECH / ProRing [Check disc for physical ring] (Unconfirmed - Please report to us on Github)"), + }; - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - - return null; + return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); } // TODO: Confirm if these checks are only for ProRing or if they are also for older Ring PROTECH diff --git a/BinaryObjectScanner/Protection/SVKP.cs b/BinaryObjectScanner/Protection/SVKP.cs index 6deaabc8..ec43201a 100644 --- a/BinaryObjectScanner/Protection/SVKP.cs +++ b/BinaryObjectScanner/Protection/SVKP.cs @@ -82,8 +82,7 @@ namespace BinaryObjectScanner.Protection // Get the .svkp section, if it exists. // This section is present in at least versions 1.05-1.32, but isn't present in every known sample of these versions. Removing this section name may be a perk of the licensed version. - bool neolitSection = pex.ContainsSection(".svkp", exact: true); - if (neolitSection) + if (pex.ContainsSection(".svkp", exact: true)) return "SVKP"; return null; diff --git a/BinaryObjectScanner/Protection/SecuROM.cs b/BinaryObjectScanner/Protection/SecuROM.cs index 0d2563c7..4de2a597 100644 --- a/BinaryObjectScanner/Protection/SecuROM.cs +++ b/BinaryObjectScanner/Protection/SecuROM.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text; using BinaryObjectScanner.Interfaces; using SabreTools.Matching; @@ -41,22 +40,18 @@ namespace BinaryObjectScanner.Protection return $"SecuROM Product Activation v{pex.GetInternalVersion()}"; // Get the matrosch section, if it exists - bool matroschSection = pex.ContainsSection("matrosch", exact: true); - if (matroschSection) + if (pex.ContainsSection("matrosch", exact: true)) return $"SecuROM Matroschka Package"; - bool dsstextSection = pex.ContainsSection(".dsstext", exact: true); - if (dsstextSection) + if (pex.ContainsSection(".dsstext", exact: true)) return $"SecuROM 8.03.03+"; // Get the .securom section, if it exists - bool securomSection = pex.ContainsSection(".securom", exact: true); - if (securomSection) + if (pex.ContainsSection(".securom", exact: true)) return $"SecuROM {GetV7Version(pex)}"; // Get the .sll section, if it exists - bool sllSection = pex.ContainsSection(".sll", exact: true); - if (sllSection) + if (pex.ContainsSection(".sll", exact: true)) return $"SecuROM SLL Protected (for SecuROM v8.x)"; // Search after the last section @@ -73,7 +68,7 @@ namespace BinaryObjectScanner.Protection if (nthSection == null) continue; - string nthSectionName = Encoding.UTF8.GetString(nthSection.Name ?? []).TrimEnd('\0'); + string nthSectionName = Encoding.ASCII.GetString(nthSection.Name ?? []).TrimEnd('\0'); if (nthSectionName != ".idata" && nthSectionName != ".rsrc") { var nthSectionData = pex.GetFirstSectionData(nthSectionName); @@ -104,9 +99,7 @@ namespace BinaryObjectScanner.Protection } // Get the .cms_d and .cms_t sections, if they exist -- TODO: Confirm if both are needed or either/or is fine - bool cmsdSection = pex.ContainsSection(".cmd_d", true); - bool cmstSection = pex.ContainsSection(".cms_t", true); - if (cmsdSection || cmstSection) + if (pex.ContainsSection(".cmd_d", true) || pex.ContainsSection(".cms_t", true)) return $"SecuROM 1-3"; return null; diff --git a/BinaryObjectScanner/Protection/SoftLock.cs b/BinaryObjectScanner/Protection/SoftLock.cs index 1a35fe3b..80502fd4 100644 --- a/BinaryObjectScanner/Protection/SoftLock.cs +++ b/BinaryObjectScanner/Protection/SoftLock.cs @@ -62,7 +62,7 @@ namespace BinaryObjectScanner.Protection // Found in "TafseerVer4.exe" in IA item "TAFSEERVER4SETUP" var strings = pex.GetFirstSectionStrings(".section") ?? []; - if (strings.Exists(s => s?.Contains("SOFTLOCKPROTECTION") == true)) + if (strings.Exists(s => s.Contains("SOFTLOCKPROTECTION"))) return "SoftLock"; // Investigate if the ".section" section is an indicator of SoftLock diff --git a/BinaryObjectScanner/Protection/SolidShield.cs b/BinaryObjectScanner/Protection/SolidShield.cs index 4e21324a..c60afd48 100644 --- a/BinaryObjectScanner/Protection/SolidShield.cs +++ b/BinaryObjectScanner/Protection/SolidShield.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using BinaryObjectScanner.Interfaces; using SabreTools.Matching; using SabreTools.Matching.Content; @@ -77,7 +76,7 @@ namespace BinaryObjectScanner.Protection return "SolidShield EXE Wrapper v1"; // Search the last two available sections - for (int i = (pex.SectionNames != null && pex.SectionNames.Length >= 2 ? pex.SectionNames.Length - 2 : 0); i < (pex.SectionNames?.Length ?? 0); i++) + for (int i = Math.Max(sections.Length - 2, 0); i < sections.Length; i++) { // Get the nth section strings, if they exist var strs = pex.GetSectionStrings(i); @@ -152,23 +151,18 @@ namespace BinaryObjectScanner.Protection int position = positions[0]; -#if NET20 || NET35 || NET40 byte[] id1 = new byte[3]; Array.Copy(fileContent, position + 5, id1, 0, 3); byte[] id2 = new byte[4]; Array.Copy(fileContent, position + 16, id2, 0, 3); -#else - var id1 = new ArraySegment(fileContent, position + 5, 3); - var id2 = new ArraySegment(fileContent, position + 16, 4); -#endif - if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) - && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 })) + if (id1[0] == 0x00 && id1[1] == 0x00 && id1[2] == 0x00 + && id2[0] == 0x00 && id2[1] == 0x10 && id2[2] == 0x00 && id2[3] == 0x00) { return "v1"; } - else if (id1.SequenceEqual(new byte[] { 0x2E, 0x6F, 0x26 }) - && id2.SequenceEqual(new byte[] { 0xDB, 0xC5, 0x20, 0x3A })) // [0xDB, 0xC5, 0x20, 0x3A, 0xB9] + else if (id1[0] == 0x2E && id1[1] == 0x6F && id1[2] == 0x26 + && id2[0] == 0xDB && id2[1] == 0xC5 && id2[2] == 0x20 && id2[3] == 0x3A) // [0xDB, 0xC5, 0x20, 0x3A, 0xB9] { return "v2"; // TODO: Verify against other SolidShield 2 discs } @@ -183,24 +177,20 @@ namespace BinaryObjectScanner.Protection return null; int position = positions[0]; -#if NET20 || NET35 || NET40 + byte[] id1 = new byte[3]; Array.Copy(fileContent, position + 4, id1, 0, 3); byte[] id2 = new byte[4]; Array.Copy(fileContent, position + 15, id2, 0, 3); -#else - var id1 = new ArraySegment(fileContent, position + 4, 3); - var id2 = new ArraySegment(fileContent, position + 15, 4); -#endif if ((fileContent[position + 3] == 0x04 || fileContent[position + 3] == 0x05) - && id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) - && id2.SequenceEqual(new byte[] { 0x00, 0x10, 0x00, 0x00 })) + && id1[0] == 0x00 && id1[1] == 0x00 && id1[2] == 0x00 + && id2[0] == 0x00 && id2[1] == 0x10 && id2[2] == 0x00 && id2[3] == 0x00) { return "2 (SolidShield v2 EXE Wrapper)"; } - else if (id1.SequenceEqual(new byte[] { 0x00, 0x00, 0x00 }) - && id2.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 })) + else if (id1[0] == 0x00 && id1[1] == 0x00 && id1[2] == 0x00 + && id2[0] == 0x00 && id2[1] == 0x10 && id2[2] == 0x00 && id2[3] == 0x00) { // "T" + (char)0x00 + "a" + (char)0x00 + "g" + (char)0x00 + "e" + (char)0x00 + "s" + (char)0x00 + "S" + (char)0x00 + "e" + (char)0x00 + "t" + (char)0x00 + "u" + (char)0x00 + "p" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + "0" + (char)0x00 + (char)0x8 + (char)0x00 + (char)0x1 + (char)0x0 + "F" + (char)0x00 + "i" + (char)0x00 + "l" + (char)0x00 + "e" + (char)0x00 + "V" + (char)0x00 + "e" + (char)0x00 + "r" + (char)0x00 + "s" + (char)0x00 + "i" + (char)0x00 + "o" + (char)0x00 + "n" + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 byte?[] check2 = diff --git a/BinaryObjectScanner/Protection/StarForce.cs b/BinaryObjectScanner/Protection/StarForce.cs index 1f220074..160f2103 100644 --- a/BinaryObjectScanner/Protection/StarForce.cs +++ b/BinaryObjectScanner/Protection/StarForce.cs @@ -90,13 +90,11 @@ namespace BinaryObjectScanner.Protection // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/StarForce.2.sg // Get the .brick section, if it exists - bool brickSection = pex.ContainsSection(".brick", exact: true); - if (brickSection) + if (pex.ContainsSection(".brick", exact: true)) return "StarForce 3-5"; // Get the .sforce* section, if it exists - bool sforceSection = pex.ContainsSection(".sforce", exact: false); - if (sforceSection) + if (pex.ContainsSection(".sforce", exact: false)) return "StarForce 3-5"; return null; diff --git a/BinaryObjectScanner/Protection/Steam.cs b/BinaryObjectScanner/Protection/Steam.cs index 8c5b88a3..c10d4244 100644 --- a/BinaryObjectScanner/Protection/Steam.cs +++ b/BinaryObjectScanner/Protection/Steam.cs @@ -17,21 +17,21 @@ namespace BinaryObjectScanner.Protection return null; var name = pex.FileDescription; - if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Autorun Setup")) + if (name?.Contains("Steam Autorun Setup") == true) return "Steam"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client API")) + else if (name?.Contains("Steam Client API") == true) return "Steam"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Engine")) + else if (name?.Contains("Steam Client Engine") == true) return $"Steam Client Engine {pex.GetInternalVersion()}"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Service")) + else if (name?.Contains("Steam Client Service") == true) return "Steam"; name = pex.ProductName; - if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Autorun Setup")) + if (name?.Contains("Steam Autorun Setup") == true) return "Steam"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client API")) + else if (name?.Contains("Steam Client API") == true) return "Steam"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Steam Client Service")) + else if (name?.Contains("Steam Client Service") == true) return "Steam"; /// TODO: Add entry point checks diff --git a/BinaryObjectScanner/Protection/Tages.cs b/BinaryObjectScanner/Protection/Tages.cs index c6c239d8..b9bc72fc 100644 --- a/BinaryObjectScanner/Protection/Tages.cs +++ b/BinaryObjectScanner/Protection/Tages.cs @@ -51,7 +51,11 @@ namespace BinaryObjectScanner.Protection var matchers = new List { // (char)0xE8 + u + (char)0x00 + (char)0x00 + (char)0x00 + (char)0xE8 + ?? + ?? + (char)0xFF + (char)0xFF + "h" - new(new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8, null, null, 0xFF, 0xFF, 0x68 }, GetVersion, "TAGES"), + new(new byte?[] + { + 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8, null, null, + 0xFF, 0xFF, 0x68 + }, GetVersion, "TAGES"), }; var match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); diff --git a/BinaryObjectScanner/Protection/Themida.cs b/BinaryObjectScanner/Protection/Themida.cs index 933f70bd..8548f2d5 100644 --- a/BinaryObjectScanner/Protection/Themida.cs +++ b/BinaryObjectScanner/Protection/Themida.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using BinaryObjectScanner.Interfaces; +using BinaryObjectScanner.Interfaces; using SabreTools.Serialization.Wrappers; namespace BinaryObjectScanner.Protection @@ -33,7 +32,7 @@ namespace BinaryObjectScanner.Protection return null; // Get the "Arcsoft " section strings, if they exist - List? strs = pex.GetFirstSectionStrings("Arcsoft "); + var strs = pex.GetFirstSectionStrings("Arcsoft "); if (strs != null) { // Found in "uDigital Theatre.exe" in http://downloads.fyxm.net/ArcSoft-TotalMedia-23085.html (https://web.archive.org/web/20221114042838/http://files.fyxm.net/23/23085/totalmediatheatre3platinum_retail_tbyb_all.exe). diff --git a/BinaryObjectScanner/Protection/Uplay.cs b/BinaryObjectScanner/Protection/Uplay.cs index 2d483be2..d2ef8c5c 100644 --- a/BinaryObjectScanner/Protection/Uplay.cs +++ b/BinaryObjectScanner/Protection/Uplay.cs @@ -18,26 +18,26 @@ namespace BinaryObjectScanner.Protection return null; var name = pex.FileDescription; - if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect Installer")) + if (name?.Contains("Ubisoft Connect Installer") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect Service")) + else if (name?.Contains("Ubisoft Connect Service") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect WebCore")) + else if (name?.Contains("Ubisoft Connect WebCore") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Crash Reporter")) + else if (name?.Contains("Ubisoft Crash Reporter") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Game Launcher")) + else if (name?.Contains("Ubisoft Game Launcher") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Uplay Installer")) + else if (name?.Contains("Ubisoft Uplay Installer") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Uplay launcher")) + else if (name?.Contains("Uplay launcher") == true) return "Uplay / Ubisoft Connect"; // There's also a variant that looks like "Uplay installer" name = pex.ProductName; - if (!string.IsNullOrEmpty(name) && name!.Contains("Ubisoft Connect")) + if (name?.Contains("Ubisoft Connect") == true) return "Uplay / Ubisoft Connect"; - else if (!string.IsNullOrEmpty(name) && name!.Contains("Uplay")) + else if (name?.Contains("Uplay") == true) return "Uplay / Ubisoft Connect"; return null;