From c610ec33193cb6ff4d6f5a265eb2a9856a819770 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Fri, 16 Jun 2017 22:37:04 +0200 Subject: [PATCH] Virtually full support for 4.x sysNAND (see also: previous commit) --- k11_extension/source/main.c | 2 +- source/firm.c | 13 +++++----- .../rosalina/source/menus/process_patches.c | 26 ++++++++++--------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/k11_extension/source/main.c b/k11_extension/source/main.c index 843c0f6..cbd5eda 100644 --- a/k11_extension/source/main.c +++ b/k11_extension/source/main.c @@ -158,7 +158,7 @@ static void findUsefulSymbols(void) for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++); 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++); KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1); diff --git a/source/firm.c b/source/firm.c index 312cba7..92558cd 100755 --- a/source/firm.c +++ b/source/firm.c @@ -170,8 +170,9 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF *firmType = NATIVE_FIRM1X2X; } - //We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD/CTRNAND - else if(firmVersion < 0x25) mustLoadFromStorage = true; + //We can't boot a 3.x/4.x NATIVE_FIRM EmuNAND, load one from SD/CTRNAND + //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; @@ -245,12 +246,12 @@ static inline void mergeSection0(FirmwareType firmType, bool loadFromStorage) { memcpy(moduleList[nbModules].name, ((Cxi *)src)->exHeader.systemControlInfo.appTitle, 8); 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) { - //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) { 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 u8 *dst = firm->section[0].address; 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) { @@ -324,7 +325,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora kernel9Loader((Arm9Bin *)arm9Section); firm->arm9Entry = (u8 *)0x801B01C; } - + //Find the Process9 .code location, size and memory address u32 process9Size, process9MemAddr; diff --git a/sysmodules/rosalina/source/menus/process_patches.c b/sysmodules/rosalina/source/menus/process_patches.c index cfec643..c5253cc 100644 --- a/sysmodules/rosalina/source/menus/process_patches.c +++ b/sysmodules/rosalina/source/menus/process_patches.c @@ -46,25 +46,24 @@ static Result ProcessPatchesMenu_DoPatchUnpatchSM(u32 textTotalRoundedSize) { static bool patched = false; static u32 *off; - static u32 origData[7]; + static u32 origData; if(patched) { - memcpy(off, &origData, sizeof(origData)); + *off = origData; patched = false; } else { - for(off = (u32 *)0x00100000; off < (u32 *)(0x00100000 + textTotalRoundedSize) - 6 && - (off[0] != 0xE1A01006 || off[1] != 0xE1A00005 || off[3] != 0xE3500000 || off[6] != 0xE2850004); + for(off = (u32 *)0x00100000; off < (u32 *)(0x00100000 + textTotalRoundedSize) - 3 && + (off[0] != 0xE1A01006 || (off[1] & 0xFFFF) != 5); off++); - if(off >= (u32 *)(0x00100000 + textTotalRoundedSize) - 6) + if(off >= (u32 *)(0x00100000 + textTotalRoundedSize) - 3) return -1; - memcpy(&origData, off, sizeof(origData)); - - off[2] = off[3] = off[4] = off[5] = 0xE320F000; // nop + off += 2; + *off = 0xE3A00001; // mov r0, #1 patched = true; } @@ -76,9 +75,10 @@ static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize) { static bool patched = false; static u16 *off; - static const u16 origData[2] = { - 0x4618, // mov r0, r3 - 0x3481, // adds r4, #0x81 + static u16 origData[2]; + static const u16 pattern[2] = { + 0x7401, // strb r1, [r0, #16] + 0x2000, // movs r0, #0 }; if(patched) @@ -88,10 +88,12 @@ static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize) } else { - off = (u16 *)memsearch((u8 *)0x00100000, &origData, textTotalRoundedSize, sizeof(origData)); + off = (u16 *)memsearch((u8 *)0x00100000, &pattern, textTotalRoundedSize, sizeof(pattern)); if(off == NULL) return -1; + off += 4; + memcpy(origData, off, 4); off[0] = 0x2001; // mov r0, #1 off[1] = 0x4770; // bx lr