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];
static u8 nandSlot;
static u32 fatStart;
static u32 fatStart = 0;
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}
};
void ctrNandInit(void)
int ctrNandInit(void)
{
__attribute__((aligned(4))) u8 cid[AES_BLOCK_SIZE],
shaSum[SHA_256_HASH_SIZE];
@ -342,16 +342,31 @@ void ctrNandInit(void)
sha(shaSum, cid, sizeof(cid), SHA_256_MODE);
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;
fatStart = 0x5CAD7;
}
else
{
nandSlot = 0x04;
fatStart = 0x5CAE5;
u32 partitionNum = 1; //TWL partitions need to be first
for(u8 *partitionId = temp + 0x111; *partitionId != 1; partitionId++, partitionNum++);
u32 ctrMbrOffset = *((u32 *)(temp + 0x120) + (2 * partitionNum));
//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)

View File

@ -104,13 +104,14 @@
#define SHA_224_HASH_SIZE (224 / 8)
#define SHA_1_HASH_SIZE (160 / 8)
extern u32 emuOffset;
extern u32 emuOffset,
emuHeader;
extern FirmwareSource firmSource;
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 ctrNandInit(void);
int ctrNandInit(void);
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
bool decryptExeFs(Cxi *cxi);

View File

@ -29,9 +29,10 @@
#include "fatfs/sdmmc/sdmmc.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 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)
{
emuOffset = nandOffset + 1;
*emuHeader = nandOffset + 1;
emuHeader = nandOffset + 1;
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)
{
emuOffset = nandOffset;
*emuHeader = nandOffset + nandSize;
emuHeader = nandOffset + nandSize;
return;
}
}
@ -90,7 +91,7 @@ void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType)
if(*nandType != FIRMWARE_EMUNAND)
{
*nandType = FIRMWARE_EMUNAND;
locateEmuNand(emuHeader, nandType);
locateEmuNand(nandType);
}
else *nandType = FIRMWARE_SYSNAND;
}
@ -161,7 +162,7 @@ static inline u32 patchMpu(u8 *pos, u32 size)
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;

View File

@ -30,5 +30,5 @@
#define ROUND_TO_4MB(a) (((a) + 0x2000 - 1) & (~(0x2000 - 1)))
void locateEmuNand(u32 *emuHeader, FirmwareSource *nandType);
u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u32 emuHeader, u8 *kernel9Address);
void locateEmuNand(FirmwareSource *nandType);
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 */
)
{
DSTATUS ret;
static u32 sdmmcInitResult = 4;
if(sdmmcInitResult == 4) sdmmcInitResult = sdmmc_sdcard_init();
if(pdrv == CTRNAND)
{
if(!(sdmmcInitResult & 1))
{
ctrNandInit();
ret = 0;
}
else ret = STA_NOINIT;
}
else ret = (!(sdmmcInitResult & 2)) ? 0 : STA_NOINIT;
return ret;
return ((pdrv == SDCARD && !(sdmmcInitResult & 2)) ||
(pdrv == CTRNAND && !(sdmmcInitResult & 1) && !ctrNandInit())) ? 0 : STA_NOINIT;
}

View File

@ -197,7 +197,7 @@ u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStora
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,
*arm11Section1 = (u8 *)firm + firm->section[1].offset;
@ -229,7 +229,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
ret += patchSignatureChecks(process9Offset, process9Size);
//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
else ret += patchFirmWrites(process9Offset, process9Size);

View File

@ -28,7 +28,7 @@
static Firm *const firm = (Firm *const)0x20001000;
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 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch);
u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers);

View File

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