Virtually full support for 4.x sysNAND

(see also: previous commit)
This commit is contained in:
TuxSH 2017-06-16 22:37:04 +02:00
parent b71dedccfc
commit c610ec3319
3 changed files with 22 additions and 19 deletions

View File

@ -158,7 +158,7 @@ static void findUsefulSymbols(void)
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++); for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1); KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1);
// On < 6.x the pattern will match but the result will be wrong // From 4.x to 6.x the pattern will match but the result will be wrong
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++); for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1); KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1);

View File

@ -170,8 +170,9 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF
*firmType = NATIVE_FIRM1X2X; *firmType = NATIVE_FIRM1X2X;
} }
//We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD/CTRNAND //We can't boot a 3.x/4.x NATIVE_FIRM EmuNAND, load one from SD/CTRNAND
else if(firmVersion < 0x25) mustLoadFromStorage = true; //We can't boot a 3.x NATIVE_FIRM, load one from SD/CTRNAND too
else if(firmVersion < (nandType == FIRMWARE_SYSNAND ? 0x1D : 0x25)) mustLoadFromStorage = true;
} }
bool loadedFromStorage = false; bool loadedFromStorage = false;
@ -245,12 +246,12 @@ static inline void mergeSection0(FirmwareType firmType, bool loadFromStorage)
{ {
memcpy(moduleList[nbModules].name, ((Cxi *)src)->exHeader.systemControlInfo.appTitle, 8); memcpy(moduleList[nbModules].name, ((Cxi *)src)->exHeader.systemControlInfo.appTitle, 8);
moduleList[nbModules].src = src; moduleList[nbModules].src = src;
srcModuleSize = moduleList[nbModules].size = ((Cxi *)src)->ncch.contentSize * 0x200; srcModuleSize = moduleList[nbModules].size = ((Cxi *)src)->ncch.contentSize * 0x200;
} }
if(firmType == NATIVE_FIRM) if(firmType == NATIVE_FIRM)
{ {
//2) Merge that info with our own modules' //2) Merge that info with our own modules'
for(u8 *src = (u8 *)0x1FF60000; src < (u8 *)(0x1FF60000 + LUMA_SECTION0_SIZE); src += srcModuleSize) for(u8 *src = (u8 *)0x1FF60000; src < (u8 *)(0x1FF60000 + LUMA_SECTION0_SIZE); src += srcModuleSize)
{ {
const char *name = ((Cxi *)src)->exHeader.systemControlInfo.appTitle; const char *name = ((Cxi *)src)->exHeader.systemControlInfo.appTitle;
@ -273,7 +274,7 @@ static inline void mergeSection0(FirmwareType firmType, bool loadFromStorage)
//3) Read or copy the modules //3) Read or copy the modules
u8 *dst = firm->section[0].address; u8 *dst = firm->section[0].address;
const char *extModuleSizeError = "The external FIRM modules are too large."; const char *extModuleSizeError = "The external FIRM modules are too large.";
for(u32 i = 0, dstModuleSize, maxModuleSize = 0x60000; i < nbModules; i++, dst += dstModuleSize, maxModuleSize -= dstModuleSize) for(u32 i = 0, dstModuleSize, maxModuleSize = 0x60000; i < nbModules; i++, dst += dstModuleSize, maxModuleSize -= dstModuleSize)
{ {
if(loadFromStorage) if(loadFromStorage)
{ {
@ -324,7 +325,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
kernel9Loader((Arm9Bin *)arm9Section); kernel9Loader((Arm9Bin *)arm9Section);
firm->arm9Entry = (u8 *)0x801B01C; firm->arm9Entry = (u8 *)0x801B01C;
} }
//Find the Process9 .code location, size and memory address //Find the Process9 .code location, size and memory address
u32 process9Size, u32 process9Size,
process9MemAddr; process9MemAddr;

View File

@ -46,25 +46,24 @@ static Result ProcessPatchesMenu_DoPatchUnpatchSM(u32 textTotalRoundedSize)
{ {
static bool patched = false; static bool patched = false;
static u32 *off; static u32 *off;
static u32 origData[7]; static u32 origData;
if(patched) if(patched)
{ {
memcpy(off, &origData, sizeof(origData)); *off = origData;
patched = false; patched = false;
} }
else else
{ {
for(off = (u32 *)0x00100000; off < (u32 *)(0x00100000 + textTotalRoundedSize) - 6 && for(off = (u32 *)0x00100000; off < (u32 *)(0x00100000 + textTotalRoundedSize) - 3 &&
(off[0] != 0xE1A01006 || off[1] != 0xE1A00005 || off[3] != 0xE3500000 || off[6] != 0xE2850004); (off[0] != 0xE1A01006 || (off[1] & 0xFFFF) != 5);
off++); off++);
if(off >= (u32 *)(0x00100000 + textTotalRoundedSize) - 6) if(off >= (u32 *)(0x00100000 + textTotalRoundedSize) - 3)
return -1; return -1;
memcpy(&origData, off, sizeof(origData)); off += 2;
*off = 0xE3A00001; // mov r0, #1
off[2] = off[3] = off[4] = off[5] = 0xE320F000; // nop
patched = true; patched = true;
} }
@ -76,9 +75,10 @@ static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
{ {
static bool patched = false; static bool patched = false;
static u16 *off; static u16 *off;
static const u16 origData[2] = { static u16 origData[2];
0x4618, // mov r0, r3 static const u16 pattern[2] = {
0x3481, // adds r4, #0x81 0x7401, // strb r1, [r0, #16]
0x2000, // movs r0, #0
}; };
if(patched) if(patched)
@ -88,10 +88,12 @@ static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
} }
else else
{ {
off = (u16 *)memsearch((u8 *)0x00100000, &origData, textTotalRoundedSize, sizeof(origData)); off = (u16 *)memsearch((u8 *)0x00100000, &pattern, textTotalRoundedSize, sizeof(pattern));
if(off == NULL) if(off == NULL)
return -1; return -1;
off += 4;
memcpy(origData, off, 4);
off[0] = 0x2001; // mov r0, #1 off[0] = 0x2001; // mov r0, #1
off[1] = 0x4770; // bx lr off[1] = 0x4770; // bx lr