diff --git a/BinaryObjectScanner.Test/Protection/CDDVDCopsTests.cs b/BinaryObjectScanner.Test/Protection/CDDVDCopsTests.cs index ab0f01f6..7a43cf54 100644 --- a/BinaryObjectScanner.Test/Protection/CDDVDCopsTests.cs +++ b/BinaryObjectScanner.Test/Protection/CDDVDCopsTests.cs @@ -7,17 +7,6 @@ namespace BinaryObjectScanner.Test.Protection { public class CDDVDCopsTests { - [Fact] - public void CheckContentsTest() - { - string file = "filename"; - byte[] fileContent = [0x01, 0x02, 0x03, 0x04]; - - var checker = new CDDVDCops(); - string? actual = checker.CheckContents(file, fileContent, includeDebug: true); - Assert.Null(actual); - } - [Fact] public void CheckNewExecutableTest() { diff --git a/BinaryObjectScanner/Protection/CDDVDCops.cs b/BinaryObjectScanner/Protection/CDDVDCops.cs index 6915e20b..08cc291c 100644 --- a/BinaryObjectScanner/Protection/CDDVDCops.cs +++ b/BinaryObjectScanner/Protection/CDDVDCops.cs @@ -4,6 +4,7 @@ using System.Linq; #endif using System.Text; +using System.Text.RegularExpressions; using BinaryObjectScanner.Interfaces; using SabreTools.Matching; using SabreTools.Matching.Content; @@ -64,35 +65,12 @@ namespace BinaryObjectScanner.Protection /// /// List of applications that have CD/DVD/WEB-Cops relating to a Windows update: https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/924867 /// - - public class CDDVDCops : IContentCheck, IExecutableCheck, IExecutableCheck, IPathCheck + // TODO: Investigate reference to "CD32COPS.DLL" in "WETFLIPP.QZ_" in IA item "Triada_Russian_DVD_Complete_Collection_of_Erotic_Games". + // TODO: Investigate cdcode.key for redump ID 108167, may be key-less cd-cops? + // TODO: Document update 12 for redump ID 108167 bumping version, adding key, adding vista(?) support + + public class CDDVDCops : IExecutableCheck, IExecutableCheck, IPathCheck { - // TODO: Investigate reference to "CD32COPS.DLL" in "WETFLIPP.QZ_" in IA item "Triada_Russian_DVD_Complete_Collection_of_Erotic_Games". - /// - public string? CheckContents(string file, byte[] fileContent, bool includeDebug) - { - // TODO: Obtain a sample to find where this string is in a typical executable - var contentMatchSets = new List - { - // TODO: Remove from here once it's confirmed that no PE executables contain this string - // CD-Cops, ver. - new(new byte?[] - { - 0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C, - 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 - }, GetVersion, "CD-Cops (Unconfirmed - Please report to us on Github)"), - - // // DVD-Cops, ver. - new(new byte?[] - { - 0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, - 0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 - }, GetVersion, "DVD-Cops (Unconfirmed - Please report to us on Github)"), - }; - - return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug); - } - /// public string? CheckExecutable(string file, NewExecutable nex, bool includeDebug) { @@ -104,13 +82,39 @@ public class CDDVDCops : IContentCheck, IExecutableCheck, IExecut // TODO: Figure out what NE section this lives in var neMatchSets = new List { - // CD-Cops, ver. + // Checking for variants with one or two spaces, just in case; the Brockhaus DVDs only had one + new(new byte?[] + { + 0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C, + 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 + }, GetVersion, "CD-Cops"), + // CD-Cops, ver. + // Found in "h3blade.exe" in Redump entry 85077. new(new byte?[] { 0x43, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, 0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 }, GetVersion, "CD-Cops"), + // CD-Cops, ver. + + // Found in IA entries "der-brockhaus-multimedial-2002-premium" and "der-brockhaus-multimedial-2003-premium" + // TODO: 2002 returns DVD-Cops 2.01, 2003 returns DVD-Cops 1,60. CD-Cops version numbers seem to "reset" + // after some point in time in existing redump entries- perhaps the command instead of the period may have + // some significance? + new(new byte?[] + { + 0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, + 0x2C, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 + }, GetVersion, "DVD-Cops"), + // DVD-Cops, ver. + + new(new byte?[] + { + 0x44, 0x56, 0x44, 0x2D, 0x43, 0x6F, 0x70, 0x73, + 0x2C, 0x20, 0x20, 0x76, 0x65, 0x72, 0x2E, 0x20 + }, GetVersion, "DVD-Cops"), + // DVD-Cops, ver. }; var match = MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug); @@ -186,7 +190,22 @@ public class CDDVDCops : IContentCheck, IExecutableCheck, IExecut // Found in "FGP.exe" in IA item "flaklypa-grand-prix-dvd"/Redump entry 108169. if (pex.ContainsSection("UNICops", exact: true)) return "UNI-Cops"; - + + // Get the DATA section, if it exists + // 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 = pex.GetFirstSectionStrings("DATA"); + if (strs != null) + { + var match = strs.Find(s => s.Contains(" ver. ") && (s.Contains("CD-Cops, ") || s.Contains("DVD-Cops, "))); + if (match != null) + if (match.Contains("CD-Cops")) + return $"CD-Cops {GetVersionString(match)}"; + else if (match.Contains("DVD-Cops")) + return $"DVD-Cops {GetVersionString(match)}"; + } + return null; } @@ -206,6 +225,16 @@ public List CheckDirectoryPath(string path, List? files) new(new PathMatch(".GZ_", matchCase: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"), new(new PathMatch(".Qz", matchCase: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"), + + // Found in Redump entries 84517, 108167, 119435, 119436, and 119437. This is the official + // name from their website https://www.linkdatasecurity.com/index.htm#/protection-products/cd-dvd-usb-copy-protection/cdcops + // I can't find this specific filename documented anywhere, but, all of these + // games do not require a key to be input + new(new FilePathMatch("cdcode.key"), "CD-Cops Codefree"), + + // DVD-Cops Codefree does exist https://www.linkdatasecurity.com/index.htm#/protection-products/cd-dvd-usb-copy-protection/dvdvers + // but we currently have no samples. Presumably this is what the file would be called? + new(new FilePathMatch("dvdcode.key"), "DVD-Cops Codefree (Unconfirmed - Please report to us on Github)"), }; return MatchUtil.GetAllMatches(files, matchers, any: true); @@ -226,6 +255,15 @@ public List CheckDirectoryPath(string path, List? files) new(new PathMatch(".GZ_", matchCase: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"), new(new PathMatch(".Qz", matchCase: true, useEndsWith: true), "CD-Cops (Unconfirmed - Please report to us on Github)"), + // Found in Redump entries 84517, 108167, 119435, 119436, and 119437. This is the official + // name from their website https://www.linkdatasecurity.com/index.htm#/protection-products/cd-dvd-usb-copy-protection/cdcops + // I can't find this specific filename documented anywhere, but, all of these + // games do not require a key to be input + new(new FilePathMatch("cdcode.key"), "CD-Cops Codefree"), + + // DVD-Cops Codefree does exist https://www.linkdatasecurity.com/index.htm#/protection-products/cd-dvd-usb-copy-protection/dvdvers + // but we currently have no samples. Presumably this is what the file would be called? + new(new FilePathMatch("dvdcode.key"), "DVD-Cops Codefree (Unconfirmed - Please report to us on Github)"), }; return MatchUtil.GetFirstMatch(path, matchers, any: true); @@ -243,5 +281,17 @@ public List CheckDirectoryPath(string path, List? files) return version; } + + private static string GetVersionString(string match) + { + // Full string ends with # (i.e. "CD-Cops, ver. 1.72, #"), use that to compensate for comma in version + // number cases (don't change the comma, see earlier to-do) like "DVD-Cops, ver. 1,60, #" + // TODO: improve regex via the starting "N" character? Possibly unnecessary? + var versionMatch = Regex.Match(match, @"(?<=D-Cops,\s{1,}ver. )(.*?)(?=,\s{1,}#)"); + if (versionMatch.Success) + return versionMatch.Value; + + return "(Unknown Version - Please report to us on GitHub)"; + } } }