Remove hardcoded CTRNAND FAT offsets, calculate them from parsing NCSD + CTR MBR
This commit is contained in:
parent
710d8cd15c
commit
28e5d8107f
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user