@@ -35,6 +35,8 @@ class Offsets
35
35
public uint GenerateDexDisplayData ;
36
36
37
37
public uint GetSingletonAccessorInstance ;
38
+
39
+ public bool IsUltra ;
38
40
}
39
41
40
42
@@ -63,7 +65,9 @@ class Program
63
65
aeabi_memcpy = 0x1FEC20 ,
64
66
GenerateDexDisplayData = 0x2CD230 ,
65
67
66
- GetSingletonAccessorInstance = 0x48B4
68
+ GetSingletonAccessorInstance = 0x48B4 ,
69
+
70
+ IsUltra = false
67
71
} ;
68
72
69
73
private static readonly Offsets Offsets_1_1 = new Offsets
@@ -88,7 +92,9 @@ class Program
88
92
aeabi_memcpy = 0x1FEBD8 ,
89
93
GenerateDexDisplayData = 0x2CE714 ,
90
94
91
- GetSingletonAccessorInstance = 0x48B4
95
+ GetSingletonAccessorInstance = 0x48B4 ,
96
+
97
+ IsUltra = false
92
98
} ;
93
99
94
100
private static readonly Offsets Offsets_1_2 = new Offsets
@@ -113,7 +119,36 @@ class Program
113
119
aeabi_memcpy = 0x1FEBD8 ,
114
120
GenerateDexDisplayData = 0x2CE714 ,
115
121
116
- GetSingletonAccessorInstance = 0x48B4
122
+ GetSingletonAccessorInstance = 0x48B4 ,
123
+
124
+ IsUltra = false
125
+ } ;
126
+
127
+ private static readonly Offsets Ultra_Offsets_1_0 = new Offsets
128
+ {
129
+ CTRIsDebugMode = 0x4DE0 ,
130
+
131
+ DecryptQRCodeStart = 0x2DEEA0 ,
132
+ DecryptQRCodeEnd = 0x2DEF38 ,
133
+
134
+ AnalyzeQRBinaryStart = 0x2DF364 ,
135
+ AnalyzeQRBinaryEnd = 0x2DF8DC ,
136
+ QRReaderSaveDataBatteryQuery = 0x353864 ,
137
+
138
+ QRReaderSaveDataIsRegisteredData = 0x3C3D24 ,
139
+
140
+ ForbiddenQRs = 0x4CC724 ,
141
+
142
+ NoOutlines = 0x32E2B8 ,
143
+
144
+ CRC16 = 0x261534 ,
145
+ DexDataAllocator = 0x5500 ,
146
+ aeabi_memcpy = 0x1FED44 ,
147
+ GenerateDexDisplayData = 0x2DEB80 ,
148
+
149
+ GetSingletonAccessorInstance = 0x48B4 ,
150
+
151
+ IsUltra = true
117
152
} ;
118
153
119
154
static uint GetARMBranch ( uint from , uint to )
@@ -194,7 +229,7 @@ static void Main(string[] args)
194
229
var dir = Path . GetDirectoryName ( args [ 0 ] ) ;
195
230
var fn = Path . GetFileNameWithoutExtension ( args [ 0 ] ) ;
196
231
197
- Console . WriteLine ( "Sun/Moon Patcher v1.2 - SciresM" ) ;
232
+ Console . WriteLine ( "Sun/Moon Patcher v1.3 - SciresM" ) ;
198
233
199
234
var hash = ( new SHA256CryptoServiceProvider ( ) ) . ComputeHash ( code ) ;
200
235
if ( hash . SequenceEqual ( Resources . moon_hash_1_0 ) )
@@ -227,16 +262,64 @@ static void Main(string[] args)
227
262
Console . WriteLine ( "Pokemon Sun v1.2 detected" ) ;
228
263
Offsets = Offsets_1_2 ;
229
264
}
265
+ else if ( hash . SequenceEqual ( Resources . ultra_moon_hash_1_0 ) )
266
+ {
267
+ Console . WriteLine ( "Pokemon Ultra Moon v1.0 detected" ) ;
268
+ Offsets = Ultra_Offsets_1_0 ;
269
+ }
270
+ else if ( hash . SequenceEqual ( Resources . ultra_sun_hash_1_0 ) )
271
+ {
272
+ Console . WriteLine ( "Pokemon Ultra Sun v1.0 detected" ) ;
273
+ Offsets = Ultra_Offsets_1_0 ;
274
+ }
230
275
else
231
276
{
232
277
Console . WriteLine ( "Unknown code.bin! Contact SciresM to update the program." ) ;
233
278
return ;
234
279
}
235
280
236
281
Resources . debug_stub . CopyTo ( code , Offsets . CTRIsDebugMode ) ;
282
+
283
+ if ( Offsets . IsUltra ) // Patch up static memory clobber.
284
+ {
285
+ for ( var i = 0 ; i < Resources . debug_stub . Length ; i += 4 )
286
+ {
287
+ if ( BitConverter . ToUInt32 ( Resources . debug_stub , i ) == 0x006A1080 )
288
+ {
289
+ BitConverter . GetBytes ( 0x00667180 ) . CopyTo ( code , Offsets . CTRIsDebugMode + i ) ;
290
+ }
291
+ }
292
+ }
237
293
Resources . battery_save . CopyTo ( code , Offsets . QRReaderSaveDataBatteryQuery ) ;
294
+ if ( Offsets . IsUltra ) // Patch up Stack reads.
295
+ {
296
+ for ( var i = 0 ; i < Resources . battery_save . Length ; i += 4 )
297
+ {
298
+ if ( BitConverter . ToUInt32 ( Resources . battery_save , i ) == 0xE59D70B0 ) // LDR R7, [SP, #0xB0]
299
+ {
300
+ // LDR R7, [SP, #0xC0]
301
+ BitConverter . GetBytes ( 0xE59D70C0 ) . CopyTo ( code , Offsets . QRReaderSaveDataBatteryQuery + i ) ;
302
+ }
303
+ else if ( BitConverter . ToUInt32 ( Resources . battery_save , i ) == 0xE59D1088 ) // LDR R1, [SP, #0x88]
304
+ {
305
+ // LDR R1, [SP, #0x98]
306
+ BitConverter . GetBytes ( 0xE59D1098 ) . CopyTo ( code , Offsets . QRReaderSaveDataBatteryQuery + i ) ;
307
+ }
308
+ }
309
+ }
238
310
Resources . qr_is_registered . CopyTo ( code , Offsets . QRReaderSaveDataIsRegisteredData ) ;
239
- new byte [ 0x24 ] . CopyTo ( code , Offsets . ForbiddenQRs ) ;
311
+ if ( Offsets . IsUltra ) // Patch up Box offset
312
+ {
313
+ for ( var i = 0 ; i < Resources . qr_is_registered . Length ; i += 4 )
314
+ {
315
+ if ( BitConverter . ToUInt32 ( Resources . qr_is_registered , i ) == 0xE28CCE31 ) // ADD R12, R12, #0x310
316
+ {
317
+ // ADD R12, R12, #0x4A0 (+0x190 to box base in USUM vs SM)
318
+ BitConverter . GetBytes ( 0xE28CCE4A ) . CopyTo ( code , Offsets . QRReaderSaveDataIsRegisteredData + i ) ;
319
+ }
320
+ }
321
+ }
322
+ new byte [ Offsets . IsUltra ? 0x30 : 0x24 ] . CopyTo ( code , Offsets . ForbiddenQRs ) ;
240
323
241
324
// Fix relative jumps within shellcode
242
325
// QR Decryption Jumps
0 commit comments