From d4cf22d370cca64119ce3c29570da15fac749fbb Mon Sep 17 00:00:00 2001 From: Aurora Date: Mon, 10 Oct 2016 15:53:56 +0200 Subject: [PATCH] Display the number of failed patches, make loader svcBreak on failed patch, minor cleanup --- injector/source/patcher.c | 17 ++++++----- source/crypto.c | 2 +- source/exceptions.c | 60 +++++++++++++++++++++------------------ source/fs.c | 2 +- source/main.c | 8 +++++- source/patches.c | 6 ++-- source/strings.c | 4 +-- source/strings.h | 2 +- 8 files changed, 58 insertions(+), 43 deletions(-) diff --git a/injector/source/patcher.c b/injector/source/patcher.c index 6c83d53..51676c8 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -13,7 +13,7 @@ static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, i { u8 *found = memsearch(start, pattern, size, patSize); - if(found == NULL) break; + if(found == NULL) svcBreak(USERBREAK_ASSERT); memcpy(found + offset, replace, repSize); @@ -143,6 +143,8 @@ static void loadTitleCodeSection(u64 progId, u8 *code, u32 size) { u64 total; IFile_Read(&file, &total, code, fileSize); + + if(total != fileSize) svcBreak(USERBREAK_ASSERT); } IFile_Close(&file); @@ -374,8 +376,10 @@ void patchCode(u64 progId, u8 *code, u32 size) u8 *fpdVer = memsearch(code, fpdVerPattern, size, sizeof(fpdVerPattern)); + if(fpdVer == NULL) svcBreak(USERBREAK_ASSERT); + //Allow online access to work with old friends modules - if(fpdVer != NULL && fpdVer[9] < mostRecentFpdVer) fpdVer[9] = mostRecentFpdVer; + if(fpdVer[9] < mostRecentFpdVer) fpdVer[9] = mostRecentFpdVer; break; } @@ -462,12 +466,11 @@ void patchCode(u64 progId, u8 *code, u32 size) u32 *cfgN3dsCpuLoc = (u32 *)memsearch(code, cfgN3dsCpuPattern, size, sizeof(cfgN3dsCpuPattern)); + if(cfgN3dsCpuLoc == NULL) svcBreak(USERBREAK_ASSERT); + //Patch N3DS CPU Clock and L2 cache setting - if(cfgN3dsCpuLoc != NULL) - { - *(cfgN3dsCpuLoc + 1) = 0xE1A00000; - *(cfgN3dsCpuLoc + 8) = 0xE3A00000 | cpuSetting; - } + *(cfgN3dsCpuLoc + 1) = 0xE1A00000; + *(cfgN3dsCpuLoc + 8) = 0xE3A00000 | cpuSetting; } break; diff --git a/source/crypto.c b/source/crypto.c index b5d7072..a3fcea5 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -498,7 +498,7 @@ void kernel9Loader(Arm9Bin *arm9Section) aes_use_keyslot(arm9BinSlot); aes(startOfArm9Bin, startOfArm9Bin, arm9BinSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); - if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Error decrypting the ARM9 binary."); + if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary."); } //Set >=9.6 KeyXs diff --git a/source/exceptions.c b/source/exceptions.c index 7f7a809..21094f9 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -47,38 +47,44 @@ void installArm9Handlers(void) u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset) { + u32 ret; + u32 *endPos = exceptionsPage + 0x400; + u32 *initFPU; - for(initFPU = exceptionsPage; initFPU < exceptionsPage + 0x400 && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++); + for(initFPU = exceptionsPage; *initFPU != 0xE1A0D002 && initFPU < endPos; initFPU++); u32 *freeSpace; - for(freeSpace = initFPU; freeSpace < exceptionsPage + 0x400 && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++); + for(freeSpace = initFPU; *freeSpace != 0xFFFFFFFF && freeSpace < endPos; freeSpace++); u32 *mcuReboot; - for(mcuReboot = exceptionsPage; mcuReboot < exceptionsPage + 0x400 && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++); + for(mcuReboot = exceptionsPage; *mcuReboot != 0xE3A0A0C2 && mcuReboot < endPos; mcuReboot++); - u32 ret = (initFPU == exceptionsPage + 0x400 || freeSpace == exceptionsPage + 0x400 || - mcuReboot == exceptionsPage + 0x400 || *(u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 36) != 0xFFFFFFFF) ? 1 : 0; - - mcuReboot--; - - memcpy(freeSpace, arm11_exceptions_bin + 32, arm11_exceptions_bin_size - 32); - - exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 8) - 32); //Undefined Instruction - exceptionsPage[3] = MAKE_BRANCH(exceptionsPage + 3, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 12) - 32); //Prefetch Abort - exceptionsPage[4] = MAKE_BRANCH(exceptionsPage + 4, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 16) - 32); //Data Abort - exceptionsPage[7] = MAKE_BRANCH(exceptionsPage + 7, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 4) - 32); //FIQ - - for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 32); pos++) + if(initFPU == endPos || freeSpace == endPos || mcuReboot == endPos) ret = 1; + else { - switch(*pos) //Perform relocations + initFPU += 3; + mcuReboot -= 2; + + memcpy(freeSpace, arm11_exceptions_bin + 32, arm11_exceptions_bin_size - 32); + + exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 8) - 32); //Undefined Instruction + exceptionsPage[3] = MAKE_BRANCH(exceptionsPage + 3, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 12) - 32); //Prefetch Abort + exceptionsPage[4] = MAKE_BRANCH(exceptionsPage + 4, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 16) - 32); //Data Abort + exceptionsPage[7] = MAKE_BRANCH(exceptionsPage + 7, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 4) - 32); //FIQ + + for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 32); pos++) { - case 0xFFFF3000: *pos = stackAddress; break; - case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break; - case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break; - case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler) - case 0xBEEFBEEF: *pos = codeSetOffset; break; - default: break; + switch(*pos) //Perform relocations + { + case 0xFFFF3000: *pos = stackAddress; break; + case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break; + case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break; + case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler) + case 0xBEEFBEEF: *pos = codeSetOffset; break; + } } + + ret = 0; } return ret; @@ -145,13 +151,13 @@ void detectAndProcessExceptionDumps(void) for(u32 i = 0; i < 17; i += 2) { posY = drawString(registerNames[i], true, 10, posY + SPACING_Y, COLOR_WHITE); - hexItoa(regs[i], hexString, 8); + hexItoa(regs[i], hexString, 8, true); drawString(hexString, true, 10 + 7 * SPACING_X, posY, COLOR_WHITE); if(i != 16 || dumpHeader->processor != 9) { drawString(registerNames[i + 1], true, 10 + 22 * SPACING_X, posY, COLOR_WHITE); - hexItoa(i == 16 ? regs[20] : regs[i + 1], hexString, 8); + hexItoa(i == 16 ? regs[20] : regs[i + 1], hexString, 8, true); drawString(hexString, true, 10 + 29 * SPACING_X, posY, COLOR_WHITE); } } @@ -166,14 +172,14 @@ void detectAndProcessExceptionDumps(void) for(u32 line = 0; line < 19 && stackDump < additionalData; line++) { - hexItoa(regs[13] + 8 * line, hexString, 8); + hexItoa(regs[13] + 8 * line, hexString, 8, true); posYBottom = drawString(hexString, false, 10, posYBottom + SPACING_Y, COLOR_WHITE); drawCharacter(':', false, 10 + 8 * SPACING_X, posYBottom, COLOR_WHITE); for(u32 i = 0; i < 8 && stackDump < additionalData; i++, stackDump++) { char byteString[] = "00"; - hexItoa(*stackDump, byteString, 2); + hexItoa(*stackDump, byteString, 2, false); drawString(byteString, false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE); } } diff --git a/source/fs.c b/source/fs.c index 1e6df76..be84ebd 100644 --- a/source/fs.c +++ b/source/fs.c @@ -201,7 +201,7 @@ u32 firmRead(void *dest, u32 firmType) concatenateStrings(path, "/00000000.app"); //Convert back the .app name from integer to array - hexItoa(firmVersion, &path[35], 8); + hexItoa(firmVersion, path + 35, 8, false); if(!fileRead(dest, path, 0x400200)) firmVersion = 0xFFFFFFFF; } diff --git a/source/main.c b/source/main.c index 9156ce9..e86b68c 100644 --- a/source/main.c +++ b/source/main.c @@ -27,6 +27,7 @@ #include "utils.h" #include "exceptions.h" #include "draw.h" +#include "strings.h" #include "buttons.h" #include "pin.h" @@ -243,7 +244,12 @@ void main(void) break; } - if(res != 0) error("Error applying FIRM patches."); + if(res != 0) + { + char patchesError[] = "Failed to apply FIRM patch(es)."; + hexItoa(res, patchesError + 16, 2, false); + error(patchesError); + } launchFirm(firmType, loadFromStorage); } \ No newline at end of file diff --git a/source/patches.c b/source/patches.c index 408be22..12966d9 100644 --- a/source/patches.c +++ b/source/patches.c @@ -35,7 +35,7 @@ u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) { u8 *temp = memsearch(pos, "NCCH", size, 4); - if(temp == NULL) error("Error getting Process9 data."); + if(temp == NULL) error("Failed to get Process9 data."); Cxi *off = (Cxi *)(temp - 0x100); @@ -72,7 +72,7 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 * if(*freeK11Space == NULL) ret = false; else (*freeK11Space)++; - if(!ret) error("Error getting Kernel11 data."); + if(!ret) error("Failed to get Kernel11 data."); return arm11SvcTable; } @@ -359,7 +359,7 @@ u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset) if(temp == NULL) ret = false; else stackAddress = *(u32 *)(temp + 9); - if(!ret) error("Error getting ARM11 exception handlers data."); + if(!ret) error("Failed to get ARM11 exception handlers data."); return stackAddress; } diff --git a/source/strings.c b/source/strings.c index 55fee26..bbdb25f 100644 --- a/source/strings.c +++ b/source/strings.c @@ -40,7 +40,7 @@ void concatenateStrings(char *destination, const char *source) memcpy(&destination[j], source, i + 1); } -void hexItoa(u32 number, char *out, u32 digits) +void hexItoa(u32 number, char *out, u32 digits, bool fillString) { const char hexDigits[] = "0123456789ABCDEF"; u32 i = 0; @@ -51,5 +51,5 @@ void hexItoa(u32 number, char *out, u32 digits) number >>= 4; } - while(i < digits) out[digits - 1 - i++] = '0'; + if(fillString) while(i < digits) out[digits - 1 - i++] = '0'; } \ No newline at end of file diff --git a/source/strings.h b/source/strings.h index fc40e19..7bc0859 100644 --- a/source/strings.h +++ b/source/strings.h @@ -26,4 +26,4 @@ u32 strlen(const char *string); void concatenateStrings(char *destination, const char *source); -void hexItoa(u32 number, char *out, u32 digits); \ No newline at end of file +void hexItoa(u32 number, char *out, u32 digits, bool fillString); \ No newline at end of file