Remove hardcoded CTRNAND FAT offsets, calculate them from parsing NCSD + CTR MBR

This commit is contained in:
Aurora Wright 2017-05-26 03:07:39 +02:00 committed by TuxSH
parent 710d8cd15c
commit 28e5d8107f
8 changed files with 45 additions and 40 deletions

View File

@ -320,7 +320,7 @@ void sha(void *res, const void *src, u32 size, u32 mode)
__attribute__((aligned(4))) static u8 nandCtr[AES_BLOCK_SIZE]; __attribute__((aligned(4))) static u8 nandCtr[AES_BLOCK_SIZE];
static u8 nandSlot; static u8 nandSlot;
static u32 fatStart; static u32 fatStart = 0;
FirmwareSource firmSource; FirmwareSource firmSource;
@ -333,7 +333,7 @@ __attribute__((aligned(4))) static const u8 key1s[2][AES_BLOCK_SIZE] = {
{0xFF, 0x77, 0xA0, 0x9A, 0x99, 0x81, 0xE9, 0x48, 0xEC, 0x51, 0xC9, 0x32, 0x5D, 0x14, 0xEC, 0x25} {0xFF, 0x77, 0xA0, 0x9A, 0x99, 0x81, 0xE9, 0x48, 0xEC, 0x51, 0xC9, 0x32, 0x5D, 0x14, 0xEC, 0x25}
}; };
void ctrNandInit(void) int ctrNandInit(void)
{ {
__attribute__((aligned(4))) u8 cid[AES_BLOCK_SIZE], __attribute__((aligned(4))) u8 cid[AES_BLOCK_SIZE],
shaSum[SHA_256_HASH_SIZE]; shaSum[SHA_256_HASH_SIZE];
@ -342,16 +342,31 @@ void ctrNandInit(void)
sha(shaSum, cid, sizeof(cid), SHA_256_MODE); sha(shaSum, cid, sizeof(cid), SHA_256_MODE);
memcpy(nandCtr, shaSum, sizeof(nandCtr)); memcpy(nandCtr, shaSum, sizeof(nandCtr));
if(ISN3DS) nandSlot = ISN3DS ? 0x05 : 0x04;
u8 __attribute__((aligned(4))) temp[0x200];
int result;
//Read NCSD header
result = firmSource == FIRMWARE_SYSNAND ? sdmmc_nand_readsectors(0, 1, temp) : sdmmc_sdcard_readsectors(emuHeader, 1, temp);
if(!result)
{ {
nandSlot = 0x05; u32 partitionNum = 1; //TWL partitions need to be first
fatStart = 0x5CAD7;
} for(u8 *partitionId = temp + 0x111; *partitionId != 1; partitionId++, partitionNum++);
else
{ u32 ctrMbrOffset = *((u32 *)(temp + 0x120) + (2 * partitionNum));
nandSlot = 0x04;
fatStart = 0x5CAE5; //Read CTR MBR
result = ctrNandRead(ctrMbrOffset, 1, temp);
//Calculate final CTRNAND FAT offset
if(!result) fatStart = ctrMbrOffset + *(u32 *)(temp + 0x1C6);
} }
return result;
} }
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf) int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)

View File

@ -104,13 +104,14 @@
#define SHA_224_HASH_SIZE (224 / 8) #define SHA_224_HASH_SIZE (224 / 8)
#define SHA_1_HASH_SIZE (160 / 8) #define SHA_1_HASH_SIZE (160 / 8)
extern u32 emuOffset; extern u32 emuOffset,
emuHeader;
extern FirmwareSource firmSource; extern FirmwareSource firmSource;
void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode); void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode);
void sha(void *res, const void *src, u32 size, u32 mode); void sha(void *res, const void *src, u32 size, u32 mode);
void ctrNandInit(void); int ctrNandInit(void);
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf); int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
bool decryptExeFs(Cxi *cxi); bool decryptExeFs(Cxi *cxi);

View File

@ -29,9 +29,10 @@
#include "fatfs/sdmmc/sdmmc.h" #include "fatfs/sdmmc/sdmmc.h"
#include "../build/bundled.h" #include "../build/bundled.h"
u32 emuOffset; u32 emuOffset,
emuHeader;
void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType) void locateEmuNand(FirmwareSource *nandType)
{ {
static u8 __attribute__((aligned(4))) temp[0x200]; static u8 __attribute__((aligned(4))) temp[0x200];
static u32 nandSize = 0, static u32 nandSize = 0,
@ -70,7 +71,7 @@ void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType)
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0) if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0)
{ {
emuOffset = nandOffset + 1; emuOffset = nandOffset + 1;
*emuHeader = nandOffset + 1; emuHeader = nandOffset + 1;
return; return;
} }
@ -78,7 +79,7 @@ void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType)
else if(i != 2 && !sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0) else if(i != 2 && !sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0)
{ {
emuOffset = nandOffset; emuOffset = nandOffset;
*emuHeader = nandOffset + nandSize; emuHeader = nandOffset + nandSize;
return; return;
} }
} }
@ -90,7 +91,7 @@ void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType)
if(*nandType != FIRMWARE_EMUNAND) if(*nandType != FIRMWARE_EMUNAND)
{ {
*nandType = FIRMWARE_EMUNAND; *nandType = FIRMWARE_EMUNAND;
locateEmuNand(emuHeader, nandType); locateEmuNand(nandType);
} }
else *nandType = FIRMWARE_SYSNAND; else *nandType = FIRMWARE_SYSNAND;
} }
@ -161,7 +162,7 @@ static inline u32 patchMpu(u8 *pos, u32 size)
return 0; return 0;
} }
u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u32 emuHeader, u8 *kernel9Address) u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u8 *kernel9Address)
{ {
u8 *freeK9Space; u8 *freeK9Space;

View File

@ -30,5 +30,5 @@
#define ROUND_TO_4MB(a) (((a) + 0x2000 - 1) & (~(0x2000 - 1))) #define ROUND_TO_4MB(a) (((a) + 0x2000 - 1) & (~(0x2000 - 1)))
void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType); void locateEmuNand(FirmwareSource *nandType);
u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u32 emuHeader, u8 *kernel9Address); u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u8 *kernel9Address);

View File

@ -37,23 +37,12 @@ DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */ BYTE pdrv /* Physical drive nmuber to identify the drive */
) )
{ {
DSTATUS ret;
static u32 sdmmcInitResult = 4; static u32 sdmmcInitResult = 4;
if(sdmmcInitResult == 4) sdmmcInitResult = sdmmc_sdcard_init(); if(sdmmcInitResult == 4) sdmmcInitResult = sdmmc_sdcard_init();
if(pdrv == CTRNAND) return ((pdrv == SDCARD && !(sdmmcInitResult & 2)) ||
{ (pdrv == CTRNAND && !(sdmmcInitResult & 1) && !ctrNandInit())) ? 0 : STA_NOINIT;
if(!(sdmmcInitResult & 1))
{
ctrNandInit();
ret = 0;
}
else ret = STA_NOINIT;
}
else ret = (!(sdmmcInitResult & 2)) ? 0 : STA_NOINIT;
return ret;
} }

View File

@ -197,7 +197,7 @@ u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStora
return firmVersion; return firmVersion;
} }
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool loadFromStorage, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers) u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers)
{ {
u8 *arm9Section = (u8 *)firm + firm->section[2].offset, u8 *arm9Section = (u8 *)firm + firm->section[2].offset,
*arm11Section1 = (u8 *)firm + firm->section[1].offset; *arm11Section1 = (u8 *)firm + firm->section[1].offset;
@ -229,7 +229,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
ret += patchSignatureChecks(process9Offset, process9Size); ret += patchSignatureChecks(process9Offset, process9Size);
//Apply EmuNAND patches //Apply EmuNAND patches
if(nandType != FIRMWARE_SYSNAND) ret += patchEmuNand(arm9Section, kernel9Size, process9Offset, process9Size, emuHeader, firm->section[2].address); if(nandType != FIRMWARE_SYSNAND) ret += patchEmuNand(arm9Section, kernel9Size, process9Offset, process9Size, firm->section[2].address);
//Apply FIRM0/1 writes patches on SysNAND to protect A9LH //Apply FIRM0/1 writes patches on SysNAND to protect A9LH
else ret += patchFirmWrites(process9Offset, process9Size); else ret += patchFirmWrites(process9Offset, process9Size);

View File

@ -28,7 +28,7 @@
static Firm *const firm = (Firm *const)0x20001000; static Firm *const firm = (Firm *const)0x20001000;
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode); u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode);
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool loadFromStorage, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers); u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers);
u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch); u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch);
u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch); u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch);
u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers); u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers);

View File

@ -46,7 +46,6 @@ void main(int argc, char **argv, u32 magicWord)
{ {
bool isSafeMode = false, bool isSafeMode = false,
isNoForceFlagSet = false; isNoForceFlagSet = false;
u32 emuHeader;
FirmwareType firmType; FirmwareType firmType;
FirmwareSource nandType; FirmwareSource nandType;
@ -266,13 +265,13 @@ boot:
//If we need to boot EmuNAND, make sure it exists //If we need to boot EmuNAND, make sure it exists
if(nandType != FIRMWARE_SYSNAND) if(nandType != FIRMWARE_SYSNAND)
{ {
locateEmuNand(&emuHeader, &nandType); locateEmuNand(&nandType);
if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND; if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND;
} }
//Same if we're using EmuNAND as the FIRM source //Same if we're using EmuNAND as the FIRM source
else if(firmSource != FIRMWARE_SYSNAND) else if(firmSource != FIRMWARE_SYSNAND)
locateEmuNand(&emuHeader, &firmSource); locateEmuNand(&firmSource);
if(!isFirmlaunch) if(!isFirmlaunch)
{ {
@ -291,7 +290,7 @@ boot:
switch(firmType) switch(firmType)
{ {
case NATIVE_FIRM: case NATIVE_FIRM:
res = patchNativeFirm(firmVersion, nandType, emuHeader, loadFromStorage, isSafeMode, doUnitinfoPatch, enableExceptionHandlers); res = patchNativeFirm(firmVersion, nandType, loadFromStorage, isSafeMode, doUnitinfoPatch, enableExceptionHandlers);
break; break;
case TWL_FIRM: case TWL_FIRM:
res = patchTwlFirm(firmVersion, loadFromStorage, doUnitinfoPatch); res = patchTwlFirm(firmVersion, loadFromStorage, doUnitinfoPatch);