Add support (firmprot and firmlaunch patches) for 2.x on sysNAND
This commit is contained in:
parent
a5c6b908b6
commit
83a0293af4
@ -7,12 +7,14 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB
|
||||
.arm
|
||||
; Interesting registers and locations to keep in mind, set just before this code is ran:
|
||||
; - r1: FIRM path in exefs.
|
||||
; - r7: pointer to file object
|
||||
; - r7: pointer to file object (r10 on < 4.x; r7 is equal to 0 in that case)
|
||||
; - *r7: vtable
|
||||
; - *(vtable + 0x28): fread function
|
||||
; - *(r7 + 8): file handle
|
||||
; - *(r7 + 8) = r0: file handle
|
||||
|
||||
mov r8, r1
|
||||
cmp r7, #0
|
||||
moveq r7, r10
|
||||
|
||||
pxi_wait_recv:
|
||||
ldr r2, =0x44846
|
||||
|
@ -40,14 +40,14 @@ extern u16 launchedFirmTIDLow[8]; //Defined in start.s
|
||||
static firmHeader *const firm = (firmHeader *)0x24000000;
|
||||
static const firmSectionHeader *section;
|
||||
|
||||
u32 emuOffset;
|
||||
u32 emuOffset, firmVersion;
|
||||
|
||||
bool isN3DS,
|
||||
isDevUnit,
|
||||
isFirmlaunch;
|
||||
|
||||
cfgData configData;
|
||||
FirmwareSource firmSource;
|
||||
FirmwareSource firmSource, nandType;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
@ -213,12 +213,12 @@ void main(void)
|
||||
writeConfig(configPath, configTemp);
|
||||
}
|
||||
|
||||
u32 firmVersion = loadFirm(firmType);
|
||||
loadFirm(firmType);
|
||||
|
||||
switch(firmType)
|
||||
{
|
||||
case NATIVE_FIRM:
|
||||
patchNativeFirm(firmVersion, nandType, emuHeader, isA9lh);
|
||||
patchNativeFirm(emuHeader, isA9lh);
|
||||
break;
|
||||
case SAFE_FIRM:
|
||||
patchSafeFirm();
|
||||
@ -232,37 +232,38 @@ void main(void)
|
||||
launchFirm(firmType);
|
||||
}
|
||||
|
||||
static inline u32 loadFirm(FirmwareType firmType)
|
||||
static inline void loadFirm(FirmwareType firmType)
|
||||
{
|
||||
section = firm->section;
|
||||
|
||||
//Load FIRM from CTRNAND, unless it's an O3DS and we're loading a pre-5.0 NATIVE FIRM
|
||||
u32 firmVersion = firmRead(firm, (u32)firmType);
|
||||
firmVersion = firmRead(firm, (u32)firmType);
|
||||
|
||||
if(!isN3DS && firmType == NATIVE_FIRM && firmVersion < 0x25)
|
||||
{
|
||||
//We can't boot < 3.x NANDs
|
||||
if(firmVersion < 0x18)
|
||||
//We can't boot < 2.x NANDs. No emuNAND either.
|
||||
if(firmVersion < ((firmSource == FIRMWARE_SYSNAND) ? 9 : 0x18))
|
||||
error("An old unsupported NAND has been detected.\nLuma3DS is unable to boot it.");
|
||||
|
||||
//We can't boot a 4.x NATIVE_FIRM, load one from SD
|
||||
if(!fileRead(firm, "/luma/firmware.bin") || (((u32)section[2].address >> 8) & 0xFF) != 0x68)
|
||||
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot");
|
||||
else if(!fileRead(firm, "/luma/firmware.bin") || (((u32)section[2].address >> 8) & 0xFF) != 0x68)
|
||||
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot.");
|
||||
|
||||
//No assumption regarding FIRM version
|
||||
firmVersion = 0xffffffff;
|
||||
}
|
||||
else decryptExeFs((u8 *)firm);
|
||||
else if(!isN3DS && firmType == SAFE_FIRM && firmVersion < 1)
|
||||
error("An old unsupported SAFE_FIRM has been detected.");
|
||||
|
||||
return firmVersion;
|
||||
else decryptExeFs((u8 *)firm);
|
||||
}
|
||||
|
||||
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh)
|
||||
static inline void patchNativeFirm(u32 emuHeader, bool isA9lh)
|
||||
{
|
||||
u8 *arm9Section = (u8 *)firm + section[2].offset;
|
||||
u8 *arm11Section1 = (u8 *)firm + section[1].offset;
|
||||
|
||||
if(isN3DS)
|
||||
if(firmVersion >= 0x37 && isN3DS)
|
||||
{
|
||||
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip arm9loader
|
||||
arm9Loader(arm9Section);
|
||||
@ -277,6 +278,15 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
|
||||
process9MemAddr;
|
||||
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
|
||||
|
||||
//Apply firmlaunch patches
|
||||
patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
|
||||
|
||||
if(firmVersion < 0x18) // < 3.x
|
||||
{
|
||||
if(isA9lh) patchOldFirmWrites(process9Offset, process9Size);
|
||||
return;
|
||||
}
|
||||
|
||||
//Apply signature patches
|
||||
patchSignatureChecks(process9Offset, process9Size);
|
||||
|
||||
@ -290,9 +300,6 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
|
||||
//Apply FIRM0/1 writes patches on sysNAND to protect A9LH
|
||||
else if(isA9lh) patchFirmWrites(process9Offset, process9Size);
|
||||
|
||||
//Apply firmlaunch patches
|
||||
patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
|
||||
|
||||
//11.0 FIRM patches
|
||||
if(firmVersion >= (isN3DS ? 0x21 : 0x52))
|
||||
{
|
||||
@ -333,7 +340,7 @@ static inline void patchSafeFirm(void)
|
||||
|
||||
patchFirmWrites(arm9Section, section[2].size);
|
||||
}
|
||||
else patchFirmWriteSafe(arm9Section, section[2].size);
|
||||
else patchOldFirmWrites(arm9Section, section[2].size);
|
||||
}
|
||||
|
||||
static inline void copySection0AndInjectSystemModules(void)
|
||||
@ -371,7 +378,7 @@ static inline void launchFirm(FirmwareType firmType)
|
||||
{
|
||||
//If we're booting NATIVE_FIRM, section0 needs to be copied separately to inject 3ds_injector
|
||||
u32 sectionNum;
|
||||
if(firmType == NATIVE_FIRM)
|
||||
if(firmType == NATIVE_FIRM && firmVersion >= 0x18)
|
||||
{
|
||||
copySection0AndInjectSystemModules();
|
||||
sectionNum = 1;
|
||||
|
@ -54,8 +54,8 @@ typedef enum ConfigurationStatus
|
||||
CREATE_CONFIGURATION = 2
|
||||
} ConfigurationStatus;
|
||||
|
||||
static inline u32 loadFirm(FirmwareType firmType);
|
||||
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh);
|
||||
static inline void loadFirm(FirmwareType firmType);
|
||||
static inline void patchNativeFirm(u32 emuHeader, bool isA9lh);
|
||||
static inline void patchLegacyFirm(FirmwareType firmType);
|
||||
static inline void patchSafeFirm(void);
|
||||
static inline void copySection0AndInjectSystemModules(void);
|
||||
|
@ -113,7 +113,7 @@ void patchFirmWrites(u8 *pos, u32 size)
|
||||
off2[1] = writeBlock[1];
|
||||
}
|
||||
|
||||
void patchFirmWriteSafe(u8 *pos, u32 size)
|
||||
void patchOldFirmWrites(u8 *pos, u32 size)
|
||||
{
|
||||
const u16 writeBlockSafe[2] = {0x2400, 0xE01D};
|
||||
|
||||
|
@ -54,7 +54,7 @@ void patchSignatureChecks(u8 *pos, u32 size);
|
||||
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
|
||||
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
||||
void patchFirmWrites(u8 *pos, u32 size);
|
||||
void patchFirmWriteSafe(u8 *pos, u32 size);
|
||||
void patchOldFirmWrites(u8 *pos, u32 size);
|
||||
void reimplementSvcBackdoor(u8 *pos, u32 size);
|
||||
void implementSvcGetCFWInfo(u8 *pos, u32 size);
|
||||
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
|
||||
|
Reference in New Issue
Block a user