diff --git a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs index 66351076..b031e351 100644 --- a/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs +++ b/BurnOutSharp/ExecutableType/Microsoft/Entries/ResourceDirectoryTableEntry.cs @@ -127,8 +127,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft.Entries int dataEntryAddress = (int)(rdte.DataEntryOffset + sectionStart); if (dataEntryAddress > 0 && dataEntryAddress < content.Length) rdte.DataEntry = ResourceDataEntry.Deserialize(content, ref dataEntryAddress, sections); - - //Console.WriteLine($"At {dataEntryAddress}: {rdte.DataEntry.DataAsUTF8String}"); } else { diff --git a/BurnOutSharp/PackerType/Armadillo.cs b/BurnOutSharp/PackerType/Armadillo.cs index 429eb1d0..e210c16f 100644 --- a/BurnOutSharp/PackerType/Armadillo.cs +++ b/BurnOutSharp/PackerType/Armadillo.cs @@ -17,7 +17,7 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - // Get the .nicode section, if it exists -- TODO: Confirm this check with a real disc + // Get the .nicode section, if it exists var nicodeSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".nicode")); if (nicodeSection != null) return "Armadillo"; diff --git a/BurnOutSharp/PackerType/CExe.cs b/BurnOutSharp/PackerType/CExe.cs index 46898d7c..816292f2 100644 --- a/BurnOutSharp/PackerType/CExe.cs +++ b/BurnOutSharp/PackerType/CExe.cs @@ -37,6 +37,11 @@ namespace BurnOutSharp.PackerType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug, PortableExecutable pex, NewExecutable nex) { + // Get the sections from the executable, if possible + var sections = pex?.SectionTable; + if (sections == null) + return null; + var contentMatchSets = GetContentMatchSets(); if (contentMatchSets != null && contentMatchSets.Any()) return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); diff --git a/BurnOutSharp/PackerType/PECompact.cs b/BurnOutSharp/PackerType/PECompact.cs index cffd0068..9c3c94cc 100644 --- a/BurnOutSharp/PackerType/PECompact.cs +++ b/BurnOutSharp/PackerType/PECompact.cs @@ -15,11 +15,10 @@ namespace BurnOutSharp.PackerType var sections = pex?.SectionTable; if (sections == null) return null; - - // TODO: Do something with this information - - // PE Compact 1 uses the symbol table pointer in the file header to store the value 1329808720 / 50 45 43 4F / PECO - // Console.WriteLine($"{file} symbol table pointer: {pex.ImageFileHeader.PointerToSymbolTable}"); - // Console.WriteLine($"{file} ptr as string: {Encoding.ASCII.GetString(BitConverter.GetBytes(pex.ImageFileHeader.PointerToSymbolTable))}"); + + // 0x4F434550 is "PECO" + if (pex.ImageFileHeader.PointerToSymbolTable == 0x4F434550) + return "PE Compact v1.x"; // TODO: Get more granular version detection. PiD is somehow able to detect version ranges based // on the data in the file. This may be related to information in other fields diff --git a/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs b/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs index 213cab38..6ad4bfbc 100644 --- a/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs +++ b/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs @@ -14,7 +14,7 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .cenega section, if it exists -- TODO: Confirm this check with a real disc + // Get the .cenega section, if it exists var cenegaSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".cenega")); if (cenegaSection != null) return "Cenega ProtectDVD"; diff --git a/BurnOutSharp/ProtectionType/ElectronicArts.cs b/BurnOutSharp/ProtectionType/ElectronicArts.cs index dd37bfcf..ea31b2fc 100644 --- a/BurnOutSharp/ProtectionType/ElectronicArts.cs +++ b/BurnOutSharp/ProtectionType/ElectronicArts.cs @@ -14,6 +14,9 @@ namespace BurnOutSharp.ProtectionType // TODO: Do more research into the Cucko protection: // - Reference to `EASTL` and `EAStdC` are standard for EA products and does not indicate Cucko by itself // - There's little information outside of PiD detection that actually knows about Cucko + // - Look into `ccinstall`, `Services/EACOM`, `TSLHost`, `SIGS/UploadThread/exchangeAuthToken`, + // `blazeURL`, `psapi.dll`, `DasmX86Dll.dll`, `NVCPL.dll`, `iphlpapi.dll`, `dbghelp.dll`, + // `WS2_32.dll`, /// private List GetContentMatchSets() { diff --git a/BurnOutSharp/ProtectionType/Intenium.cs b/BurnOutSharp/ProtectionType/Intenium.cs index 2ac43de4..d514978e 100644 --- a/BurnOutSharp/ProtectionType/Intenium.cs +++ b/BurnOutSharp/ProtectionType/Intenium.cs @@ -1,8 +1,5 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using BurnOutSharp.ExecutableType.Microsoft; -using BurnOutSharp.Matching; +using BurnOutSharp.ExecutableType.Microsoft; +using BurnOutSharp.Tools; namespace BurnOutSharp.ProtectionType { @@ -32,30 +29,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // TODO: This isn't working for some reason. Look into it a bit more - // var resource = Utilities.FindResourceInSection(pex.ResourceSection, dataContains: "Trial\0P"); - // if (resource != null) - // return "INTENIUM Trial & Buy Protection"; - - // TODO: Find this inside of the .rsrc section using the executable header - // Get the .rsrc section, if it exists - var rsrcSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".rsrc")); - if (rsrcSection != null) - { - int sectionAddr = (int)rsrcSection.PointerToRawData; - int sectionEnd = sectionAddr + (int)rsrcSection.VirtualSize; - var matchers = new List - { - // Trial + (char)0x00 + P - new ContentMatchSet( - new ContentMatch(new byte?[] { 0x54, 0x72, 0x69, 0x61, 0x6C, 0x00, 0x50 }, start: sectionAddr, end: sectionEnd), - "INTENIUM Trial & Buy Protection"), - }; - - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + var fileNameResource = Utilities.FindResourceInSection(pex.ResourceSection, dataContains: $"NO NESTED PRMS SUPPORTED"); + if (fileNameResource != null) + return "ITENIUM Trial & Buy Protection"; return null; } diff --git a/BurnOutSharp/ProtectionType/SafeDisc.cs b/BurnOutSharp/ProtectionType/SafeDisc.cs index ecedcf74..8e9ee32b 100644 --- a/BurnOutSharp/ProtectionType/SafeDisc.cs +++ b/BurnOutSharp/ProtectionType/SafeDisc.cs @@ -158,7 +158,6 @@ namespace BurnOutSharp.ProtectionType return MatchUtil.GetFirstMatch(path, pathMatchers, any: true); } - // TODO: Try to find a file that this actually triggers for public static string Get320to4xVersion(string file, byte[] fileContent, List positions) => "3.20-4.xx (version removed)"; public static string GetVersion(string file, byte[] fileContent, List positions) diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs index 605e9cc8..d46f45e7 100644 --- a/BurnOutSharp/Tools/Utilities.cs +++ b/BurnOutSharp/Tools/Utilities.cs @@ -372,13 +372,14 @@ namespace BurnOutSharp.Tools /// ResourceSection from the executable /// String to use if checking for data starting with a string /// String to use if checking for data contains a string + /// String to use if checking for data ending with a string /// Full encoded resource data, null on error - public static ResourceDataEntry FindResourceInSection(ResourceSection rs, string dataStart = null, string dataContains = null) + public static ResourceDataEntry FindResourceInSection(ResourceSection rs, string dataStart = null, string dataContains = null, string dataEnd = null) { if (rs == null) return null; - return FindResourceInTable(rs.ResourceDirectoryTable, dataStart, dataContains); + return FindResourceInTable(rs.ResourceDirectoryTable, dataStart, dataContains, dataEnd); } /// @@ -387,8 +388,9 @@ namespace BurnOutSharp.Tools /// ResourceDirectoryTable representing a layer /// String to use if checking for data starting with a string /// String to use if checking for data contains a string + /// String to use if checking for data ending with a string /// Full encoded resource data, null on error - private static ResourceDataEntry FindResourceInTable(ResourceDirectoryTable rdt, string dataStart, string dataContains) + private static ResourceDataEntry FindResourceInTable(ResourceDirectoryTable rdt, string dataStart, string dataContains, string dataEnd) { if (rdt == null) return null; @@ -401,10 +403,12 @@ namespace BurnOutSharp.Tools return rdte.DataEntry; else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains)) return rdte.DataEntry; + else if (dataEnd != null && rdte.DataEntry.DataAsUTF8String.EndsWith(dataStart)) + return rdte.DataEntry; } else { - var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains); + var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains, dataEnd); if (manifest != null) return manifest; } @@ -418,10 +422,12 @@ namespace BurnOutSharp.Tools return rdte.DataEntry; else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains)) return rdte.DataEntry; + else if (dataEnd != null && rdte.DataEntry.DataAsUTF8String.EndsWith(dataStart)) + return rdte.DataEntry; } else { - var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains); + var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains, dataEnd); if (manifest != null) return manifest; }