diff --git a/BinaryObjectScanner/FileType/Executable.cs b/BinaryObjectScanner/FileType/Executable.cs index 2894da4b..c9bfc9db 100644 --- a/BinaryObjectScanner/FileType/Executable.cs +++ b/BinaryObjectScanner/FileType/Executable.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using BinaryObjectScanner.Data; using BinaryObjectScanner.Interfaces; using SabreTools.IO.Extensions; @@ -235,308 +234,6 @@ namespace BinaryObjectScanner.FileType return protections; } - #endregion - - #region Helpers -- Remove when dependent libraries updated - - /// - /// Map to contain overlay strings to avoid rereading - /// - private static readonly Dictionary> _overlayStrings = []; - - /// - /// Lock object for - /// - private static readonly object _overlayStringsLock = new(); - - /// - /// Cached found string data in sections - /// - private static readonly Dictionary[]?> _sectionStringData = []; - - /// - /// Lock object for - /// - private static readonly object _sectionStringDataLock = new(); - - /// - /// Overlay strings, if they exist - /// - public static List? GetOverlayStrings(NewExecutable nex) - { - lock (_overlayStringsLock) - { - // Use the cached data if possible - if (_overlayStrings.TryGetValue(nex, out var strings)) - return strings; - - // Get the available source length, if possible - long dataLength = nex.Length; - if (dataLength == -1) - return null; - - // If a required property is missing - if (nex.Header == null || nex.SegmentTable == null || nex.ResourceTable?.ResourceTypes == null) - return null; - - try - { - // Get the overlay data, if possible - byte[]? overlayData = nex.OverlayData; - if (overlayData == null || overlayData.Length == 0) - { - _overlayStrings[nex] = []; - return []; - } - - // Otherwise, cache and return the strings - _overlayStrings[nex] = ReadStringsFrom(overlayData, charLimit: 3) ?? []; - return _overlayStrings[nex]; - } - catch - { - // Ignore the error for now - return []; - } - } - } - - /// - /// Overlay strings, if they exist - /// - public static List? GetOverlayStrings(PortableExecutable pex) - { - lock (_overlayStringsLock) - { - // Use the cached data if possible - if (_overlayStrings.TryGetValue(pex, out var strings)) - return strings; - - // Get the available source length, if possible - long dataLength = pex.Length; - if (dataLength == -1) - return null; - - // If the section table is missing - if (pex.SectionTable == null) - return null; - - // Get the overlay data, if possible - byte[]? overlayData = pex.OverlayData; - if (overlayData == null || overlayData.Length == 0) - { - _overlayStrings[pex] = []; - return []; - } - - // Otherwise, cache and return the strings - _overlayStrings[pex] = ReadStringsFrom(overlayData, charLimit: 4) ?? []; - return _overlayStrings[pex]; - } - } - - /// - /// Get the section strings based on index, if possible - /// - /// Index of the section to check for - /// Section strings on success, null on error - public static List? GetSectionStrings(PortableExecutable pex, int index) - { - lock (_sectionStringDataLock) - { - // If we already have cached data, just use that immediately - if (_sectionStringData.TryGetValue(pex, out var strings) - && strings != null - && strings[index] != null - && strings[index].Count > 0) - { - return strings[index]; - } - - // If we have no sections - if (pex.SectionNames == null || pex.SectionNames.Length == 0 || pex.SectionTable == null || pex.SectionTable.Length == 0) - return null; - - // Create the section string array if we have to - if (!_sectionStringData.ContainsKey(pex)) - _sectionStringData[pex] = new List[pex.SectionNames.Length]; - - // If the section doesn't exist - if (index < 0 || index >= pex.SectionTable.Length) - return null; - - // Get the section data from the table - var section = pex.SectionTable[index]; - if (section == null) - return null; - - // Get the section data, if possible - byte[]? sectionData = pex.GetSectionData(index); - if (sectionData == null || sectionData.Length == 0) - { - _sectionStringData[pex]![index] = []; - return []; - } - - // Otherwise, cache and return the strings - _sectionStringData[pex]![index] = ReadStringsFrom(sectionData, charLimit: 4) ?? []; - return _sectionStringData[pex]![index]; - } - } - - /// - /// Get the first section strings based on name, if possible - /// - /// Name of the section to check for - /// True to enable exact matching of names, false for starts-with - /// Section strings on success, null on error - public static List? GetFirstSectionStrings(PortableExecutable pex, string? name, bool exact = false) - { - // If we have no sections - if (pex.SectionNames == null || pex.SectionNames.Length == 0 || pex.SectionTable == null || pex.SectionTable.Length == 0) - return null; - - // If the section doesn't exist - if (!pex.ContainsSection(name, exact)) - return null; - - // Get the first index of the section - int index = Array.IndexOf(pex.SectionNames, name); - return GetSectionStrings(pex, index); - } - - /// - /// Get the last section strings based on name, if possible - /// - /// Name of the section to check for - /// True to enable exact matching of names, false for starts-with - /// Section strings on success, null on error - public static List? GetLastSectionStrings(PortableExecutable pex, string? name, bool exact = false) - { - // If we have no sections - if (pex.SectionNames == null || pex.SectionNames.Length == 0 || pex.SectionTable == null || pex.SectionTable.Length == 0) - return null; - - // If the section doesn't exist - if (!pex.ContainsSection(name, exact)) - return null; - - // Get the last index of the section - int index = Array.LastIndexOf(pex.SectionNames, name); - return GetSectionStrings(pex, index); - } - - /// - /// Read string data from the source - /// - /// Number of characters needed to be a valid string, default 5 - /// String list containing the requested data, null on error - private static List? ReadStringsFrom(byte[]? input, int charLimit = 5) - { - // Validate the data - if (input == null || input.Length == 0) - return null; - - // Limit to 16KiB of data - if (input.Length > 16384) - { - int offset = 0; - input = input.ReadBytes(ref offset, 16384); - } - - // Check for ASCII strings - var asciiStrings = ReadStringsWithEncoding(input, charLimit, Encoding.ASCII); - - // Check for UTF-8 strings - // We are limiting the check for Unicode characters with a second byte of 0x00 for now - var utf8Strings = ReadStringsWithEncoding(input, charLimit, Encoding.UTF8); - - // Ignore duplicate strings across encodings - List sourceStrings = [.. asciiStrings, .. utf8Strings]; - - // Sort the strings and return - sourceStrings.Sort(); - return sourceStrings; - } - - /// - /// Read string data from the source with an encoding - /// - /// Byte array representing the source data - /// Number of characters needed to be a valid string - /// Character encoding to use for checking - /// String list containing the requested data, empty on error - /// - /// This method has a couple of notable implementation details: - /// - Strings can only have a maximum of 64 characters - /// - Characters that fall outside of the extended ASCII set will be unused - /// -#if NET20 - private static List ReadStringsWithEncoding(byte[]? bytes, int charLimit, Encoding encoding) -#else - private static HashSet ReadStringsWithEncoding(byte[]? bytes, int charLimit, Encoding encoding) -#endif - { - if (bytes == null || bytes.Length == 0) - return []; - if (charLimit <= 0 || charLimit > bytes.Length) - return []; - - // Create the string set to return -#if NET20 - var strings = new List(); -#else - var strings = new HashSet(); -#endif - - // Open the text reader with the correct encoding - using var ms = new MemoryStream(bytes); - using var reader = new StreamReader(ms, encoding); - - // Create a string builder for the loop - var sb = new StringBuilder(); - - // Check for strings - long lastOffset = 0; - while (!reader.EndOfStream) - { - // Read the next character from the stream - char c = (char)reader.Read(); - - // If the character is invalid - if (char.IsControl(c) || (c & 0xFF00) != 0) - { - // Seek to the end of the last found string - string str = sb.ToString(); - lastOffset += encoding.GetByteCount(str) + 1; - ms.Seek(lastOffset, SeekOrigin.Begin); - reader.DiscardBufferedData(); - - // Add the string if long enough - if (str.Length >= charLimit) - strings.Add(str); - - // Clear the builder and continue -#if NET20 || NET35 - sb = new(); -#else - sb.Clear(); -#endif - continue; - } - - // Otherwise, add the character to the builder and continue - sb.Append(c); - } - - // Handle any remaining data - if (sb.Length >= charLimit) - strings.Add(sb.ToString()); - - return strings; - } - - #endregion } } diff --git a/BinaryObjectScanner/Packer/AdvancedInstaller.cs b/BinaryObjectScanner/Packer/AdvancedInstaller.cs index ae18fdb9..1f2335af 100644 --- a/BinaryObjectScanner/Packer/AdvancedInstaller.cs +++ b/BinaryObjectScanner/Packer/AdvancedInstaller.cs @@ -11,7 +11,7 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .rdata section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { if (strs.Exists(s => s.Contains("Software\\Caphyon\\Advanced Installer"))) diff --git a/BinaryObjectScanner/Packer/Crunch.cs b/BinaryObjectScanner/Packer/Crunch.cs index 1943c0f6..3b7c1960 100644 --- a/BinaryObjectScanner/Packer/Crunch.cs +++ b/BinaryObjectScanner/Packer/Crunch.cs @@ -13,7 +13,7 @@ namespace BinaryObjectScanner.Packer { // Get the last section strings, if they exist var sections = pex.Model.SectionTable ?? []; - var strs = FileType.Executable.GetSectionStrings(pex, sections.Length - 1); + var strs = pex.GetSectionStrings(sections.Length - 1); if (strs != null) { if (strs.Exists(s => s.Contains("BITARTS"))) diff --git a/BinaryObjectScanner/Packer/DotFuscator.cs b/BinaryObjectScanner/Packer/DotFuscator.cs index 5fbc5b99..4be90519 100644 --- a/BinaryObjectScanner/Packer/DotFuscator.cs +++ b/BinaryObjectScanner/Packer/DotFuscator.cs @@ -10,7 +10,7 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .text section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + var strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { if (strs.Exists(s => s.Contains("DotfuscatorAttribute"))) diff --git a/BinaryObjectScanner/Packer/GenteeInstaller.cs b/BinaryObjectScanner/Packer/GenteeInstaller.cs index d4070570..f983cc31 100644 --- a/BinaryObjectScanner/Packer/GenteeInstaller.cs +++ b/BinaryObjectScanner/Packer/GenteeInstaller.cs @@ -11,7 +11,7 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("Gentee installer"))) diff --git a/BinaryObjectScanner/Packer/InnoSetup.cs b/BinaryObjectScanner/Packer/InnoSetup.cs index fbf24ab3..c6a068b7 100644 --- a/BinaryObjectScanner/Packer/InnoSetup.cs +++ b/BinaryObjectScanner/Packer/InnoSetup.cs @@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { var str = strs.Find(s => s.StartsWith("Inno Setup Setup Data")); diff --git a/BinaryObjectScanner/Packer/InstallerVISE.cs b/BinaryObjectScanner/Packer/InstallerVISE.cs index a3db2e01..ed6bb462 100644 --- a/BinaryObjectScanner/Packer/InstallerVISE.cs +++ b/BinaryObjectScanner/Packer/InstallerVISE.cs @@ -12,7 +12,7 @@ namespace BinaryObjectScanner.Packer public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("ViseMain"))) diff --git a/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs b/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs index 97b9f009..b05fd37a 100644 --- a/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs +++ b/BinaryObjectScanner/Packer/MicrosoftCABSFX.cs @@ -20,7 +20,7 @@ namespace BinaryObjectScanner.Packer return $"Microsoft CAB SFX {GetVersion(pex)}"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("wextract_cleanup"))) @@ -28,7 +28,7 @@ namespace BinaryObjectScanner.Packer } // Get the .text section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { // This detects a different but similar type of SFX that uses Microsoft CAB files. diff --git a/BinaryObjectScanner/Packer/NSIS.cs b/BinaryObjectScanner/Packer/NSIS.cs index d747672e..6cdd4f51 100644 --- a/BinaryObjectScanner/Packer/NSIS.cs +++ b/BinaryObjectScanner/Packer/NSIS.cs @@ -14,7 +14,7 @@ namespace BinaryObjectScanner.Packer return $"NSIS {name!.Substring("Nullsoft Install System".Length).Trim()}"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("NullsoftInst"))) diff --git a/BinaryObjectScanner/Protection/ActiveMARK.cs b/BinaryObjectScanner/Protection/ActiveMARK.cs index f57ab77c..9fde52d0 100644 --- a/BinaryObjectScanner/Protection/ActiveMARK.cs +++ b/BinaryObjectScanner/Protection/ActiveMARK.cs @@ -40,7 +40,7 @@ namespace BinaryObjectScanner.Protection } // Get the .data section strings, if they exist - var strs = FileType.Executable.GetLastSectionStrings(pex, ".data"); + var strs = pex.GetLastSectionStrings(".data"); if (strs != null) { if (strs.Exists(s => s.Contains("MPRMMGVA")) @@ -62,14 +62,14 @@ namespace BinaryObjectScanner.Protection } // Get the overlay data, if it exists - if (FileType.Executable.GetOverlayStrings(pex) != null) + if (pex.OverlayStrings != null) { - if (FileType.Executable.GetOverlayStrings(pex)!.Exists(s => s.Contains("TMSAMVOH"))) + if (pex.OverlayStrings.Exists(s => s.Contains("TMSAMVOH"))) return "ActiveMARK"; } // Get the last .bss section strings, if they exist - strs = FileType.Executable.GetLastSectionStrings(pex, ".bss"); + strs = pex.GetLastSectionStrings(".bss"); if (strs != null) { if (strs.Exists(s => s.Contains("TMSAMVOF"))) diff --git a/BinaryObjectScanner/Protection/AlphaROM.cs b/BinaryObjectScanner/Protection/AlphaROM.cs index e984253c..6786b729 100644 --- a/BinaryObjectScanner/Protection/AlphaROM.cs +++ b/BinaryObjectScanner/Protection/AlphaROM.cs @@ -48,7 +48,7 @@ namespace BinaryObjectScanner.Protection // TODO: Add version detection for Alpha-ROM. // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("\\SETTEC"))) @@ -59,7 +59,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { if (strs.Exists(s => s.Contains("This Game is Japan Only"))) @@ -75,10 +75,10 @@ namespace BinaryObjectScanner.Protection } // Get the overlay data, if it exists - if (FileType.Executable.GetOverlayStrings(pex) != null) + if (pex.OverlayStrings != null) { // Found in Redump entry 84122. - if (FileType.Executable.GetOverlayStrings(pex)!.Exists(s => s.Contains("SETTEC0000"))) + if (pex.OverlayStrings.Exists(s => s.Contains("SETTEC0000"))) return "Alpha-ROM"; } diff --git a/BinaryObjectScanner/Protection/Armadillo.cs b/BinaryObjectScanner/Protection/Armadillo.cs index 0863a595..4cd5cc2a 100644 --- a/BinaryObjectScanner/Protection/Armadillo.cs +++ b/BinaryObjectScanner/Protection/Armadillo.cs @@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Protection foreach (var sectionName in Array.FindAll(pex.SectionNames ?? [], s => s != null && s.EndsWith("1"))) { // Get the section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, sectionName); + var strs = pex.GetFirstSectionStrings(sectionName); if (strs != null) { if (strs.Exists(s => s.Contains("ARMDEBUG"))) diff --git a/BinaryObjectScanner/Protection/ByteShield.cs b/BinaryObjectScanner/Protection/ByteShield.cs index 3fe48ed9..20103c83 100644 --- a/BinaryObjectScanner/Protection/ByteShield.cs +++ b/BinaryObjectScanner/Protection/ByteShield.cs @@ -82,7 +82,7 @@ namespace BinaryObjectScanner.Protection return "ByteShield"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in "LineRider2.exe" in Redump entry 6236 @@ -91,7 +91,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { // Found in "ByteShield.dll" in Redump entry 6236 @@ -108,7 +108,7 @@ namespace BinaryObjectScanner.Protection } // Get the .ret section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".ret"); + strs = pex.GetFirstSectionStrings(".ret"); if (strs != null) { // TODO: Figure out if this specifically indicates if the file is encrypted diff --git a/BinaryObjectScanner/Protection/CDDVDCops.cs b/BinaryObjectScanner/Protection/CDDVDCops.cs index c708f468..bd53ea7f 100644 --- a/BinaryObjectScanner/Protection/CDDVDCops.cs +++ b/BinaryObjectScanner/Protection/CDDVDCops.cs @@ -190,7 +190,7 @@ namespace BinaryObjectScanner.Protection // Found in "bib.dll" in IA item "https://archive.org/details/cover_202501" // This contains the version section that the Content Check looked for. There are likely other sections // that may contain it. Update when more are found. - var strs = FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings("DATA"); if (strs != null) { var match = strs.Find(s => s.Contains(" ver. ") && (s.Contains("CD-Cops, ") || s.Contains("DVD-Cops, "))); diff --git a/BinaryObjectScanner/Protection/CDSHiELDSE.cs b/BinaryObjectScanner/Protection/CDSHiELDSE.cs index 362dc2a7..8f632769 100644 --- a/BinaryObjectScanner/Protection/CDSHiELDSE.cs +++ b/BinaryObjectScanner/Protection/CDSHiELDSE.cs @@ -18,7 +18,7 @@ namespace BinaryObjectScanner.Protection //} // Get the code/CODE section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, "code") ?? FileType.Executable.GetFirstSectionStrings(pex, "CODE"); + var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE"); if (strs != null) { if (strs.Exists(s => s.Contains("~0017.tmp"))) diff --git a/BinaryObjectScanner/Protection/ChosenBytesCodeLock.cs b/BinaryObjectScanner/Protection/ChosenBytesCodeLock.cs index ffb99c29..8cfb7ed7 100644 --- a/BinaryObjectScanner/Protection/ChosenBytesCodeLock.cs +++ b/BinaryObjectScanner/Protection/ChosenBytesCodeLock.cs @@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Protection return $"ChosenBytes Code-Lock {pex.ProductVersion}"; // Get the .text section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + var strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { if (strs.Exists(s => s.Contains("CODE-LOCK.OCX"))) diff --git a/BinaryObjectScanner/Protection/CopyX.cs b/BinaryObjectScanner/Protection/CopyX.cs index 256508a1..f14de804 100644 --- a/BinaryObjectScanner/Protection/CopyX.cs +++ b/BinaryObjectScanner/Protection/CopyX.cs @@ -66,7 +66,7 @@ namespace BinaryObjectScanner.Protection if (sections == null) return null; - if (FileType.Executable.GetOverlayStrings(pex) != null) + if (pex.OverlayStrings != null) { // Checks if main executable contains reference to optgraph.dll. // This might be better removed later, as Redump ID 82475 is a false positive, and also doesn't actually @@ -76,11 +76,11 @@ namespace BinaryObjectScanner.Protection // TODO: This might need to check every single section. Unsure until more samples are acquired. // TODO: TKKG also has an NE 3.1x executable with a reference. This can be added later. // Samples: Redump ID 108150 - if (FileType.Executable.GetOverlayStrings(pex)!.Exists(s => s.Contains("optgraph.dll"))) + if (pex.OverlayStrings.Exists(s => s.Contains("optgraph.dll"))) return "copy-X [Check disc for physical ring]"; } - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { // Samples: Redump ID 82475, German Emergency 2 Deluxe, Redump ID 48393 diff --git a/BinaryObjectScanner/Protection/CrypKey.cs b/BinaryObjectScanner/Protection/CrypKey.cs index f6493cab..dc259ec0 100644 --- a/BinaryObjectScanner/Protection/CrypKey.cs +++ b/BinaryObjectScanner/Protection/CrypKey.cs @@ -16,7 +16,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the code/CODE section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, "code") ?? FileType.Executable.GetFirstSectionStrings(pex, "CODE"); + var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE"); if (strs != null) { // Found in "NECRO95.EXE" in IA item "NBECRORV11". diff --git a/BinaryObjectScanner/Protection/ElectronicArts.cs b/BinaryObjectScanner/Protection/ElectronicArts.cs index ddf2f71a..90f16b7d 100644 --- a/BinaryObjectScanner/Protection/ElectronicArts.cs +++ b/BinaryObjectScanner/Protection/ElectronicArts.cs @@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Protection return $"EA CdKey Registration Module {pex.GetInternalVersion()}"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("EReg Config Form"))) @@ -35,7 +35,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { if (strs.Exists(s => s.Contains("GenericEA")) && strs.Exists(s => s.Contains("Activation"))) @@ -43,7 +43,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { if (strs.Exists(s => s.Contains("GenericEA")) && strs.Exists(s => s.Contains("Activation"))) diff --git a/BinaryObjectScanner/Protection/HexalockAutoLock.cs b/BinaryObjectScanner/Protection/HexalockAutoLock.cs index b33aafa4..a09d0011 100644 --- a/BinaryObjectScanner/Protection/HexalockAutoLock.cs +++ b/BinaryObjectScanner/Protection/HexalockAutoLock.cs @@ -50,7 +50,7 @@ namespace BinaryObjectScanner.Protection return $"Hexalock AutoLock 4.5"; // Get the .text section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".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. @@ -59,7 +59,7 @@ namespace BinaryObjectScanner.Protection } // Get the code/CODE section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, "code") ?? FileType.Executable.GetFirstSectionStrings(pex, "CODE"); + strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE"); if (strs != null) { // Found in "launcher.exe" in "Sea Adventure / Adventure de la Mer" by Compedia. @@ -68,7 +68,7 @@ namespace BinaryObjectScanner.Protection } // Get the UPX1 section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, "UPX1"); + strs = pex.GetFirstSectionStrings("UPX1"); if (strs != null) { // Found in "postmanpat.exe" in "Postman Pat" by Compedia. diff --git a/BinaryObjectScanner/Protection/ImpulseReactor.cs b/BinaryObjectScanner/Protection/ImpulseReactor.cs index d1b31e84..b018b312 100644 --- a/BinaryObjectScanner/Protection/ImpulseReactor.cs +++ b/BinaryObjectScanner/Protection/ImpulseReactor.cs @@ -34,7 +34,7 @@ namespace BinaryObjectScanner.Protection // Get the .rdata section strings, if they exist bool containsCheck2 = false; - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { containsCheck2 = strs.Exists(s => s.EndsWith("ATTLIST")) diff --git a/BinaryObjectScanner/Protection/InterLok.cs b/BinaryObjectScanner/Protection/InterLok.cs index cf36aed2..de06b10c 100644 --- a/BinaryObjectScanner/Protection/InterLok.cs +++ b/BinaryObjectScanner/Protection/InterLok.cs @@ -10,7 +10,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .rsrc section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rsrc"); + var strs = pex.GetFirstSectionStrings(".rsrc"); if (strs != null) { // Found in "nfsc_link.exe" in IA item "nfscorigin". diff --git a/BinaryObjectScanner/Protection/KalypsoLauncher.cs b/BinaryObjectScanner/Protection/KalypsoLauncher.cs index a80587da..dd610f25 100644 --- a/BinaryObjectScanner/Protection/KalypsoLauncher.cs +++ b/BinaryObjectScanner/Protection/KalypsoLauncher.cs @@ -39,7 +39,7 @@ namespace BinaryObjectScanner.Protection return $"Kalypso Launcher {pex.GetInternalVersion()}"; // Get the .text section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { // Found in "TFT.exe" in Redump entry 95617. diff --git a/BinaryObjectScanner/Protection/LabelGate.cs b/BinaryObjectScanner/Protection/LabelGate.cs index be1e2e68..e1b09cd1 100644 --- a/BinaryObjectScanner/Protection/LabelGate.cs +++ b/BinaryObjectScanner/Protection/LabelGate.cs @@ -31,7 +31,7 @@ namespace BinaryObjectScanner.Protection return $"LabelGate CD2 Media Player"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in "START.EXE" (Redump entry 95010 and product ID SVWC-7185). diff --git a/BinaryObjectScanner/Protection/Macrovision.CDilla.cs b/BinaryObjectScanner/Protection/Macrovision.CDilla.cs index 43ce79dc..3f554f29 100644 --- a/BinaryObjectScanner/Protection/Macrovision.CDilla.cs +++ b/BinaryObjectScanner/Protection/Macrovision.CDilla.cs @@ -113,7 +113,7 @@ namespace BinaryObjectScanner.Protection return $"C-Dilla License Management System"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in "DJMixStation\DJMixStation.exe" in IA item "ejay_nestle_trial". diff --git a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs index 3d555658..27de3c46 100644 --- a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs +++ b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs @@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Protection internal static string? CactusDataShieldCheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("\\*.CDS"))) diff --git a/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs b/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs index 1bc72555..d3f3a201 100644 --- a/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs +++ b/BinaryObjectScanner/Protection/Macrovision.FLEXnet.cs @@ -51,7 +51,7 @@ namespace BinaryObjectScanner.Protection return $"FlexLM {pex.ProductVersion}"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in "FLEXLM.CPL", "INSTALLS.EXE", "LMGR326B.DLL", "LMGRD.EXE", and "TAKEFIVE.EXE" in IA item "prog-17_202403". diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs index 48905e21..75b955b3 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs @@ -98,7 +98,7 @@ namespace BinaryObjectScanner.Protection return "SafeCast"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in "DJMixStation\DJMixStation.exe" in IA item "ejay_nestle_trial". diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs index 676cf1f7..24d62740 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs @@ -65,7 +65,7 @@ namespace BinaryObjectScanner.Protection } // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { // Found in Redump entries 14928, 25579, 32751. diff --git a/BinaryObjectScanner/Protection/Macrovision.cs b/BinaryObjectScanner/Protection/Macrovision.cs index 323690ba..858eeb42 100644 --- a/BinaryObjectScanner/Protection/Macrovision.cs +++ b/BinaryObjectScanner/Protection/Macrovision.cs @@ -74,7 +74,7 @@ namespace BinaryObjectScanner.Protection resultsList.Add(sectionMatch); // Get the .data section, if it exists, for protected sections. - sectionMatch = CheckSectionForProtection(file, includeDebug, FileType.Executable.GetFirstSectionStrings(pex, ".data"), pex.GetFirstSectionData(".data"), true); + sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), true); if (sectionMatch != null) resultsList.Add(sectionMatch!); @@ -107,7 +107,7 @@ namespace BinaryObjectScanner.Protection resultsList.Add(sectionMatch); // Check the .data section, if it exists, for protected sections. - sectionMatch = CheckSectionForProtection(file, includeDebug, FileType.Executable.GetFirstSectionStrings(pex, ".data"), pex.GetFirstSectionData(".data"), false); + sectionMatch = CheckSectionForProtection(file, includeDebug, pex.GetFirstSectionStrings(".data"), pex.GetFirstSectionData(".data"), false); if (sectionMatch != null) resultsList.Add(sectionMatch); } diff --git a/BinaryObjectScanner/Protection/MediaMax.cs b/BinaryObjectScanner/Protection/MediaMax.cs index 06c229ee..b6f13900 100644 --- a/BinaryObjectScanner/Protection/MediaMax.cs +++ b/BinaryObjectScanner/Protection/MediaMax.cs @@ -37,7 +37,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 - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { if (strs.Exists(s => s.Contains("CD3 Launch Error"))) diff --git a/BinaryObjectScanner/Protection/ProtectDISC.cs b/BinaryObjectScanner/Protection/ProtectDISC.cs index e2cad07f..66c60d08 100644 --- a/BinaryObjectScanner/Protection/ProtectDISC.cs +++ b/BinaryObjectScanner/Protection/ProtectDISC.cs @@ -54,7 +54,7 @@ namespace BinaryObjectScanner.Protection if (sections.Length > 1) { // Get the n - 1 section strings, if they exist - var strs = FileType.Executable.GetSectionStrings(pex, sections.Length - 2); + var strs = pex.GetSectionStrings(sections.Length - 2); if (strs != null) { var str = strs.Find(s => s.Contains("VOB ProtectCD")); diff --git a/BinaryObjectScanner/Protection/RainbowSentinel.cs b/BinaryObjectScanner/Protection/RainbowSentinel.cs index c9d15068..4a663ce5 100644 --- a/BinaryObjectScanner/Protection/RainbowSentinel.cs +++ b/BinaryObjectScanner/Protection/RainbowSentinel.cs @@ -203,7 +203,7 @@ namespace BinaryObjectScanner.Protection return "Rainbow Sentinel Driver"; // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "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". @@ -216,7 +216,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { // Found in "SP32W.DLL" in IA item "pcwkcd-1296". @@ -241,7 +241,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rsrc section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rsrc"); + strs = pex.GetFirstSectionStrings(".rsrc"); if (strs != null) { // Found in "WINMON.exe" in IA item "czchip199707cd". @@ -250,7 +250,7 @@ namespace BinaryObjectScanner.Protection } // Get the .text section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { // Found in "ACLT.HWL" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]", folder "\aclt\DRV\W95LOCK". diff --git a/BinaryObjectScanner/Protection/RealArcade.cs b/BinaryObjectScanner/Protection/RealArcade.cs index 7ce10ad6..3a441008 100644 --- a/BinaryObjectScanner/Protection/RealArcade.cs +++ b/BinaryObjectScanner/Protection/RealArcade.cs @@ -19,7 +19,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data"); + var strs = pex.GetFirstSectionStrings(".data"); if (strs != null) { // Found in "rebound.exe" in the installation directory for "Rebound" in IA item "Nova_RealArcadeCD_USA". diff --git a/BinaryObjectScanner/Protection/Roxxe.cs b/BinaryObjectScanner/Protection/Roxxe.cs index b50bf341..c5197b12 100644 --- a/BinaryObjectScanner/Protection/Roxxe.cs +++ b/BinaryObjectScanner/Protection/Roxxe.cs @@ -17,7 +17,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the code/CODE section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, "code") ?? FileType.Executable.GetFirstSectionStrings(pex, "CODE"); + var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE"); if (strs != null) { // Found in "Owar.exe" in IA item "game4u-22-cd". @@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Protection // Get the .rsrc section strings, if they exist // TODO: Check for these strings specifically within the application-defined resource that they're found in, not just the generic resource section. - strs = FileType.Executable.GetFirstSectionStrings(pex, ".rsrc"); + strs = pex.GetFirstSectionStrings(".rsrc"); if (strs != null) { // Found in "Owar.exe" in IA items "game4u-22-cd" and "original-war". diff --git a/BinaryObjectScanner/Protection/SecuROM.cs b/BinaryObjectScanner/Protection/SecuROM.cs index 1312f00a..0f59c174 100644 --- a/BinaryObjectScanner/Protection/SecuROM.cs +++ b/BinaryObjectScanner/Protection/SecuROM.cs @@ -64,9 +64,9 @@ namespace BinaryObjectScanner.Protection return $"SecuROM SLL Protected (for SecuROM v8.x)"; // Search after the last section - if (FileType.Executable.GetOverlayStrings(pex) != null) + if (pex.OverlayStrings != null) { - if (FileType.Executable.GetOverlayStrings(pex)!.Exists(s => s == "AddD")) + if (pex.OverlayStrings.Exists(s => s == "AddD")) return $"SecuROM {GetV4Version(pex)}"; } @@ -98,7 +98,7 @@ namespace BinaryObjectScanner.Protection } // Get the .rdata section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + var strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { // Both have the identifier found within `.rdata` but the version is within `.data` diff --git a/BinaryObjectScanner/Protection/SoftLock.cs b/BinaryObjectScanner/Protection/SoftLock.cs index b54a4ca5..61414598 100644 --- a/BinaryObjectScanner/Protection/SoftLock.cs +++ b/BinaryObjectScanner/Protection/SoftLock.cs @@ -56,7 +56,7 @@ namespace BinaryObjectScanner.Protection // and dialog boxes. See if any of those are unique to SoftLock. // Found in "TafseerVer4.exe" in IA item "TAFSEERVER4SETUP" - var strings = FileType.Executable.GetFirstSectionStrings(pex, ".section") ?? []; + var strings = pex.GetFirstSectionStrings(".section") ?? []; if (strings.Exists(s => s.Contains("SOFTLOCKPROTECTION"))) return "SoftLock"; diff --git a/BinaryObjectScanner/Protection/SolidShield.cs b/BinaryObjectScanner/Protection/SolidShield.cs index 976803c2..a1aa4175 100644 --- a/BinaryObjectScanner/Protection/SolidShield.cs +++ b/BinaryObjectScanner/Protection/SolidShield.cs @@ -79,7 +79,7 @@ namespace BinaryObjectScanner.Protection for (int i = Math.Max(sections.Length - 2, 0); i < sections.Length; i++) { // Get the nth section strings, if they exist - var strs = FileType.Executable.GetSectionStrings(pex, i); + var strs = pex.GetSectionStrings(i); if (strs != null) { var str = strs.Find(s => s.Contains("Solidshield ")); diff --git a/BinaryObjectScanner/Protection/Sysiphus.cs b/BinaryObjectScanner/Protection/Sysiphus.cs index af6ae6c5..c55f4110 100644 --- a/BinaryObjectScanner/Protection/Sysiphus.cs +++ b/BinaryObjectScanner/Protection/Sysiphus.cs @@ -10,7 +10,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .data/DATA section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, ".data") ?? FileType.Executable.GetFirstSectionStrings(pex, "DATA"); + var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA"); if (strs != null) { var str = strs.Find(s => s.Contains("V SUHPISYS")); diff --git a/BinaryObjectScanner/Protection/Themida.cs b/BinaryObjectScanner/Protection/Themida.cs index 9db85506..51bde32f 100644 --- a/BinaryObjectScanner/Protection/Themida.cs +++ b/BinaryObjectScanner/Protection/Themida.cs @@ -27,7 +27,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the "Arcsoft " section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, "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/WTMCDProtect.cs b/BinaryObjectScanner/Protection/WTMCDProtect.cs index 63feccd6..3bfd5a45 100644 --- a/BinaryObjectScanner/Protection/WTMCDProtect.cs +++ b/BinaryObjectScanner/Protection/WTMCDProtect.cs @@ -25,7 +25,7 @@ namespace BinaryObjectScanner.Protection return "WTM Protection Viewer"; // Get the code/CODE section strings, if they exist - var strs = FileType.Executable.GetFirstSectionStrings(pex, "code") ?? FileType.Executable.GetFirstSectionStrings(pex, "CODE"); + var strs = pex.GetFirstSectionStrings("code") ?? pex.GetFirstSectionStrings("CODE"); if (strs != null) { if (strs.Exists(s => s.Contains("wtmdum.imp"))) @@ -33,7 +33,7 @@ namespace BinaryObjectScanner.Protection } // Get the .text section strings, if they exist - strs = FileType.Executable.GetFirstSectionStrings(pex, ".text"); + strs = pex.GetFirstSectionStrings(".text"); if (strs != null) { if (strs.Exists(s => s.Contains("WTM DIGITAL Photo Protect"))) diff --git a/BinaryObjectScanner/Protection/XCP.cs b/BinaryObjectScanner/Protection/XCP.cs index ea21461c..eea19cd9 100644 --- a/BinaryObjectScanner/Protection/XCP.cs +++ b/BinaryObjectScanner/Protection/XCP.cs @@ -14,7 +14,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the .rdata section strings, if they exist - List? strs = FileType.Executable.GetFirstSectionStrings(pex, ".rdata"); + List? strs = pex.GetFirstSectionStrings(".rdata"); if (strs != null) { if (strs.Exists(s => s.Contains("XCP.DAT")))