From b5f2c64e77aebe59beaf9e6e6d54968d690311af Mon Sep 17 00:00:00 2001 From: d0k3 Date: Mon, 20 Nov 2017 17:01:43 +0100 Subject: [PATCH] NCCH crypto: Workaround for unrecognized seeds in internal SEEDDB --- arm9/source/game/ncch.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/arm9/source/game/ncch.c b/arm9/source/game/ncch.c index ffe73bc..9b28074 100644 --- a/arm9/source/game/ncch.c +++ b/arm9/source/game/ncch.c @@ -67,6 +67,7 @@ u32 GetNcchSeed(u8* seed, NcchHeader* ncch) { } // try to grab the seed from NAND database + const u32 seed_offset[2] = {SEEDSAVE_AREA_OFFSETS}; const char* nand_drv[] = {"1:", "4:"}; // SysNAND and EmuNAND for (u32 i = 0; i < (sizeof(nand_drv)/sizeof(char*)); i++) { // grab the key Y from movable.sed @@ -84,23 +85,32 @@ u32 GetNcchSeed(u8* seed, NcchHeader* ncch) { nand_drv[i], sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); // check seedsave for seed - u8* seedsave = (u8*) (TEMP_BUFFER + (TEMP_BUFFER_SIZE/2)); + u8* seeddb[2]; + seeddb[0] = (u8*) (TEMP_BUFFER + (TEMP_BUFFER_SIZE/2)); + seeddb[1] = seeddb[0] + (SEEDSAVE_MAX_ENTRIES*(8+16)); if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) continue; - f_read(&file, seedsave, 0x200, &btr); - u32 p_active = (getle32(seedsave + 0x168)) ? 1 : 0; - static const u32 seed_offset[2] = {SEEDSAVE_AREA_OFFSETS}; + f_read(&file, seeddb[0], 0x200, &btr); + u32 p_active = (getle32(seeddb[0] + 0x168)) ? 1 : 0; + + // read both partitions for (u32 p = 0; p < 2; p++) { f_lseek(&file, seed_offset[(p + p_active) % 2]); - f_read(&file, seedsave, SEEDSAVE_MAX_ENTRIES*(8+16), &btr); + f_read(&file, seeddb[p], SEEDSAVE_MAX_ENTRIES*(8+16), &btr); + } + + // search for the seed + for (u32 p = 0; p < 2; p++) { for (u32 s = 0; s < SEEDSAVE_MAX_ENTRIES; s++) { - if (titleId != getle64(seedsave + (s*8))) continue; - memcpy(lseed, seedsave + (SEEDSAVE_MAX_ENTRIES*8) + (s*16), 16); - sha_quick(sha256sum, lseed, 16 + 8, SHA256_MODE); - if (hash_seed == sha256sum[0]) { - memcpy(seed, lseed, 16); - f_close(&file); - return 0; // found! + if (titleId != getle64(seeddb[p] + (s*8))) continue; + for (u32 p0 = 0; p0 < 2; p0++) { + memcpy(lseed, seeddb[(p+p0)%2] + (SEEDSAVE_MAX_ENTRIES*8) + (s*16), 16); + sha_quick(sha256sum, lseed, 16 + 8, SHA256_MODE); + if (hash_seed == sha256sum[0]) { + memcpy(seed, lseed, 16); + f_close(&file); + return 0; // found! + } } } }