From 373268a6a85ded20e8b5888d7d2465da531add17 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 10 Sep 2021 13:51:32 -0700 Subject: [PATCH] Convert resource checks to header checks --- .../PackerType/IntelInstallationFramework.cs | 78 +----- BurnOutSharp/PackerType/MicrosoftCABSFX.cs | 70 +---- BurnOutSharp/PackerType/SetupFactory.cs | 75 +----- BurnOutSharp/PackerType/WinZipSFX.cs | 10 +- BurnOutSharp/ProtectionType/CDKey.cs | 41 +-- BurnOutSharp/ProtectionType/ElectronicArts.cs | 68 +---- BurnOutSharp/ProtectionType/GFWL.cs | 66 +---- .../ProtectionType/OnlineRegistration.cs | 41 +-- BurnOutSharp/ProtectionType/SafeDisc.cs | 8 - BurnOutSharp/ProtectionType/SolidShield.cs | 100 ++------ BurnOutSharp/ProtectionType/StarForce.cs | 48 +--- BurnOutSharp/Tools/Utilities.cs | 239 +++++++++++------- 12 files changed, 247 insertions(+), 597 deletions(-) diff --git a/BurnOutSharp/PackerType/IntelInstallationFramework.cs b/BurnOutSharp/PackerType/IntelInstallationFramework.cs index bb3a9171..cbd65dc6 100644 --- a/BurnOutSharp/PackerType/IntelInstallationFramework.cs +++ b/BurnOutSharp/PackerType/IntelInstallationFramework.cs @@ -17,78 +17,26 @@ namespace BurnOutSharp.PackerType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.FileDescription?.Trim(); - if (!string.IsNullOrWhiteSpace(name) - && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) - || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) - { - return $"Intel Installation Framework {Utilities.GetFileVersion(fileContent)}"; - } - - name = fvinfo?.ProductName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) - && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) - || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) - { - return $"Intel Installation Framework {Utilities.GetFileVersion(fileContent)}"; - } - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - - // Get the .rsrc section, if it exists - var rsrcSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".rsrc")); - if (rsrcSection != null) + + string name = Utilities.GetFileDescription(pex); + if (!string.IsNullOrWhiteSpace(name) + && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) + || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) { - int sectionAddr = (int)rsrcSection.PointerToRawData; - int sectionEnd = sectionAddr + (int)rsrcSection.VirtualSize; - var matchers = new List - { - // I + (char)0x00 + n + (char)0x00 + t + (char)0x00 + e + (char)0x00 + l + (char)0x00 + ( + (char)0x00 + R + (char)0x00 + ) + (char)0x00 + + (char)0x00 + I + (char)0x00 + n + (char)0x00 + s + (char)0x00 + t + (char)0x00 + a + (char)0x00 + l + (char)0x00 + l + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + F + (char)0x00 + r + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + w + (char)0x00 + o + (char)0x00 + r + (char)0x00 + k + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x6C, 0x00, 0x28, 0x00, 0x52, 0x00, 0x29, 0x00, - 0x20, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x73, 0x00, - 0x74, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x6C, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, - 0x6E, 0x00, 0x20, 0x00, 0x46, 0x00, 0x72, 0x00, - 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x77, 0x00, - 0x6F, 0x00, 0x72, 0x00, 0x6B, 0x00, - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "Intel Installation Framework"), + return $"Intel Installation Framework {Utilities.GetFileVersion(pex)}"; + } - // I + (char)0x00 + n + (char)0x00 + t + (char)0x00 + e + (char)0x00 + l + (char)0x00 + ( + (char)0x00 + R + (char)0x00 + ) + (char)0x00 + + (char)0x00 + I + (char)0x00 + n + (char)0x00 + s + (char)0x00 + t + (char)0x00 + a + (char)0x00 + l + (char)0x00 + l + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + F + (char)0x00 + r + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + w + (char)0x00 + o + (char)0x00 + r + (char)0x00 + k + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x6C, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6E, 0x00, - 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6C, 0x00, - 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x46, 0x00, - 0x72, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x77, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6B, 0x00, - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "Intel Installation Framework"), - }; - - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; + name = Utilities.GetProductName(pex); + if (!string.IsNullOrWhiteSpace(name) + && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) + || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) + { + return $"Intel Installation Framework {Utilities.GetFileVersion(pex)}"; } return null; diff --git a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs index 9d473b4b..21b9b77d 100644 --- a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs +++ b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs @@ -22,41 +22,20 @@ namespace BurnOutSharp.PackerType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.InternalName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Equals("Wextract", StringComparison.OrdinalIgnoreCase)) - { - string version = GetVersion(file, fileContent, null); - if (!string.IsNullOrWhiteSpace(version)) - return $"Microsoft CAB SFX v{Utilities.GetFileVersion(fileContent)}"; - - return "Microsoft CAB SFX"; - } - - name = fvinfo?.OriginalFilename?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase)) - { - string version = GetVersion(file, fileContent, null); - if (!string.IsNullOrWhiteSpace(version)) - return $"Microsoft CAB SFX v{Utilities.GetFileVersion(fileContent)}"; - - return "Microsoft CAB SFX"; - } - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; + string name = Utilities.GetInternalName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Equals("Wextract", StringComparison.OrdinalIgnoreCase)) + return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v'); + + name = Utilities.GetOriginalFileName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase)) + return $"Microsoft CAB SFX v{Utilities.GetFileVersion(pex)}".TrimEnd('v'); + // Get the .data section, if it exists var dataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".data")); if (dataSection != null) @@ -80,39 +59,6 @@ namespace BurnOutSharp.PackerType return match; } - // 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 - { - // W + (char)0x00 + e + (char)0x00 + x + (char)0x00 + t + (char)0x00 + r + (char)0x00 + a + (char)0x00 + c + (char)0x00 + t + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x57, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00, - 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, - }, start: sectionAddr, end: sectionEnd), - GetVersion, "Microsoft CAB SFX"), - - // W + (char)0x00 + E + (char)0x00 + X + (char)0x00 + T + (char)0x00 + R + (char)0x00 + A + (char)0x00 + C + (char)0x00 + T + (char)0x00 + . + (char)0x00 + E + (char)0x00 + X + (char)0x00 + E + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x57, 0x00, 0x45, 0x00, 0x58, 0x00, 0x54, 0x00, - 0x52, 0x00, 0x41, 0x00, 0x43, 0x00, 0x54, 0x00, - 0x2E, 0x00, 0x45, 0x00, 0x58, 0x00, 0x45, 0x00, - }, start: sectionAddr, end: sectionEnd), - GetVersion, "Microsoft CAB SFX"), - }; - - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } - // Get the .text section, if it exists var textSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".text")); if (textSection != null) diff --git a/BurnOutSharp/PackerType/SetupFactory.cs b/BurnOutSharp/PackerType/SetupFactory.cs index 9e8334a5..31b77cfc 100644 --- a/BurnOutSharp/PackerType/SetupFactory.cs +++ b/BurnOutSharp/PackerType/SetupFactory.cs @@ -21,75 +21,22 @@ namespace BurnOutSharp.PackerType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.LegalTrademarks?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase)) - return $"Setup Factory {GetVersion(file, fileContent, null)}"; - - name = fvinfo?.ProductName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase)) - return $"Setup Factory {GetVersion(file, fileContent, null)}"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - // 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 - { - // S + (char)0x00 + e + (char)0x00 + t + (char)0x00 + u + (char)0x00 + p + (char)0x00 + + (char)0x00 + F + (char)0x00 + a + (char)0x00 + c + (char)0x00 + t + (char)0x00 + o + (char)0x00 + r + (char)0x00 + y + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x53, 0x00, 0x65, 0x00, 0x74, 0x00, 0x75, 0x00, - 0x70, 0x00, 0x20, 0x00, 0x46, 0x00, 0x61, 0x00, - 0x63, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, - 0x79, 0x00 - }, start: sectionAddr, end: sectionEnd), - GetVersion, "Setup Factory"), + string name = Utilities.GetLegalCopyright(pex); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase)) + return $"Setup Factory {GetVersion(pex)}"; - // Longer version of the check that can be used if false positves become an issue: - // S + (char)0x00 + e + (char)0x00 + t + (char)0x00 + u + (char)0x00 + p + (char)0x00 + + (char)0x00 + F + (char)0x00 + a + (char)0x00 + c + (char)0x00 + t + (char)0x00 + o + (char)0x00 + r + (char)0x00 + y + (char)0x00 + + (char)0x00 + i + (char)0x00 + s + (char)0x00 + + (char)0x00 + a + (char)0x00 + + (char)0x00 + t + (char)0x00 + r + (char)0x00 + a + (char)0x00 + d + (char)0x00 + e + (char)0x00 + m + (char)0x00 + a + (char)0x00 + r + (char)0x00 + k + (char)0x00 + + (char)0x00 + o + (char)0x00 + f + (char)0x00 + + (char)0x00 + I + (char)0x00 + n + (char)0x00 + d + (char)0x00 + i + (char)0x00 + g + (char)0x00 + o + (char)0x00 + + (char)0x00 + R + (char)0x00 + o + (char)0x00 + s + (char)0x00 + e + (char)0x00 + + (char)0x00 + C + (char)0x00 + o + (char)0x00 + r + (char)0x00 + p + (char)0x00 + o + (char)0x00 + r + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 - // new ContentMatchSet( - // new ContentMatch(new byte?[] - // { - // 0x53, 0x00, 0x65, 0x00, 0x74, 0x00, 0x75, 0x00, - // 0x70, 0x00, 0x20, 0x00, 0x46, 0x00, 0x61, 0x00, - // 0x63, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, - // 0x79, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, - // 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x74, 0x00, - // 0x72, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, - // 0x6D, 0x00, 0x61, 0x00, 0x72, 0x00, 0x6B, 0x00, - // 0x20, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x20, 0x00, - // 0x49, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x69, 0x00, - // 0x67, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x52, 0x00, - // 0x6F, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, - // 0x43, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x70, 0x00, - // 0x6F, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, - // 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00 - // }, start: sectionAddr, end: sectionEnd), - // GetVersion, "Setup Factory"), - }; + name = Utilities.GetProductName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase)) + return $"Setup Factory {GetVersion(pex)}"; - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + // Longer version of the check that can be used if false positves become an issue: + // Setup Factory is a trademark of Indigo Rose Corporation return null; } @@ -114,15 +61,15 @@ namespace BurnOutSharp.PackerType return null; } - public static string GetVersion(string file, byte[] fileContent, List positions) + private string GetVersion(PortableExecutable pex) { // Check the manifest version first - string version = Utilities.GetManifestVersion(fileContent); + string version = Utilities.GetManifestVersion(pex); if (!string.IsNullOrEmpty(version)) return version; // Then check the file version - version = Utilities.GetFileVersion(fileContent); + version = Utilities.GetFileVersion(pex); if (!string.IsNullOrEmpty(version)) return version; diff --git a/BurnOutSharp/PackerType/WinZipSFX.cs b/BurnOutSharp/PackerType/WinZipSFX.cs index eba91e83..4ffee884 100644 --- a/BurnOutSharp/PackerType/WinZipSFX.cs +++ b/BurnOutSharp/PackerType/WinZipSFX.cs @@ -49,7 +49,7 @@ namespace BurnOutSharp.PackerType if (!string.IsNullOrWhiteSpace(version)) return $"WinZip SFX {version}"; - version = GetAdjustedManifestVersion(file, fileContent); + version = GetAdjustedManifestVersion(pex); if (!string.IsNullOrWhiteSpace(version)) return $"WinZip SFX {version}"; @@ -102,7 +102,7 @@ namespace BurnOutSharp.PackerType if (!string.IsNullOrWhiteSpace(version)) { // Try to grab the value from the manifest, if possible - string manifestVersion = GetAdjustedManifestVersion(file, fileContent); + string manifestVersion = GetAdjustedManifestVersion(pex); if (!string.IsNullOrWhiteSpace(manifestVersion)) return $"WinZip SFX {manifestVersion}"; @@ -194,11 +194,11 @@ namespace BurnOutSharp.PackerType /// /// Get the version from the assembly manifest, correcting where possible /// - private static string GetAdjustedManifestVersion(string file, byte[] fileContent) + private static string GetAdjustedManifestVersion(PortableExecutable pex) { // Get the manifest information, if possible - string description = Utilities.GetManifestDescription(fileContent); - string version = Utilities.GetManifestVersion(fileContent); + string description = Utilities.GetManifestDescription(pex); + string version = Utilities.GetManifestVersion(pex); // Either an incorrect description or empty version mean we can't match if (description != "WinZip Self-Extractor") diff --git a/BurnOutSharp/ProtectionType/CDKey.cs b/BurnOutSharp/ProtectionType/CDKey.cs index bb055cea..5521b392 100644 --- a/BurnOutSharp/ProtectionType/CDKey.cs +++ b/BurnOutSharp/ProtectionType/CDKey.cs @@ -16,50 +16,15 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.InternalName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDKey", StringComparison.OrdinalIgnoreCase)) - return "CD-Key / Serial"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - - // 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 - { - // I + (char)0x00 + n + (char)0x00 + t + (char)0x00 + e + (char)0x00 + r + (char)0x00 + n + (char)0x00 + a + (char)0x00 + l + (char)0x00 + N + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + + (char)0x00 + + (char)0x00 + C + (char)0x00 + D + (char)0x00 + K + (char)0x00 + e + (char)0x00 + y + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, - 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x00, 0x00, 0x43, 0x00, 0x44, 0x00, 0x4B, 0x00, - 0x65, 0x00, 0x79, 0x00, - }, start: sectionAddr, end: sectionEnd), - "CD-Key / Serial"), - }; - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + string name = Utilities.GetInternalName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDKey", StringComparison.OrdinalIgnoreCase)) + return "CD-Key / Serial"; return null; } diff --git a/BurnOutSharp/ProtectionType/ElectronicArts.cs b/BurnOutSharp/ProtectionType/ElectronicArts.cs index c6251bb4..8a629227 100644 --- a/BurnOutSharp/ProtectionType/ElectronicArts.cs +++ b/BurnOutSharp/ProtectionType/ElectronicArts.cs @@ -36,31 +36,22 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.FileDescription?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Contains("Registration code installer program")) - return $"EA CdKey Registration Module {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.Equals("EA DRM Helper", StringComparison.OrdinalIgnoreCase)) - return $"EA DRM Protection {Utilities.GetFileVersion(fileContent)}"; - - name = fvinfo?.InternalName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDCode", StringComparison.Ordinal)) - return $"EA CdKey Registration Module {Utilities.GetFileVersion(fileContent)}"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; + string name = Utilities.GetFileDescription(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Contains("Registration code installer program")) + return $"EA CdKey Registration Module {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.Equals("EA DRM Helper", StringComparison.OrdinalIgnoreCase)) + return $"EA DRM Protection {Utilities.GetFileVersion(pex)}"; + + name = Utilities.GetInternalName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Equals("CDCode", StringComparison.Ordinal)) + return $"EA CdKey Registration Module {Utilities.GetFileVersion(pex)}"; + // Get the .data section, if it exists var dataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".data")); if (dataSection != null) @@ -101,45 +92,6 @@ namespace BurnOutSharp.ProtectionType 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00 }, start: sectionAddr, end: sectionEnd), Utilities.GetFileVersion, "EA CdKey Registration Module"), - - // I + (char)0x00 + n + (char)0x00 + t + (char)0x00 + e + (char)0x00 + r + (char)0x00 + n + (char)0x00 + a + (char)0x00 + l + (char)0x00 + N + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + + (char)0x00 + + (char)0x00 + C + (char)0x00 + D + (char)0x00 + C + (char)0x00 + o + (char)0x00 + d + (char)0x00 + e + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, - 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x00, 0x00, 0x43, 0x00, 0x44, 0x00, 0x43, 0x00, - 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "EA CdKey Registration Module"), - - // R + (char)0x00 + e + (char)0x00 + g + (char)0x00 + i + (char)0x00 + s + (char)0x00 + t + (char)0x00 + r + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + C/c + (char)0x00 + o + (char)0x00 + d + (char)0x00 + e + (char)0x00 + + (char)0x00 + i + (char)0x00 + n + (char)0x00 + s + (char)0x00 + t + (char)0x00 + a + (char)0x00 + l + (char)0x00 + l + (char)0x00 + e + (char)0x00 + r + (char)0x00 + + (char)0x00 + p + (char)0x00 + r + (char)0x00 + o + (char)0x00 + g + (char)0x00 + r + (char)0x00 + a + (char)0x00 + m + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x69, 0x00, - 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x61, 0x00, - 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, - 0x20, 0x00, null, 0x00, 0x6F, 0x00, 0x64, 0x00, - 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6E, 0x00, - 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6C, 0x00, - 0x6C, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, - 0x70, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x67, 0x00, - 0x72, 0x00, 0x61, 0x00, 0x6D, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "EA CdKey Registration Module"), - - // E + (char)0x00 + A + (char)0x00 + + (char)0x00 + D + (char)0x00 + R + (char)0x00 + M + (char)0x00 + + (char)0x00 + H + (char)0x00 + e + (char)0x00 + l + (char)0x00 + p + (char)0x00 + e + (char)0x00 + r + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x45, 0x00, 0x41, 0x00, 0x20, 0x00, 0x44, 0x00, - 0x52, 0x00, 0x4D, 0x00, 0x20, 0x00, 0x48, 0x00, - 0x65, 0x00, 0x6C, 0x00, 0x70, 0x00, 0x65, 0x00, - 0x72, 0x00 - }, start: sectionAddr, end: sectionEnd), - "EA DRM Protection"), }; string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); diff --git a/BurnOutSharp/ProtectionType/GFWL.cs b/BurnOutSharp/ProtectionType/GFWL.cs index 0e6655fc..9184a015 100644 --- a/BurnOutSharp/ProtectionType/GFWL.cs +++ b/BurnOutSharp/ProtectionType/GFWL.cs @@ -17,73 +17,17 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.FileDescription?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows - LIVE Zero Day Piracy Protection", StringComparison.OrdinalIgnoreCase)) - return $"Games for Windows LIVE - Zero Day Piracy Protection Module {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows", StringComparison.OrdinalIgnoreCase)) - return $"Games for Windows LIVE {Utilities.GetFileVersion(fileContent)}"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - // 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 - { - // G + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + s + (char)0x00 + + (char)0x00 + f + (char)0x00 + o + (char)0x00 + r + (char)0x00 + + (char)0x00 + W + (char)0x00 + i + (char)0x00 + n + (char)0x00 + d + (char)0x00 + o + (char)0x00 + w + (char)0x00 + s + (char)0x00 + + (char)0x00 + - + (char)0x00 + + (char)0x00 + L + (char)0x00 + I + (char)0x00 + V + (char)0x00 + E + (char)0x00 + + (char)0x00 + Z + (char)0x00 + e + (char)0x00 + r + (char)0x00 + o + (char)0x00 + + (char)0x00 + D + (char)0x00 + a + (char)0x00 + y + (char)0x00 + + (char)0x00 + P + (char)0x00 + i + (char)0x00 + r + (char)0x00 + a + (char)0x00 + c + (char)0x00 + y + (char)0x00 + + (char)0x00 + P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x47, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6F, 0x00, - 0x72, 0x00, 0x20, 0x00, 0x57, 0x00, 0x69, 0x00, - 0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, - 0x4C, 0x00, 0x49, 0x00, 0x56, 0x00, 0x45, 0x00, - 0x20, 0x00, 0x5A, 0x00, 0x65, 0x00, 0x72, 0x00, - 0x6F, 0x00, 0x20, 0x00, 0x44, 0x00, 0x61, 0x00, - 0x79, 0x00, 0x20, 0x00, 0x50, 0x00, 0x69, 0x00, - 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x79, 0x00, - 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, - 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, - 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "Games for Windows LIVE - Zero Day Piracy Protection Module"), - - // G + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + s + (char)0x00 + + (char)0x00 + f + (char)0x00 + o + (char)0x00 + r + (char)0x00 + + (char)0x00 + W + (char)0x00 + i + (char)0x00 + n + (char)0x00 + d + (char)0x00 + o + (char)0x00 + w + (char)0x00 + s + (char)0x00 + + (char)0x00 + - + (char)0x00 + + (char)0x00 + L + (char)0x00 + I + (char)0x00 + V + (char)0x00 + E + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x47, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6F, 0x00, - 0x72, 0x00, 0x20, 0x00, 0x57, 0x00, 0x69, 0x00, - 0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, - 0x4C, 0x00, 0x49, 0x00, 0x56, 0x00, 0x45, 0x00, - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "Games for Windows LIVE"), - }; - - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + string name = Utilities.GetFileDescription(pex); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows - LIVE Zero Day Piracy Protection", StringComparison.OrdinalIgnoreCase)) + return $"Games for Windows LIVE - Zero Day Piracy Protection Module {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Games for Windows", StringComparison.OrdinalIgnoreCase)) + return $"Games for Windows LIVE {Utilities.GetFileVersion(pex)}"; // Get the .rdata section, if it exists var rdataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".rdata")); diff --git a/BurnOutSharp/ProtectionType/OnlineRegistration.cs b/BurnOutSharp/ProtectionType/OnlineRegistration.cs index f27c328d..ff02d945 100644 --- a/BurnOutSharp/ProtectionType/OnlineRegistration.cs +++ b/BurnOutSharp/ProtectionType/OnlineRegistration.cs @@ -16,50 +16,15 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.InternalName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("EReg", StringComparison.OrdinalIgnoreCase)) - return $"Executable-Based Online Registration {Utilities.GetFileVersion(file, fileContent, null)}"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - // 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 - { - // I + (char)0x00 + n + (char)0x00 + t + (char)0x00 + e + (char)0x00 + r + (char)0x00 + n + (char)0x00 + a + (char)0x00 + l + (char)0x00 + N + (char)0x00 + a + (char)0x00 + m + (char)0x00 + e + (char)0x00 + + (char)0x00 + + (char)0x00 + E + (char)0x00 + R + (char)0x00 + e + (char)0x00 + g + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, - 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, - 0x00, 0x00, 0x45, 0x00, 0x52, 0x00, 0x65, 0x00, - 0x67, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "Executable-Based Online Registration"), - }; - - string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + string name = Utilities.GetInternalName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("EReg", StringComparison.OrdinalIgnoreCase)) + return $"Executable-Based Online Registration {Utilities.GetFileVersion(pex)}"; return null; } diff --git a/BurnOutSharp/ProtectionType/SafeDisc.cs b/BurnOutSharp/ProtectionType/SafeDisc.cs index a0b2dca8..6a31390b 100644 --- a/BurnOutSharp/ProtectionType/SafeDisc.cs +++ b/BurnOutSharp/ProtectionType/SafeDisc.cs @@ -51,14 +51,6 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - foreach (var section in sections) - { - string sectionName = System.Text.Encoding.ASCII.GetString(section.Name).Trim('\0'); - int sectionAddr = (int)section.PointerToRawData; - int sectionEnd = sectionAddr + (int)section.VirtualSize; - System.Console.WriteLine($"{sectionName}: {sectionAddr} -> {sectionEnd}"); - } - // Get the .text section, if it exists var textSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".text")); if (textSection != null) diff --git a/BurnOutSharp/ProtectionType/SolidShield.cs b/BurnOutSharp/ProtectionType/SolidShield.cs index 1b75b9e5..c6d2126f 100644 --- a/BurnOutSharp/ProtectionType/SolidShield.cs +++ b/BurnOutSharp/ProtectionType/SolidShield.cs @@ -46,38 +46,29 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.FileDescription?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("DVM Library", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield Activation Manager Module {GetFileVersion(file, fileContent, null)}"; - - name = fvinfo?.ProductName?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Library", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield Core.dll {Utilities.GetFileVersion(fileContent)}"; - else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase)) - return $"SolidShield Activation Manager Module {GetFileVersion(file, fileContent, null)}"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; - // Get the .init section, if it exists + string name = Utilities.GetFileDescription(pex)?.Trim(); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("DVM Library", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield Core.dll {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield Activation Manager Module {GetFileVersion(pex)}"; + + name = Utilities.GetProductName(pex); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Activation Library", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield Core.dll {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Solidshield Library", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield Core.dll {Utilities.GetFileVersion(pex)}"; + else if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Activation Manager", StringComparison.OrdinalIgnoreCase)) + return $"SolidShield Activation Manager Module {GetFileVersion(pex)}"; + + // Get the .init section, if it exists var initSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".init")); if (initSection != null) { @@ -118,45 +109,6 @@ namespace BurnOutSharp.ProtectionType 0x61, 0x00, 0x72, 0x00, 0x79, 0x00 }, start: sectionAddr, end: sectionEnd), Utilities.GetFileVersion, "SolidShield"), - - // A + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + v + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + M + (char)0x00 + a + (char)0x00 + n + (char)0x00 + a + (char)0x00 + g + (char)0x00 + e + (char)0x00 + r + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x4d, 0x00, - 0x61, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x67, 0x00, - 0x65, 0x00, 0x72, 0x00 - }, start: sectionAddr, end: sectionEnd), - GetFileVersion, "SolidShield Activation Manager Module"), - - // S + (char)0x00 + o + (char)0x00 + l + (char)0x00 + i + (char)0x00 + d + (char)0x00 + s + (char)0x00 + h + (char)0x00 + i + (char)0x00 + e + (char)0x00 + l + (char)0x00 + d + (char)0x00 + + (char)0x00 + L + (char)0x00 + i + (char)0x00 + b + (char)0x00 + r + (char)0x00 + a + (char)0x00 + r + (char)0x00 + y + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00, - 0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00, - 0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00, - 0x4C, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, - 0x61, 0x00, 0x72, 0x00, 0x79, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "SolidShield Core.dll"), - - // S + (char)0x00 + o + (char)0x00 + l + (char)0x00 + i + (char)0x00 + d + (char)0x00 + s + (char)0x00 + h + (char)0x00 + i + (char)0x00 + e + (char)0x00 + l + (char)0x00 + d + (char)0x00 + + (char)0x00 + A + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + v + (char)0x00 + a + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + L + (char)0x00 + i + (char)0x00 + b + (char)0x00 + r + (char)0x00 + a + (char)0x00 + r + (char)0x00 + y + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x53, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x69, 0x00, - 0x64, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00, - 0x65, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x20, 0x00, - 0x41, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x4C, 0x00, - 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, - 0x72, 0x00, 0x79, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "SolidShield Core.dll"), }; string match = MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); @@ -220,15 +172,6 @@ namespace BurnOutSharp.ProtectionType return null; } - public static string GetFileVersion(string file, byte[] fileContent, List positions) - { - string companyName = Utilities.GetFileVersionInfo(file)?.CompanyName.ToLowerInvariant(); - if (!string.IsNullOrWhiteSpace(companyName) && (companyName.Contains("solidshield") || companyName.Contains("tages"))) - return Utilities.GetFileVersion(fileContent); - - return null; - } - public static string GetVersion(string file, byte[] fileContent, List positions) { int index = positions[0] + 12; // Begin reading after "Solidshield" @@ -285,5 +228,14 @@ namespace BurnOutSharp.ProtectionType return null; } + + private static string GetFileVersion(PortableExecutable pex) + { + string companyName = Utilities.GetCompanyName(pex)?.ToLowerInvariant(); + if (!string.IsNullOrWhiteSpace(companyName) && (companyName.Contains("solidshield") || companyName.Contains("tages"))) + return Utilities.GetFileVersion(pex); + + return null; + } } } diff --git a/BurnOutSharp/ProtectionType/StarForce.cs b/BurnOutSharp/ProtectionType/StarForce.cs index 9464bdfb..492155b3 100644 --- a/BurnOutSharp/ProtectionType/StarForce.cs +++ b/BurnOutSharp/ProtectionType/StarForce.cs @@ -17,30 +17,21 @@ namespace BurnOutSharp.ProtectionType /// public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) { - // TODO: Implement resource finding instead of using the built in methods - // Assembly information lives in the .rsrc section - // I need to find out how to navigate the resources in general - // as well as figure out the specific resources for both - // file info and MUI (XML) info. Once I figure this out, - // that also opens the doors to easier assembly XML checks. - - var fvinfo = Utilities.GetFileVersionInfo(file); - - string name = fvinfo?.LegalCopyright?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Contains("Protection Technology")) - return $"StarForce {Utilities.GetFileVersion(fileContent)}"; - - // TODO: Find what fvinfo field actually maps to this - name = fvinfo?.FileDescription?.Trim(); - if (!string.IsNullOrWhiteSpace(name) && name.Contains("Protected Module")) - return $"StarForce 5"; - // Get the sections from the executable, if possible PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var sections = pex?.SectionTable; if (sections == null) return null; + string name = Utilities.GetLegalCopyright(pex); + if (!string.IsNullOrWhiteSpace(name) && name.Contains("Protection Technology")) + return $"StarForce {Utilities.GetFileVersion(pex)}"; + + // TODO: Find what fvinfo field actually maps to this + name = Utilities.GetFileDescription(pex).Trim(); + if (!string.IsNullOrWhiteSpace(name) && name.Contains("Protected Module")) + return $"StarForce 5"; + // Get the .rsrc section, if it exists var rsrcSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".rsrc")); if (rsrcSection != null) @@ -49,19 +40,6 @@ namespace BurnOutSharp.ProtectionType int sectionEnd = sectionAddr + (int)rsrcSection.VirtualSize; var matchers = new List { - // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + T + (char)0x00 + e + (char)0x00 + c + (char)0x00 + h + (char)0x00 + n + (char)0x00 + o + (char)0x00 + l + (char)0x00 + o + (char)0x00 + g + (char)0x00 + y + (char)0x00 - new ContentMatchSet( - new ContentMatch(new byte?[] - { - 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00, - 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, - 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00, - 0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00, - 0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, - 0x79, 0x00 - }, start: sectionAddr, end: sectionEnd), - Utilities.GetFileVersion, "StarForce"), - // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + e + (char)0x00 + d + (char)0x00 + + (char)0x00 + M + (char)0x00 + o + (char)0x00 + d + (char)0x00 + u + (char)0x00 + l + (char)0x00 + e + (char)0x00 new ContentMatchSet( new ContentMatch(new byte?[] @@ -153,9 +131,9 @@ namespace BurnOutSharp.ProtectionType return null; } - public static string GetVersion(string file, byte[] fileContent, List positions) - { - return $"{Utilities.GetFileVersion(fileContent)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})"; - } + // public static string GetVersion(string file, byte[] fileContent, List positions) + // { + // return $"{Utilities.GetFileVersion(fileContent)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})"; + // } } } diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs index 81516090..673aa775 100644 --- a/BurnOutSharp/Tools/Utilities.cs +++ b/BurnOutSharp/Tools/Utilities.cs @@ -10,7 +10,6 @@ using BurnOutSharp.ExecutableType.Microsoft.Entries; using BurnOutSharp.ExecutableType.Microsoft.Resources; using BurnOutSharp.ExecutableType.Microsoft.Sections; using BurnOutSharp.ExecutableType.Microsoft.Tables; -using BurnOutSharp.Matching; namespace BurnOutSharp.Tools { @@ -185,53 +184,30 @@ namespace BurnOutSharp.Tools #region Protection /// - /// Get the file version info object related to a path, if possible + /// Get the company name as reported by the filesystem /// - /// File to get information for - /// FileVersionInfo object on success, null on error - public static FileVersionInfo GetFileVersionInfo(string file) - { - if (file == null || !File.Exists(file)) - return null; - - try - { - return FileVersionInfo.GetVersionInfo(file); - } - catch - { - return null; - } - } + /// PortableExecutable representing the file contents + /// Company name string, null on error + public static string GetCompanyName(PortableExecutable pex) => GetResourceString(pex, "CompanyName"); /// - /// Get the file version info object related to file contents, if possible + /// Get the file description as reported by the filesystem + /// + /// PortableExecutable representing the file contents + /// Description string, null on error + public static string GetFileDescription(PortableExecutable pex) => GetResourceString(pex, "FileDescription"); + + /// + /// Get the file version as reported by the filesystem /// /// Byte array representing the file contents - /// FileVersionInfo object on success, null on error - public static VersionInfo GetVersionInfo(byte[] fileContent) + /// Version string, null on error + public static string GetFileVersion(byte[] fileContent) { if (fileContent == null || !fileContent.Any()) return null; - // If we don't have a PE executable, just return null - PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); - var resourceSection = pex?.ResourceSection; - if (resourceSection == null) - return null; - - var resource = FindResourceInSection(resourceSection, dataContains: "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0"); - - try - { - int index = 0; - return VersionInfo.Deserialize(resource.Data, ref index); - } - catch (Exception ex) - { - // Console.WriteLine(ex); - return null; - } + return GetFileVersion(PortableExecutable.Deserialize(fileContent, 0)); } /// @@ -253,22 +229,17 @@ namespace BurnOutSharp.Tools /// /// Get the file version as reported by the filesystem /// - /// Byte array representing the file contents + /// PortableExecutable representing the file contents /// Version string, null on error - /// TODO: Add override that takes an existing PE - public static string GetFileVersion(byte[] fileContent) + public static string GetFileVersion(PortableExecutable pex) { - var resourceStrings = GetVersionInfo(fileContent)?.ChildrenStringFileInfo?.Children?.Children; - if (resourceStrings == null) - return null; - - var fileVersion = resourceStrings.FirstOrDefault(s => s.Key == "FileVersion"); - if (!string.IsNullOrWhiteSpace(fileVersion?.Value)) - return fileVersion.Value.Replace(", ", "."); + string version = GetResourceString(pex, "FileVersion"); + if (!string.IsNullOrWhiteSpace(version)) + return version.Replace(", ", "."); - var productVersion = resourceStrings.FirstOrDefault(s => s.Key == "ProductVersion"); - if (!string.IsNullOrWhiteSpace(productVersion?.Value)) - return productVersion.Value.Replace(", ", "."); + version = GetResourceString(pex, "ProductVersion"); + if (!string.IsNullOrWhiteSpace(version)) + return version.Replace(", ", "."); return null; } @@ -290,15 +261,66 @@ namespace BurnOutSharp.Tools /// Version string, null on error public static string GetFileVersion(string firstMatchedString, IEnumerable files) => GetFileVersion(firstMatchedString); + /// + /// Get the internal name as reported by the filesystem + /// + /// PortableExecutable representing the file contents + /// Internal name string, null on error + public static string GetInternalName(PortableExecutable pex) => GetResourceString(pex, "InternalName"); + + /// + /// Get the legal copyright as reported by the filesystem + /// + /// PortableExecutable representing the file contents + /// Legal copyright string, null on error + public static string GetLegalCopyright(PortableExecutable pex) => GetResourceString(pex, "LegalCopyright"); + /// /// Get the assembly version as determined by an embedded assembly manifest /// /// Byte array representing the file contents /// Version string, null on error - public static string GetManifestVersion(byte[] fileContent) + public static string GetManifestDescription(PortableExecutable pex) + { + // If we don't have a PE executable, just return null + var resourceSection = pex?.ResourceSection; + if (resourceSection == null) + return null; + + // Read in the manifest to a string + string manifestString = FindAssemblyManifest(pex.ResourceSection); + if (string.IsNullOrWhiteSpace(manifestString)) + return null; + + // Try to read the XML in from the string + try + { + // Try to read the assembly + var assemblyNode = GetAssemblyNode(manifestString); + if (assemblyNode == null) + return null; + + // Return the content of the description node, if possible + var descriptionNode = assemblyNode["description"]; + if (descriptionNode == null) + return null; + + return descriptionNode.InnerXml; + } + catch + { + return null; + } + } + + /// + /// Get the assembly version as determined by an embedded assembly manifest + /// + /// PortableExecutable representing the file contents + /// Version string, null on error + public static string GetManifestVersion(PortableExecutable pex) { // If we don't have a PE executable, just return null - PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); var resourceSection = pex?.ResourceSection; if (resourceSection == null) return null; @@ -331,43 +353,18 @@ namespace BurnOutSharp.Tools } /// - /// Get the assembly version as determined by an embedded assembly manifest + /// Get the original filename as reported by the filesystem /// - /// Byte array representing the file contents - /// Version string, null on error - public static string GetManifestDescription(byte[] fileContent) - { - // If we don't have a PE executable, just return null - PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); - var resourceSection = pex?.ResourceSection; - if (resourceSection == null) - return null; - - // Read in the manifest to a string - string manifestString = FindAssemblyManifest(pex.ResourceSection); - if (string.IsNullOrWhiteSpace(manifestString)) - return null; + /// PortableExecutable representing the file contents + /// Original filename string, null on error + public static string GetOriginalFileName(PortableExecutable pex) => GetResourceString(pex, "OriginalFileName"); - // Try to read the XML in from the string - try - { - // Try to read the assembly - var assemblyNode = GetAssemblyNode(manifestString); - if (assemblyNode == null) - return null; - - // Return the content of the description node, if possible - var descriptionNode = assemblyNode["description"]; - if (descriptionNode == null) - return null; - - return descriptionNode.InnerXml; - } - catch - { - return null; - } - } + /// + /// Get the product name as reported by the filesystem + /// + /// PortableExecutable representing the file contents + /// Product name string, null on error + public static string GetProductName(PortableExecutable pex) => GetResourceString(pex, "ProductName"); /// /// Find resource data in a ResourceSection, if possible @@ -470,6 +467,70 @@ namespace BurnOutSharp.Tools } } + /// + /// Get the file version info object related to a path, if possible + /// + /// File to get information for + /// FileVersionInfo object on success, null on error + private static FileVersionInfo GetFileVersionInfo(string file) + { + if (file == null || !File.Exists(file)) + return null; + + try + { + return FileVersionInfo.GetVersionInfo(file); + } + catch + { + return null; + } + } + + /// + /// Get a resource string from the version info + /// + /// PortableExecutable representing the file contents + /// Original filename string, null on error + private static string GetResourceString(PortableExecutable pex, string key) + { + var resourceStrings = GetVersionInfo(pex)?.ChildrenStringFileInfo?.Children?.Children; + if (resourceStrings == null) + return null; + + var value = resourceStrings.FirstOrDefault(s => s.Key == key); + if (!string.IsNullOrWhiteSpace(value?.Value)) + return value.Value.Trim(); + + return null; + } + + /// + /// Get the version info object related to file contents, if possible + /// + /// PortableExecutable representing the file contents + /// VersionInfo object on success, null on error + private static VersionInfo GetVersionInfo(PortableExecutable pex) + { + // If we don't have a PE executable, just return null + var resourceSection = pex?.ResourceSection; + if (resourceSection == null) + return null; + + var resource = FindResourceInSection(resourceSection, dataContains: "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0"); + + try + { + int index = 0; + return VersionInfo.Deserialize(resource.Data, ref index); + } + catch (Exception ex) + { + // Console.WriteLine(ex); + return null; + } + } + #endregion } }