@@ -10,7 +10,7 @@ namespace BinaryObjectScanner.Protection
1010 /// <summary>
1111 /// Alpha-ROM is a form of copy protection created by SETTEC. It is known to make use of twin sectors as well as region locking.
1212 /// Later forms of Alpha-ROM appear to be digital only, and it's currently unsure what forms of protection the digital only version includes, except that it does make use of region locking.
13- /// It seems that Alpha-ROM was used in Visual Novels using certain game engines, most notably RealLive and Siglus (https://forums.fuwanovel.net/topic/20927-cannot-crack-siglus-engine-with-alpharom/).
13+ /// It seems that Alpha-ROM was used in Visual Novels using certain game engines, most notably RealLive and Siglus (https://forums.fuwanovel.net/topic/20927-cannot-crack-siglus-engine-with-alpharom/).
1414 /// Not every Siglus engine game uses Alpha-ROM (Source: https://sample9.dmm.co.jp/digital/pcgame/vsat_0263/vsat_0263t.zip {Official trial mirror}).
1515 /// Not every RealLive engine game uses Alpha-ROM (Source: IA item "Kanon_Standard_Edition_Japan").
1616 /// Alpha-ROM also seems to have made use of something called "Alpha-DPS" for non-executable data files (http://www.gonsuke.co.jp/protect.html).
@@ -43,12 +43,57 @@ namespace BinaryObjectScanner.Protection
4343 // - SETTEC0000SETTEC1111
4444 // - SOFTWARE\SETTEC
4545 // TODO: Are there version numbers?
46- public class AlphaROM : IExecutableCheck < PortableExecutable > , IDiskImageCheck < ISO9660 >
46+ public class AlphaROM : IDiskImageCheck < ISO9660 > , IExecutableCheck < PortableExecutable >
4747 {
48+ /// <inheritdoc/>
49+ public string ? CheckDiskImage ( string file , ISO9660 diskImage , bool includeDebug )
50+ {
51+ // Checks can be made even easier once UDF support exists, as most (although not all, some early discs like
52+ // redump ID 124111 have no UDF partition) discs have "Settec" slathered over every field UDF lets them.
53+
54+ if ( diskImage . VolumeDescriptorSet . Length == 0 )
55+ return null ;
56+ if ( diskImage . VolumeDescriptorSet [ 0 ] is not PrimaryVolumeDescriptor pvd )
57+ return null ;
58+
59+ // Alpharom disc check #1: disc has varying (but observed to at least always be larger than 14) length
60+ // string made up of numbers and capital letters.
61+ // TODO: triple-check that length is never below 14
62+ int offset = 0 ;
63+ var applicationIdentifierString = pvd . ApplicationIdentifier . ReadNullTerminatedAnsiString ( ref offset ) ? . Trim ( ) ;
64+ if ( applicationIdentifierString == null || applicationIdentifierString . Length < 14 )
65+ return null ;
66+
67+ if ( ! Regex . IsMatch ( applicationIdentifierString , "^[A-Z0-9]*$" ) )
68+ return null ;
69+
70+ // Alpharom disc check #2: disc has publisher identifier filled with varying amount of data (26-50 bytes
71+ // have been observed) followed by spaces. There's a decent chance this is just a Japanese text string, but
72+ // UTF, Shift-JIS, and EUC-JP all fail to display anything but garbage.
73+
74+ var publisherIdentifier = pvd . PublisherIdentifier ;
75+ int firstSpace = Array . FindIndex ( publisherIdentifier , b => b == 0x20 ) ;
76+ if ( firstSpace <= 10 || firstSpace >= 120 )
77+ return null ;
78+
79+ var publisherData = new byte [ firstSpace ] ;
80+ var publisherSpaces = new byte [ publisherData . Length - firstSpace ] ;
81+ Array . Copy ( publisherIdentifier , 0 , publisherData , 0 , firstSpace ) ;
82+ Array . Copy ( publisherIdentifier , firstSpace , publisherSpaces , 0 , publisherData . Length - firstSpace ) ;
83+
84+ if ( ! Array . TrueForAll ( publisherSpaces , b => b == 0x20 ) )
85+ return null ;
86+
87+ if ( ! FileType . ISO9660 . IsPureData ( publisherData ) )
88+ return null ;
89+
90+ return "AlphaROM" ;
91+ }
92+
4893 /// <inheritdoc/>
4994 public string ? CheckExecutable ( string file , PortableExecutable exe , bool includeDebug )
5095 {
51- // TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
96+ // TODO: Add support for detecting Alpha-ROM found in older games made with the RealLive engine.
5297 // TODO: Add version detection for Alpha-ROM.
5398
5499 // Get the .data/DATA section strings, if they exist
@@ -88,51 +133,5 @@ public class AlphaROM : IExecutableCheck<PortableExecutable>, IDiskImageCheck<IS
88133
89134 return null ;
90135 }
91-
92- /// <inheritdoc/>
93- public string ? CheckDiskImage ( string file , ISO9660 diskImage , bool includeDebug )
94- {
95- // Checks can be made even easier once UDF support exists, as most (although not all, some early discs like
96- // redump ID 124111 have no UDF partition) discs have "Settec" slathered over every field UDF lets them.
97-
98- if ( diskImage . VolumeDescriptorSet . Length == 0 )
99- return null ;
100-
101- if ( diskImage . VolumeDescriptorSet [ 0 ] is not PrimaryVolumeDescriptor pvd )
102- return null ;
103-
104- // Alpharom disc check #1: disc has varying (but observed to at least always be larger than 14) length
105- // string made up of numbers and capital letters.
106- // TODO: triple-check that length is never below 14
107- int offset = 0 ;
108- var applicationIdentifierString = pvd . ApplicationIdentifier . ReadNullTerminatedAnsiString ( ref offset ) ? . Trim ( ) ;
109- if ( applicationIdentifierString == null || applicationIdentifierString . Length < 14 )
110- return null ;
111-
112- if ( ! Regex . IsMatch ( applicationIdentifierString , "^[A-Z0-9]*$" ) )
113- return null ;
114-
115- // Alpharom disc check #2: disc has publisher identifier filled with varying amount of data (26-50 bytes
116- // have been observed) followed by spaces. There's a decent chance this is just a Japanese text string, but
117- // UTF, Shift-JIS, and EUC-JP all fail to display anything but garbage.
118-
119- var publisherIdentifier = pvd . PublisherIdentifier ;
120- int firstSpace = Array . FindIndex ( publisherIdentifier , b => b == 0x20 ) ;
121- if ( firstSpace <= 10 || firstSpace >= 120 )
122- return null ;
123-
124- var publisherData = new byte [ firstSpace ] ;
125- var publisherSpaces = new byte [ publisherData . Length - firstSpace ] ;
126- Array . Copy ( publisherIdentifier , 0 , publisherData , 0 , firstSpace ) ;
127- Array . Copy ( publisherIdentifier , firstSpace , publisherSpaces , 0 , publisherData . Length - firstSpace ) ;
128-
129- if ( ! Array . TrueForAll ( publisherSpaces , b => b == 0x20 ) )
130- return null ;
131-
132- if ( ! FileType . ISO9660 . IsPureData ( publisherData ) )
133- return null ;
134-
135- return "AlphaROM" ;
136- }
137136 }
138137}
0 commit comments