@@ -238,7 +238,10 @@ static bool extract_file_hash(FILE* src, uint64_t part_data_offset, uint64_t fil
238
238
if (write_size > size )
239
239
write_size = size ;
240
240
241
- fread (enc , sizeof (char ), BLOCK_SIZE , src );
241
+ if (fread (enc , sizeof (char ), BLOCK_SIZE , src ) != BLOCK_SIZE ) {
242
+ fprintf (stderr , "ERROR: Could not read %d bytes from '%s'\n" , BLOCK_SIZE , path );
243
+ goto out ;
244
+ }
242
245
243
246
memset (iv , 0 , sizeof (iv ));
244
247
iv [1 ] = (uint8_t )content_id ;
@@ -261,7 +264,7 @@ static bool extract_file_hash(FILE* src, uint64_t part_data_offset, uint64_t fil
261
264
hexdump (hash , SHA_DIGEST_LENGTH );
262
265
hexdump (hashes , 0x100 );
263
266
hexdump (dec , 0x100 );
264
- fprintf (stderr , "ERROR: Failed to verify H0 hash\n" );
267
+ fprintf (stderr , "ERROR: Could not verify H0 hash\n" );
265
268
goto out ;
266
269
}
267
270
@@ -324,7 +327,10 @@ static bool extract_file(FILE* src, uint64_t part_data_offset, uint64_t file_off
324
327
if (write_size > size )
325
328
write_size = size ;
326
329
327
- fread (enc , sizeof (char ), BLOCK_SIZE , src );
330
+ if (fread (enc , sizeof (char ), BLOCK_SIZE , src ) != BLOCK_SIZE ) {
331
+ fprintf (stderr , "ERROR: Could not read %d bytes from '%s'\n" , BLOCK_SIZE , path );
332
+ goto out ;
333
+ }
328
334
329
335
aes_crypt_cbc (& ctx , AES_DECRYPT , BLOCK_SIZE , iv , (const uint8_t * )(enc ), (uint8_t * )dec );
330
336
@@ -356,6 +362,7 @@ int main_utf8(int argc, char** argv)
356
362
FILE * src = NULL ;
357
363
TitleMetaData * tmd = NULL ;
358
364
uint8_t * tik = NULL , * cnt = NULL ;
365
+ const char * pattern [] = { "%s%c%08x.app" , "%s%c%08X.app" , "%s%c%08x" , "%s%c%08X" };
359
366
360
367
if (argc < 2 ) {
361
368
printf ("%s %s - Wii U NUS content file decrypter\n"
@@ -383,8 +390,7 @@ int main_utf8(int argc, char** argv)
383
390
tik_path = strdup (argv [1 ]);
384
391
tik_path [strlen (tik_path ) - 2 ] = 'i' ;
385
392
tik_path [strlen (tik_path ) - 1 ] = 'k' ;
386
- }
387
- else {
393
+ } else {
388
394
tik_path = strdup (argv [2 ]);
389
395
}
390
396
} else if (magic == TIK_MAGIC ) {
@@ -393,8 +399,7 @@ int main_utf8(int argc, char** argv)
393
399
tmd_path = strdup (argv [1 ]);
394
400
tmd_path [strlen (tik_path ) - 2 ] = 'm' ;
395
401
tmd_path [strlen (tik_path ) - 1 ] = 'd' ;
396
- }
397
- else {
402
+ } else {
398
403
tmd_path = strdup (argv [2 ]);
399
404
}
400
405
}
@@ -543,17 +548,18 @@ int main_utf8(int argc, char** argv)
543
548
cnt_offset , getbe16 (& fe [i ].ContentID ), getbe16 (& fe [i ].Flags ), & path [short_path ]);
544
549
545
550
uint32_t cnt_file_id = getbe32 (& tmd -> Contents [getbe16 (& fe [i ].ContentID )].ID );
546
- sprintf (str , "%s%c%08X.app" , argv [1 ], PATH_SEP , cnt_file_id );
547
551
548
552
if (!(fe [i ].Type & 0x80 )) {
553
+ // Handle upper/lowercase for target as well as files without extension
554
+ for (uint32_t k = 0 ; k < array_size (pattern ); k ++ ) {
555
+ sprintf (str , pattern [k ], argv [1 ], PATH_SEP , cnt_file_id );
556
+ if (is_file (str ))
557
+ break ;
558
+ }
549
559
src = fopen_utf8 (str , "rb" );
550
560
if (src == NULL ) {
551
- sprintf (str , "%s%c%08X" , argv [1 ], PATH_SEP , cnt_file_id );
552
- src = fopen_utf8 (str , "rb" );
553
- if (src == NULL ) {
554
- fprintf (stderr , "ERROR: Could not open: '%s'\n" , str );
555
- goto out ;
556
- }
561
+ fprintf (stderr , "ERROR: Could not open: '%s'\n" , str );
562
+ goto out ;
557
563
}
558
564
if ((getbe16 (& fe [i ].Flags ) & 0x440 )) {
559
565
if (!extract_file_hash (src , 0 , cnt_offset , getbe32 (& fe [i ].FileLength ), path , getbe16 (& fe [i ].ContentID )))
0 commit comments