mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-04-24 15:13:23 +00:00
Improve starforce keyless detection (#396)
This commit is contained in:
committed by
GitHub
parent
cc7592e07a
commit
805beb3418
@@ -29,16 +29,51 @@ namespace BinaryObjectScanner.Protection
|
||||
if (diskImage.VolumeDescriptorSet[0] is not PrimaryVolumeDescriptor pvd)
|
||||
return null;
|
||||
|
||||
// Starforce Keyless check #1: the reserved 653 bytes start with a 32-bit LE number that's slightly less
|
||||
int offset = 0;
|
||||
|
||||
// StarForce Keyless check: the key is stored in the Data Preparer identifier.
|
||||
string? dataPreparerIdentiferString = pvd.DataPreparerIdentifier.ReadNullTerminatedAnsiString(ref offset)?.Trim();
|
||||
|
||||
if (dataPreparerIdentiferString != null
|
||||
&& dataPreparerIdentiferString.Length != 0
|
||||
&& Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9-]*$"))
|
||||
{
|
||||
// It is returning the key, as it tells you what set of DPM your disc corresponds to, and it would also
|
||||
// help show why a disc might be an alt of another disc (there are at least a decent amount of StarForce
|
||||
// Keyless alts that would amtch otherwise). Unclear if this is desired by the users of BOS or those
|
||||
// affected by it.
|
||||
|
||||
// Thus far, the StarForce Keyless key is always made up of a number of characters, all either capital letters or
|
||||
// numbers, sometimes with dashes in between. Thus far, 4 formats have been observed:
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXX (25 characters)
|
||||
// XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (25 characters, plus 4 dashes seperating 5 groups of 5)
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXX (28 characters)
|
||||
// XXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX (28 characters, with 4 dashes)
|
||||
if (Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{25}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{28}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"))
|
||||
{
|
||||
return $"StarForce Keyless - {dataPreparerIdentiferString}";
|
||||
}
|
||||
|
||||
// Redump ID 60270 is a unique case, there could possibly be more.
|
||||
if (UnusualStarforceKeylessKeys.ContainsKey(dataPreparerIdentiferString))
|
||||
return $"StarForce Keyless - {dataPreparerIdentiferString}";
|
||||
}
|
||||
|
||||
// Starforce general check: the reserved 653 bytes start with a 32-bit LE number that's slightly less
|
||||
// than the length of the volume size space. The difference varies, it's usually around 10. Check 500 to be
|
||||
// safe. The rest of the data is all 0x00.
|
||||
// safe. The rest of the data is all 0x00. Not many starforce discs have this, but some do, and it's
|
||||
// currently the only known non-keyless check. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578,
|
||||
// 78200 are some examples.
|
||||
if (FileType.ISO9660.NoteworthyApplicationUse(pvd))
|
||||
return null;
|
||||
|
||||
if (!FileType.ISO9660.NoteworthyReserved653Bytes(pvd))
|
||||
return null;
|
||||
|
||||
int offset = 0;
|
||||
offset = 0;
|
||||
|
||||
var reserved653Bytes = pvd.Reserved653Bytes;
|
||||
uint initialValue = reserved653Bytes.ReadUInt32LittleEndian(ref offset);
|
||||
@@ -48,48 +83,7 @@ namespace BinaryObjectScanner.Protection
|
||||
// through here.
|
||||
if (initialValue > pvd.VolumeSpaceSize || initialValue + 500 < pvd.VolumeSpaceSize || !Array.TrueForAll(zeroBytes, b => b == 0x00))
|
||||
return null;
|
||||
|
||||
offset = 0;
|
||||
|
||||
// StarForce Keyless check #2: the key is stored in the Data Preparer identifier.
|
||||
|
||||
// It turns out that some (i.e. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578, 78200)
|
||||
// non-keyless StarForce discs still have this value here? This check may need to be disabled, but it
|
||||
// seems to avoid any false positives in practice so far.
|
||||
var dataPreparerIdentiferString = pvd.DataPreparerIdentifier.ReadNullTerminatedAnsiString(ref offset)?.Trim();
|
||||
if (dataPreparerIdentiferString == null || dataPreparerIdentiferString.Length == 0)
|
||||
return "StarForce";
|
||||
|
||||
// It is returning the key, as it tells you what set of DPM your disc corresponds to, and it would also
|
||||
// help show why a disc might be an alt of another disc (there are at least a decent amount of StarForce
|
||||
// Keyless alts that would amtch otherwise). Unclear if this is desired by the users of BOS or those
|
||||
// affected by it.
|
||||
|
||||
// Thus far, the StarForce Keyless key is always made up of a number of characters, all either capital letters or
|
||||
// numbers, sometimes with dashes in between. Thus far, 4 formats have been observed:
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXX (25 characters)
|
||||
// XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (25 characters, plus 4 dashes seperating 5 groups of 5)
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXX (28 characters)
|
||||
// XXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX (28 characters, with 4 dashes)
|
||||
if (Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{25}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{28}$")
|
||||
|| Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"))
|
||||
{
|
||||
return $"StarForce Keyless - {dataPreparerIdentiferString}";
|
||||
}
|
||||
|
||||
// Redump ID 60270 is a unique case, there could possibly be more.
|
||||
if (UnusualStarforceKeylessKeys.ContainsKey(dataPreparerIdentiferString))
|
||||
return $"StarForce Keyless - {dataPreparerIdentiferString}";
|
||||
|
||||
// In case any variants were missed.
|
||||
if (Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9-]*$"))
|
||||
return $"StarForce Keyless - {dataPreparerIdentiferString} - Unknown variant, please report to us on GitHub!";
|
||||
|
||||
// 34206 reaches this because it's not keyless, and has "WinISO software" as the DPI string. However, since
|
||||
// it has lowercase letters and spaces, it's caught here. It is genuinely StarForce, so it's not a false
|
||||
// positive.
|
||||
|
||||
return "StarForce";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user