Overhaul existing and add new audio CD protections (#131)

* Overhaul existing and add new audio CD protections

Overhaul many audio CD protections, on top of adding a few more. Unfortunately, disable key2Audio detection as well, as the existing checks were simply detecting OpenMG components and not key2Audio itself.

* Fix issues from PR review
This commit is contained in:
SilasLaspada
2022-07-07 16:24:41 -06:00
committed by GitHub
parent af95ca08c3
commit 8502924083
10 changed files with 282 additions and 68 deletions

View File

@@ -225,6 +225,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
/// </summary>
public string LegalCopyright { get; private set; }
/// <summary>
/// Legal trademarks resource string
/// </summary>
public string LegalTrademarks { get; private set; }
/// <summary>
/// Description manifest string
/// </summary>
@@ -791,6 +796,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
this.FileVersion = GetResourceString("FileVersion")?.Replace(", ", ".");
this.InternalName = GetResourceString("InternalName");
this.LegalCopyright = GetResourceString("LegalCopyright");
this.LegalTrademarks = GetResourceString("LegalTrademarks");
this.OriginalFileName = GetResourceString("OriginalFileName");
this.ProductName = GetResourceString("ProductName");
this.ProductVersion = GetResourceString("ProductVersion")?.Replace(", ", ".");

View File

@@ -53,7 +53,7 @@ namespace BurnOutSharp.ProtectionType
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -0,0 +1,16 @@
namespace BurnOutSharp.ProtectionType
{
/// <summary>
/// Key2Audio is an audio CD copy protection created by Sony. The initial version, simply called key2audio, appears to simply attempt to make the disc unplayable on a computer.
/// Further investigation is needed to determine if this first version is able to be detected, or if there's no identifying data present on these.
/// The other major version, key2AudioXS, appears to be a standard audio CD protection that uses, at the very least, WMDS DRM, and quite possibly OpenMG as well.
/// Key2AudioXS appears to have three sessions total, and some reports online indicate it may have a partially invalid TOC.
/// References:
/// https://web.archive.org/web/20070507073131/http://www.cdfreaks.com/reviews/Key2Audio-explained-and-should-we-fear-it-
/// https://www.cdmediaworld.com/hardware/cdrom/cd_protections_key2audio.shtml
/// </summary>
public class Key2Audio
{
// TODO: Implement
}
}

View File

@@ -1,53 +0,0 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using BurnOutSharp.ExecutableType.Microsoft.PE;
using BurnOutSharp.Interfaces;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
public class Key2AudioXS : IPortableExecutableCheck
{
/// <inheritdoc/>
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex?.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
if (!string.IsNullOrWhiteSpace(name) && name.Contains("SDKHM (KEEP)"))
return "key2AudioXS";
else if (!string.IsNullOrWhiteSpace(name) && name.Contains("SDKHM (KEPT)"))
return "key2AudioXS";
return null;
}
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
// TODO: Verify if these are OR or AND
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("SDKHM.EXE", useEndsWith: true), "key2AudioXS"),
new PathMatchSet(new PathMatch("SDKHM.DLL", useEndsWith: true), "key2AudioXS"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
}
/// <inheritdoc/>
public string CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
new PathMatchSet(new PathMatch("SDKHM.EXE", useEndsWith: true), "key2AudioXS"),
new PathMatchSet(new PathMatch("SDKHM.DLL", useEndsWith: true), "key2AudioXS"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using BurnOutSharp.ExecutableType.Microsoft.PE;
using BurnOutSharp.Interfaces;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
/// <summary>
/// LabelGate CD is a copy protection used by Sony in some Japanese CD releases. There are at least two distinct versions, characterized by the presence of either "MAGIQLIP" or "MAGIQLIP2".
/// It made use of Sony OpenMG DRM, and allowed users to make limited copies.
/// References:
/// https://web.archive.org/web/20040604223749/http://www.sonymusic.co.jp/cccd/
/// https://web.archive.org/web/20040407150004/http://www.sonymusic.co.jp/cccd/lgcd2/help/foreign.html
/// https://vgmdb.net/forums/showthread.php?p=92206
/// </summary>
public class LabelGate : IPathCheck, IPortableExecutableCheck
{
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex?.SectionTable;
if (sections == null)
return null;
// Should be present on all LabelGate CD2 discs (Redump entry 95010 and product ID SVWC-7185).
string name = pex.FileDescription;
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("MAGIQLIP2 Installer", StringComparison.OrdinalIgnoreCase))
return $"LabelGate CD2 Media Player";
name = pex.ProductName;
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("MQSTART", StringComparison.OrdinalIgnoreCase))
return $"LabelGate CD2 Media Player";
// Get the .data section, if it exists
if (pex.DataSectionRaw != null)
{
var matchers = new List<ContentMatchSet>
{
// LGCD2_LAUNCH
// Found in "START.EXE" (Redump entry 95010 and product ID SVWC-7185).
new ContentMatchSet(new byte?[] { 0x4C, 0x47, 0x43, 0x44, 0x32, 0x5F, 0x4C, 0x41, 0x55, 0x4E, 0x43, 0x48 }, "LabelGate CD2"),
};
string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
return null;
}
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
{
// All found to be present on at multiple albums with LabelGate CD2 (Redump entry 95010 and product ID SVWC-7185), the original version of LabelGate still needs to be investigated.
new PathMatchSet(new List<PathMatch>
{
new PathMatch(Path.Combine("BIN", "WIN32", "MQ2SETUP.EXE").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("BIN", "WIN32", "MQSTART.EXE").Replace("\\", "/"), useEndsWith: true),
}, "LabelGate CD2 Media Player"),
// All of these are also found present on all known LabelGate CD2 releases, though an additional file "RESERVED.DAT" is found in the same directory in at least one release (Product ID SVWC-7185)
new PathMatchSet(new List<PathMatch>
{
new PathMatch(Path.Combine("MQDISC", "LICENSE.TXT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("MQDISC", "MQDISC.INI").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("MQDISC", "START.INI").Replace("\\", "/"), useEndsWith: true),
}, "LabelGate CD2"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>
public string CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// This is the installer for the media player used by LabelGate CD2 (Redump entry 95010 and product ID SVWC-7185).
new PathMatchSet(new PathMatch("MQ2SETUP.EXE", useEndsWith: true), "LabelGate CD2 Media Player"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -7,10 +7,12 @@ using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// MediaMax CD-3 is a copy protection for audio CDs created by SunnComm, which once installed, restricted users by only allowing a limited number of copies to be made, and only using Windows Media Player.
// It appears to accomplish this using the official Windows Media Data Session Toolkit.
// List of discs known to contain MediaMax CD-3: https://en.wikipedia.org/wiki/List_of_compact_discs_sold_with_MediaMax_CD-3
// TODO: Add support for detecting the Mac version, which is present on "All That I Am" by Santana (Barcode 8 2876-59773-2 6)
/// <summary>
/// MediaMax CD-3 is a copy protection for audio CDs created by SunnComm, which once installed, restricted users by only allowing a limited number of copies to be made, and only using Windows Media Player.
/// It appears to accomplish this using the official Windows Media Data Session Toolkit.
/// List of discs known to contain MediaMax CD-3: https://en.wikipedia.org/wiki/List_of_compact_discs_sold_with_MediaMax_CD-3
/// TODO: Add support for detecting the Mac version, which is present on "All That I Am" by Santana (Barcode 8 2876-59773-2 6)
/// </summary>
public class MediaMaxCD3 : IPathCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
@@ -105,7 +107,7 @@ namespace BurnOutSharp.ProtectionType
}, "MediaMax CD-3"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using BurnOutSharp.ExecutableType.Microsoft.PE;
using BurnOutSharp.Interfaces;
using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
/// <summary>
/// OpenMG is a form of DRM created by Sony to control how music is copied and listened to on PC.
/// It is known to be used with multiple CD audio protections, such as XCP, LabelGate, and quite possibly Key2AudioXS.
/// References:
/// https://en.wikipedia.org/wiki/OpenMG
/// </summary>
public class OpenMG : IPathCheck, IPortableExecutableCheck
{
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
{
// Get the sections from the executable, if possible
var sections = pex?.SectionTable;
if (sections == null)
return null;
// Found in many different OpenMG related files ("Touch" by Amerie).
string name = pex.LegalTrademarks;
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("OpenMG", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "OMGDBP.OCX" ("Touch" by Amerie).
name = pex.FileDescription;
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("LGDiscComp Module", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "OMGDWRAP.DLL" ("Touch" by Amerie).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("LGDSimplePlayer Module", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "OMGLGD.DLL" ("Touch" by Amerie).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("omglgd Module", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "OMGUTILS.DLL" ("Touch" by Amerie).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("OpenMG Utility", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "SALWRAP.DLL" ("Touch" by Amerie).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Secure Application Loader Wrapper", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "SDKHM.DLL" ("Touch" by Amerie).
// Not every copy of this file has this File Description (Redump entry 95010).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("SDKHM (KEEP)", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
// Found in "SDKHM.EXE" ("Touch" by Amerie).
// Not every copy of this file has this File Description (Redump entry 95010).
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("SDKHM (KEPT)", StringComparison.OrdinalIgnoreCase))
return $"OpenMG";
return null;
}
/// <inheritdoc/>
public ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string> files)
{
var matchers = new List<PathMatchSet>
{
// So far found in every known release that uses OpenMG ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
// Files with the extension ".OMA" in the directory "OMGAUDIO" are the encrypted audio files, and files with in the directory "OMGEXTRA" the extension ".000" are bonus content.
// TODO: Investigate the consistency of "\OMGEXTRA\INDX0000.XML" and "\OMGEXTRA\INDX0001.XML", they seem to only appear when bonus content is present ("Touch" by Amerie).
new PathMatchSet(new List<PathMatch>
{
new PathMatch(Path.Combine("OMGAUDIO", "00AUDTOC.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGAUDIO", "01AUDSTR.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGAUDIO", "05SRPCDS.DAT").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("OMGEXTRA", "OMGSVC.DAT").Replace("\\", "/"), useEndsWith: true),
}, "OpenMG"),
// Always found together on OpenMG releases ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new List<PathMatch>
{
new PathMatch(Path.Combine("SDKHM.DLL").Replace("\\", "/"), useEndsWith: true),
new PathMatch(Path.Combine("SDKHM.EXE").Replace("\\", "/"), useEndsWith: true),
}, "OpenMG"),
};
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>
public string CheckFilePath(string path)
{
var matchers = new List<PathMatchSet>
{
// So far found in every known release that uses OpenMG ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new PathMatch("00AUDTOC.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("01AUDSTR.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("05SRPCDS.DAT", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGSVC.DAT", useEndsWith: true), "OpenMG"),
// Always found together on OpenMG releases ("Touch" by Amerie, Redump entry 95010, and product ID SVWC-7185).
new PathMatchSet(new PathMatch("SDKHM.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("SDKHM.EXE", useEndsWith: true), "OpenMG"),
// Found together on one specific release ("Touch" by Amerie).
// TODO: Verify if these are OR or AND
new PathMatchSet(new PathMatch("OMGDBP.OCX", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGDWRAP.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGLGD.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("OMGUTILS.DLL", useEndsWith: true), "OpenMG"),
new PathMatchSet(new PathMatch("SALWRAP.DLL", useEndsWith: true), "OpenMG"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
}
}
}

View File

@@ -3,5 +3,6 @@
public class SAFEAUDIO
{
// TODO: Implement - https://www.cdmediaworld.com/hardware/cdrom/cd_protections_safeaudio.shtml
// https://web.archive.org/web/20070406011304/http://www.cdfreaks.com/reviews/SafeAudio-explained-and-should-we-fear-it-
}
}

View File

@@ -7,10 +7,12 @@ using BurnOutSharp.Matching;
namespace BurnOutSharp.ProtectionType
{
// The Windows Media Data Session Toolkit was created as a form of DRM for audio CDs (and supposedly DVDs, but with no standard for multiple sessions existing for pressed DVDs, this seems unlikely), which ultimately acts a framework
// It seems to provide a framework for standardized storing of protected music, as well as allowing the disc publisher to specify how many copies they wish users to be able to create using Windows Media Player.
// Known to be used along with MediaMax CD-3, possibly others.
// Reference: https://news.microsoft.com/2003/01/20/microsoft-releases-new-windows-media-data-session-toolkit-enabling-second-session-creation/
/// <summary>
/// The Windows Media Data Session Toolkit was created as a form of DRM for audio CDs (and supposedly DVDs, but with no standard for multiple sessions existing for pressed DVDs, this seems unlikely), which ultimately acts a framework
/// It seems to provide a framework for standardized storing of protected music, as well as allowing the disc publisher to specify how many copies they wish users to be able to create using Windows Media Player.
/// Known to be used along with MediaMax CD-3 and XCP2, possibly others.
/// Reference: https://news.microsoft.com/2003/01/20/microsoft-releases-new-windows-media-data-session-toolkit-enabling-second-session-creation/
/// </summary>
public class WMDS : IPathCheck, IPortableExecutableCheck
{
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
@@ -25,6 +27,31 @@ namespace BurnOutSharp.ProtectionType
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("Windows Media Data Session Licensing Engine", StringComparison.OrdinalIgnoreCase))
return $"Windows Media Data Session DRM";
// Get the .rdata section, if it exists
if (pex.ResourceDataSectionRaw != null)
{
var matchers = new List<ContentMatchSet>
{
// You cannot generate a licence to play the protected Windows Media files without an original disc.
// Found in "autorun.exe" ("Touch" by Amerie).
new ContentMatchSet(new byte?[] {
0x59, 0x6F, 0x75, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x67,
0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x6C, 0x69,
0x63, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x6C, 0x61,
0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x74, 0x65, 0x63,
0x74, 0x65, 0x64, 0x20, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20,
0x4D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x20,
0x77, 0x69, 0x74, 0x68, 0x6F, 0x75, 0x74, 0x20, 0x61, 0x6E, 0x20, 0x6F,
0x72, 0x69, 0x67, 0x69, 0x6E, 0x61, 0x6C, 0x20, 0x64, 0x69, 0x73, 0x63,
0x2E
}, "Windows Media Data Session DRM"),
};
string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
return null;
}
@@ -33,16 +60,16 @@ namespace BurnOutSharp.ProtectionType
{
var matchers = new List<PathMatchSet>
{
// Found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6) and "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8), likely among others.
// Found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6) and "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8), "Touch" by Amerie, likely among others.
new PathMatchSet(new List<PathMatch>
{
// TODO: Verify if these are OR or AND
// These files always appear to be present together.
new PathMatch("WMDS.dll", useEndsWith: true),
new PathMatch("WMDS.ini", useEndsWith: true),
}, "Windows Media Data Session DRM"),
};
return MatchUtil.GetAllMatches(files, matchers, any: true);
return MatchUtil.GetAllMatches(files, matchers, any: false);
}
/// <inheritdoc/>
@@ -50,9 +77,12 @@ namespace BurnOutSharp.ProtectionType
{
var matchers = new List<PathMatchSet>
{
// Found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6) and "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8), likely among others.
// Found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6) and "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8), "Touch" by Amerie, likely among others.
new PathMatchSet(new PathMatch("WMDS.dll", useEndsWith: true), "Windows Media Data Session DRM"),
new PathMatchSet(new PathMatch("WMDS.ini", useEndsWith: true), "Windows Media Data Session DRM"),
// Found on "Touch" by Amerie, along with "autorun.exe".
new PathMatchSet(new PathMatch("WMDST.DAT", useEndsWith: true), "Windows Media Data Session DRM"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);

View File

@@ -57,12 +57,14 @@ Below is a list of protections detected by BurnOutSharp. The two columns explain
| IndyVCD | False | True | Unconfirmed¹ |
| ITENIUM Trial & Buy Protection | True | False | |
| JoWood X-Prot (v1/v2) / Xtreme-Protector | True | False | |
| Key2Audio XS | True | True | |
| ~~Key2Audio~~ | True | True | Existing checks found to actually be indicators of OpenMG, not key2Audio specifically. |
| Key-Lock (Dongle) | True | False | Unconfirmed¹ |
| LabelGate CD | True | True | Currently only LabelGate CD2 is detected. |
| LibCrypt | True | False | Separate subfile scan only |
| LaserLok | True | True | |
| MediaCloQ | False | True | Unconfirmed¹ |
| MediaMax CD3 | True | True | |
| OpenMG | True | True | |
| Origin | True | True | |
| phenoProtect | False | False | Text file check only |
| ProtectDISC / VOB ProtectCD/DVD | True | False | |