@@ -29,16 +29,51 @@ public class StarForce : IDiskImageCheck<ISO9660>, IExecutableCheck<PortableExec
2929 if ( diskImage . VolumeDescriptorSet [ 0 ] is not PrimaryVolumeDescriptor pvd )
3030 return null ;
3131
32- // Starforce Keyless check #1: the reserved 653 bytes start with a 32-bit LE number that's slightly less
32+ int offset = 0 ;
33+
34+ // StarForce Keyless check: the key is stored in the Data Preparer identifier.
35+ string ? dataPreparerIdentiferString = pvd . DataPreparerIdentifier . ReadNullTerminatedAnsiString ( ref offset ) ? . Trim ( ) ;
36+
37+ if ( dataPreparerIdentiferString != null
38+ && dataPreparerIdentiferString . Length != 0
39+ && Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9-]*$" ) )
40+ {
41+ // It is returning the key, as it tells you what set of DPM your disc corresponds to, and it would also
42+ // help show why a disc might be an alt of another disc (there are at least a decent amount of StarForce
43+ // Keyless alts that would amtch otherwise). Unclear if this is desired by the users of BOS or those
44+ // affected by it.
45+
46+ // Thus far, the StarForce Keyless key is always made up of a number of characters, all either capital letters or
47+ // numbers, sometimes with dashes in between. Thus far, 4 formats have been observed:
48+ // XXXXXXXXXXXXXXXXXXXXXXXXX (25 characters)
49+ // XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (25 characters, plus 4 dashes seperating 5 groups of 5)
50+ // XXXXXXXXXXXXXXXXXXXXXXXXXXXX (28 characters)
51+ // XXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX (28 characters, with 4 dashes)
52+ if ( Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{25}$" )
53+ || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$" )
54+ || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{28}$" )
55+ || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$" ) )
56+ {
57+ return $ "StarForce Keyless - { dataPreparerIdentiferString } ";
58+ }
59+
60+ // Redump ID 60270 is a unique case, there could possibly be more.
61+ if ( UnusualStarforceKeylessKeys . ContainsKey ( dataPreparerIdentiferString ) )
62+ return $ "StarForce Keyless - { dataPreparerIdentiferString } ";
63+ }
64+
65+ // Starforce general check: the reserved 653 bytes start with a 32-bit LE number that's slightly less
3366 // than the length of the volume size space. The difference varies, it's usually around 10. Check 500 to be
34- // safe. The rest of the data is all 0x00.
67+ // safe. The rest of the data is all 0x00. Not many starforce discs have this, but some do, and it's
68+ // currently the only known non-keyless check. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578,
69+ // 78200 are some examples.
3570 if ( FileType . ISO9660 . NoteworthyApplicationUse ( pvd ) )
3671 return null ;
3772
3873 if ( ! FileType . ISO9660 . NoteworthyReserved653Bytes ( pvd ) )
3974 return null ;
4075
41- int offset = 0 ;
76+ offset = 0 ;
4277
4378 var reserved653Bytes = pvd . Reserved653Bytes ;
4479 uint initialValue = reserved653Bytes . ReadUInt32LittleEndian ( ref offset ) ;
@@ -48,48 +83,7 @@ public class StarForce : IDiskImageCheck<ISO9660>, IExecutableCheck<PortableExec
4883 // through here.
4984 if ( initialValue > pvd . VolumeSpaceSize || initialValue + 500 < pvd . VolumeSpaceSize || ! Array . TrueForAll ( zeroBytes , b => b == 0x00 ) )
5085 return null ;
51-
52- offset = 0 ;
53-
54- // StarForce Keyless check #2: the key is stored in the Data Preparer identifier.
55-
56- // It turns out that some (i.e. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578, 78200)
57- // non-keyless StarForce discs still have this value here? This check may need to be disabled, but it
58- // seems to avoid any false positives in practice so far.
59- var dataPreparerIdentiferString = pvd . DataPreparerIdentifier . ReadNullTerminatedAnsiString ( ref offset ) ? . Trim ( ) ;
60- if ( dataPreparerIdentiferString == null || dataPreparerIdentiferString . Length == 0 )
61- return "StarForce" ;
62-
63- // It is returning the key, as it tells you what set of DPM your disc corresponds to, and it would also
64- // help show why a disc might be an alt of another disc (there are at least a decent amount of StarForce
65- // Keyless alts that would amtch otherwise). Unclear if this is desired by the users of BOS or those
66- // affected by it.
67-
68- // Thus far, the StarForce Keyless key is always made up of a number of characters, all either capital letters or
69- // numbers, sometimes with dashes in between. Thus far, 4 formats have been observed:
70- // XXXXXXXXXXXXXXXXXXXXXXXXX (25 characters)
71- // XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (25 characters, plus 4 dashes seperating 5 groups of 5)
72- // XXXXXXXXXXXXXXXXXXXXXXXXXXXX (28 characters)
73- // XXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX (28 characters, with 4 dashes)
74- if ( Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{25}$" )
75- || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$" )
76- || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{28}$" )
77- || Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$" ) )
78- {
79- return $ "StarForce Keyless - { dataPreparerIdentiferString } ";
80- }
81-
82- // Redump ID 60270 is a unique case, there could possibly be more.
83- if ( UnusualStarforceKeylessKeys . ContainsKey ( dataPreparerIdentiferString ) )
84- return $ "StarForce Keyless - { dataPreparerIdentiferString } ";
85-
86- // In case any variants were missed.
87- if ( Regex . IsMatch ( dataPreparerIdentiferString , "^[A-Z0-9-]*$" ) )
88- return $ "StarForce Keyless - { dataPreparerIdentiferString } - Unknown variant, please report to us on GitHub!";
89-
90- // 34206 reaches this because it's not keyless, and has "WinISO software" as the DPI string. However, since
91- // it has lowercase letters and spaces, it's caught here. It is genuinely StarForce, so it's not a false
92- // positive.
86+
9387 return "StarForce" ;
9488 }
9589
0 commit comments