mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-09 02:16:46 +00:00
Properly differentiate between Code-Lock and CopyLok (TheRogueArchivist)
This commit is contained in:
@@ -9,6 +9,7 @@ using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// TODO: Investigate "Cops Copylock II" (https://www.cbmstuff.com/forum/showthread.php?tid=488).
|
||||
public class CDDVDCops : IContentCheck, INewExecutableCheck, IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
|
||||
113
BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs
Normal file
113
BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Code-Lock by ChosenBytes (https://web.archive.org/web/20040225072021/http://chosenbytes.com/) is a form of DRM that protects Visual Basic and .NET programs.
|
||||
/// It requires the use of a registration code that is unique to each individual user (https://web.archive.org/web/20031210093259/http://www.chosenbytes.com/codemain.php).
|
||||
/// As an advertising point, ChosenBytes apparently held a contest with a cash prize to see if a protected file could be cracked (https://web.archive.org/web/20031106163334/http://www.chosenbytes.com/challenge.php).
|
||||
///
|
||||
/// Previous versions of BurnOutSharp incorrectly reported this DRM as "CodeLock / CodeLok / CopyLok". It was later discovered that due to the similar names, two entirely different DRM were erroneously lumped together.
|
||||
/// Not only is "CodeLok / CopyLok" an entirely separate form of DRM, but "CodeLock" (as opposed to "Code-Lock") appears to refer specifically to another unrelated DRM (https://web.archive.org/web/20031106033758/http://www.codelock.co.nz/).
|
||||
/// Also not to be confused with https://www.youtube.com/watch?v=AHqdgk0uJyc.
|
||||
///
|
||||
/// Code-Lock FAQ: https://web.archive.org/web/20041205165232/http://www.chosenbytes.com/codefaq.php
|
||||
/// Download (Version 2.35 trial): https://web.archive.org/web/20060220121200/http://www.chosenbytes.com:80/Code-Lock_cnet.zip
|
||||
/// </summary>
|
||||
public class ChosenBytesCodeLock : IContentCheck, IPathCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable.
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// CODE-LOCK.OCX
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x43, 0x4F, 0x44, 0x45, 0x2D, 0x4C, 0x4F, 0x43,
|
||||
0x4B, 0x2E, 0x4F, 0x43, 0x58
|
||||
}, "ChosenBytes Code-Lock (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
// Found in "Code-Lock.ocx" in Code-Lock version 2.35.
|
||||
// Also worth noting is the File Description for this file, which is "A future for you, a challenge for the rest.".
|
||||
// This check is currently broken until executable checks are overhauled.
|
||||
string name = pex.ProductName;
|
||||
if (name?.StartsWith("Code-Lock", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"ChosenBytes Code-Lock {pex.ProductVersion}";
|
||||
|
||||
// Get the .text section, if it exists
|
||||
if (pex.TextSectionRaw != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// Found in compiled code examples created with Code-Lock 2.35.
|
||||
// Code-Lock.ocx
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x43, 0x6F, 0x64, 0x65, 0x2D, 0x4C, 0x6F, 0x63,
|
||||
0x6B, 0x2E, 0x6F, 0x63, 0x78
|
||||
}, "ChosenBytes Code-Lock"),
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, 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>
|
||||
{
|
||||
// Found in the installation directory of Code-Lock version 2.35.
|
||||
new PathMatchSet(new PathMatch("Code-Lock.chm", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock.DEP", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock.ocx", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock Wizard.exe", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetAllMatches(files, matchers, any: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckFilePath(string path)
|
||||
{
|
||||
var matchers = new List<PathMatchSet>
|
||||
{
|
||||
// Found in the installation directory of Code-Lock version 2.35.
|
||||
new PathMatchSet(new PathMatch("Code-Lock.chm", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock.DEP", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock.ocx", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
new PathMatchSet(new PathMatch("Code-Lock Wizard.exe", useEndsWith: true), "ChosenBytes Code-Lock"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(path, matchers, any: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
using BurnOutSharp.Matching;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
// CodeLock / CodeLok / CopyLok
|
||||
public class CodeLock : IContentCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// CODE-LOCK.OCX
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x43, 0x4F, 0x44, 0x45, 0x2D, 0x4C, 0x4F, 0x43,
|
||||
0x4B, 0x2E, 0x4F, 0x43, 0x58
|
||||
}, "CodeLock / CodeLok / CopyLok (Unconfirmed - Please report to us on Github)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
// If there are more than 2 icd-prefixed sections, then we have a match
|
||||
// Found in Redump entry 31557.
|
||||
int icdSectionCount = pex.GetSectionNames().Count(s => s.StartsWith("icd"));
|
||||
if (icdSectionCount >= 2)
|
||||
return "CodeLock / CodeLok / CopyLok";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
BurnOutSharp/ProtectionType/CopyLok.cs
Normal file
43
BurnOutSharp/ProtectionType/CopyLok.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Linq;
|
||||
using BurnOutSharp.ExecutableType.Microsoft.PE;
|
||||
using BurnOutSharp.Interfaces;
|
||||
|
||||
namespace BurnOutSharp.ProtectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// CopyLok (AKA CodeLok) is a DRM created by PAN Technology (https://web.archive.org/web/19991117100625/http://www.pantechnology.com/).
|
||||
/// More specifically, it may have been created a spin-off division known as "Panlok" (https://cdmediaworld.com/hardware/cdrom/cd_protections_copylok.shtml).
|
||||
/// Though it may also be that "PanLok" was an alternate name for the program itself (https://gamecopyworld.com/games/pc_generic_copylok.shtml).
|
||||
/// There was a PanLok website, but it's unknown what content it had hosted (https://web.archive.org/web/20041215075727/http://www.panlok.com/).
|
||||
///
|
||||
/// CopyLok made use of bad sectors, using an average of 720-750 per disc, and appears to have been a form of ring protection (http://forum.redump.org/topic/29842/issues-dumping-pc-disc-with-code-lock-copy-protection/).
|
||||
/// At least one disc with CopyLok appears to contain an excerpt of the poem "Jabberwocky" by Lewis Carroll in the raw sector data (http://forum.redump.org/post/54050/#p54050).
|
||||
/// According to the Readme for poxylok (https://gf.wiretarget.com/copylok.htm), some version of Gangsters 2 may have this protection.
|
||||
///
|
||||
/// Previous versions of BurnOutSharp incorrectly reported this DRM as "CodeLock / CodeLok / CopyLok". It was later discovered that due to the similar names, two entirely different DRM were erroneously lumped together.
|
||||
/// "CodeLock" (in this case actually referring to "Code-Lock") is an entirely separate form of DRM, with the existing check now getting used separately.
|
||||
/// Also not to be confused with https://en.wikipedia.org/wiki/Rob_Northen_copylock.
|
||||
///
|
||||
/// COPYLOK trademark: https://www.trademarkelite.com/europe/trademark/trademark-detail/000618512/COPYLOK.
|
||||
/// </summary>
|
||||
public class CopyLok : 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;
|
||||
|
||||
// If there are more than 2 icd-prefixed sections, then we have a match
|
||||
// Though this is the same name that SafeDisc uses for protected executables, this seems to be a coincidence.
|
||||
// Found in Redump entries 31557, 31674, 31675, 31708, 38239, 44210, and 53929.
|
||||
int icdSectionCount = pex.GetSectionNames().Count(s => s.StartsWith("icd"));
|
||||
if (icdSectionCount >= 2)
|
||||
return "CopyLok / CodeLok";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,8 +42,9 @@ Below is a list of protections detected by BurnOutSharp. The two columns explain
|
||||
| CD-X | False | True | Unconfirmed¹ |
|
||||
| CDSHiELD SE | True | False | |
|
||||
| Cenga ProtectDVD | True | True | |
|
||||
| CodeLock / CodeLok / CopyLok | True | False | Partially unconfirmed² |
|
||||
| ChosenBytes CodeLock | True | True | Partially unconfirmed² |
|
||||
| CopyKiller | True | True | Unconfirmed¹ |
|
||||
| CopyLok/CodeLok | True | False | |
|
||||
| Cucko (EA Custom) | True | False | Does not detect all known cases |
|
||||
| Denuvo Anti-Cheat/Anti-Tamper| True | True | |
|
||||
| Dinamic Multimedia Protection/LockBlocks | False | True | LockBlocks needs manual confirmation of the presence of 2 rings |
|
||||
|
||||
Reference in New Issue
Block a user