Add support (firmprot and firmlaunch patches) for 2.x on sysNAND

This commit is contained in:
TuxSH 2016-08-28 00:32:47 +02:00
parent a5c6b908b6
commit 83a0293af4
5 changed files with 34 additions and 25 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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};

View File

@ -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);