diff --git a/exceptions/arm11/source/mainHandler.c b/exceptions/arm11/source/mainHandler.c index bf86049..69b3850 100644 --- a/exceptions/arm11/source/mainHandler.c +++ b/exceptions/arm11/source/mainHandler.c @@ -24,7 +24,7 @@ #define FINAL_BUFFER 0xE5000000 //0x25000000 -#define REG_DUMP_SIZE (4*23) +#define REG_DUMP_SIZE 4 * 23 #define CODE_DUMP_SIZE 48 #define CODESET_OFFSET 0xBEEFBEEF @@ -69,13 +69,13 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type //Dump registers //Current order of saved regs: dfsr, ifsr, far, fpexc, fpinst, fpinst2, cpsr, pc, r8-r12, sp, lr, r0-r7 u32 cpsr = regs[6]; - u32 pc = regs[7] - ((type < 3) ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8); + u32 pc = regs[7] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8); registerDump[15] = pc; registerDump[16] = cpsr; for(u32 i = 0; i < 6; i++) registerDump[17 + i] = regs[i]; for(u32 i = 0; i < 7; i++) registerDump[8 + i] = regs[8 + i]; - for(u32 i = 0; i < 8; i++) registerDump[i] = regs[15 + i]; + for(u32 i = 0; i < 8; i++) registerDump[i] = regs[15 + i]; //Dump code u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //Doesn't work well on 32-bit Thumb instructions, but it isn't much of a problem @@ -90,8 +90,8 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1); final += dumpHeader.stackDumpSize; - vu8 *currentKProcess = (cannotAccessVA((u8 *)0xFFFF9004)) ? NULL : *(vu8 **)0xFFFF9004; - vu8 *currentKCodeSet = (currentKProcess != NULL) ? *(vu8 **)(currentKProcess + CODESET_OFFSET) : NULL; + vu8 *currentKProcess = cannotAccessVA((u8 *)0xFFFF9004) ? NULL : *(vu8 **)0xFFFF9004; + vu8 *currentKCodeSet = currentKProcess != NULL ? *(vu8 **)(currentKProcess + CODESET_OFFSET) : NULL; if(currentKCodeSet != NULL) { @@ -101,8 +101,7 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type additionalData[0] = *(vu64 *)(currentKCodeSet + 0x50); //Process name additionalData[1] = *(vu64 *)(currentKCodeSet + 0x5C); //Title ID } - else - dumpHeader.additionalDataSize = 0; + else dumpHeader.additionalDataSize = 0; //Copy header (actually optimized by the compiler) final = (u8 *)FINAL_BUFFER; @@ -111,4 +110,4 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type cleanInvalidateDCacheAndDMB(); mcuReboot(); //Also contains DCache-cleaning code -} +} \ No newline at end of file diff --git a/exceptions/arm11/source/types.h b/exceptions/arm11/source/types.h index 256923d..2b89edb 100644 --- a/exceptions/arm11/source/types.h +++ b/exceptions/arm11/source/types.h @@ -23,12 +23,9 @@ #pragma once #include +#include #include -#ifndef NULL - #define NULL 0 -#endif - //Common data types typedef uint8_t u8; typedef uint16_t u16; diff --git a/exceptions/arm9/source/mainHandler.c b/exceptions/arm9/source/mainHandler.c index 98ff45e..8316ca6 100644 --- a/exceptions/arm9/source/mainHandler.c +++ b/exceptions/arm9/source/mainHandler.c @@ -25,7 +25,7 @@ #define FINAL_BUFFER 0x25000000 -#define REG_DUMP_SIZE (4*17) +#define REG_DUMP_SIZE 4 * 17 #define CODE_DUMP_SIZE 48 bool cannotAccessAddress(const void *address) @@ -37,7 +37,7 @@ bool cannotAccessAddress(const void *address) for(u32 i = 0; i < 8; i++) { if((dataAccessPermissions & 0xF) == 0 || (regionSettings[i] & 1) == 0) - continue; //no access / region not enabled + continue; //No access / region not enabled u32 regionAddrBase = regionSettings[i] & ~0xFFF; u32 regionSize = 1 << (((regionSettings[i] >> 1) & 0x1F) + 1); @@ -88,7 +88,7 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type //Dump registers //Current order of saved regs: cpsr, pc, r8-r14, r0-r7 u32 cpsr = regs[0]; - u32 pc = regs[1] - ((type < 3) ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8); + u32 pc = regs[1] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8); registerDump[15] = pc; registerDump[16] = cpsr; diff --git a/exceptions/arm9/source/types.h b/exceptions/arm9/source/types.h index 256923d..2b89edb 100644 --- a/exceptions/arm9/source/types.h +++ b/exceptions/arm9/source/types.h @@ -23,12 +23,9 @@ #pragma once #include +#include #include -#ifndef NULL - #define NULL 0 -#endif - //Common data types typedef uint8_t u8; typedef uint16_t u16; diff --git a/source/exceptions.c b/source/exceptions.c index 95fca9e..b850139 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -30,27 +30,11 @@ #include "../build/arm9_exceptions.h" #include "../build/arm11_exceptions.h" -typedef struct __attribute__((packed)) -{ - u32 magic[2]; - u16 versionMinor, versionMajor; - - u16 processor, core; - u32 type; - - u32 totalSize; - u32 registerDumpSize; - u32 codeDumpSize; - u32 stackDumpSize; - u32 additionalDataSize; -} ExceptionDumpHeader; - void installArm9Handlers(void) { - void *payloadAddress = (void *)0x01FF8000; const u32 offsets[] = {0x08, 0x18, 0x20, 0x28}; - memcpy(payloadAddress, arm9_exceptions + 32, arm9_exceptions_size - 32); + memcpy((void *)0x01FF8000, arm9_exceptions + 32, arm9_exceptions_size - 32); //IRQHandler is at 0x08000000, but we won't handle it for some reasons //svcHandler is at 0x08000010, but we won't handle svc either @@ -62,20 +46,18 @@ void installArm9Handlers(void) } } -#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) -#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) - void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset) { u32 *initFPU; - for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU += 1); + for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++); u32 *mcuReboot; - for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot += 1); + for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++); mcuReboot--; u32 *freeSpace; - for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace += 1); + for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++); + memcpy(freeSpace, arm11_exceptions + 32, arm11_exceptions_size - 32); exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 8) - 32); //Undefined Instruction @@ -90,8 +72,8 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset) case 0xFFFF3000: *pos = stackAddr; 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; + case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler) + case 0xBEEFBEEF: *pos = codeSetOffset; break; default: break; } } @@ -113,64 +95,61 @@ static void hexItoa(u32 n, char *out) void detectAndProcessExceptionDumps(void) { - const char *handledExceptionNames[] = { - "FIQ", "undefined instruction", "prefetch abort", "data abort" - }; - - const char *registerNames[] = { - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", - "SP", "LR", "PC", "CPSR", "FPEXC" - }; - - char hexstring[] = "00000000"; - volatile ExceptionDumpHeader *dumpHeader = (volatile ExceptionDumpHeader *)0x25000000; - vu32 *dump = (vu32 *)dumpHeader; - vu32 *regs = (vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader)); - vu8 *additionalData = (vu8 *)dumpHeader + dumpHeader->totalSize - dumpHeader->additionalDataSize; if(dumpHeader->magic[0] == 0xDEADC0DE && dumpHeader->magic[1] == 0xDEADCAFE && (dumpHeader->processor == 9 || dumpHeader->processor == 11)) { - char path9[41] = "/luma/dumps/arm9"; - char path11[42] = "/luma/dumps/arm11"; + char path[42]; char fileName[] = "crash_dump_00000000.dmp"; u32 size = dumpHeader->totalSize; + char *pathFolder; + u32 fileNameSpot; if(dumpHeader->processor == 9) { - findDumpFile(path9, fileName); - path9[16] = '/'; - memcpy(&path9[17], fileName, sizeof(fileName)); - if(!fileWrite((void *)dump, path9, size)) - { - createDirectory("/luma"); - createDirectory("/luma/dumps"); - createDirectory("/luma/dumps/arm9"); - fileWrite((void *)dump, path9, size); - } - } - + pathFolder = "/luma/dumps/arm9"; + fileNameSpot = 16; + } else { - findDumpFile(path11, fileName); - path11[17] = '/'; - memcpy(&path11[18], fileName, sizeof(fileName)); - if(!fileWrite((void *)dump, path11, size)) - { - createDirectory("/luma"); - createDirectory("/luma/dumps"); - createDirectory("/luma/dumps/arm11"); - fileWrite((void *)dump, path11, size); - } + pathFolder = "/luma/dumps/arm11"; + fileNameSpot = 17; } + findDumpFile(pathFolder, fileName); + memcpy(path, pathFolder, 17); + path[fileNameSpot] = '/'; + memcpy(&path[fileNameSpot + 1], fileName, sizeof(fileName)); + + if(!fileWrite((void *)dumpHeader, path, size)) + { + createDirectory("/luma"); + createDirectory("/luma/dumps"); + createDirectory(pathFolder); + fileWrite((void *)dumpHeader, path, size); + } + + vu32 *regs = (vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader)); + vu8 *additionalData = (vu8 *)dumpHeader + dumpHeader->totalSize - dumpHeader->additionalDataSize; + + const char *handledExceptionNames[] = { + "FIQ", "undefined instruction", "prefetch abort", "data abort" + }; + + const char *registerNames[] = { + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", + "SP", "LR", "PC", "CPSR", "FPEXC" + }; + + char hexstring[] = "00000000"; + char arm11Str[] = "Processor: ARM11 (core X)"; if(dumpHeader->processor == 11) arm11Str[29] = '0' + (char)(dumpHeader->core); - + initScreens(); drawString("An exception occurred", 10, 10, COLOR_RED); - int posY = drawString((dumpHeader->processor == 11) ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y; + int posY = drawString(dumpHeader->processor == 11 ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y; posY = drawString("Exception type: ", 10, posY, COLOR_WHITE); posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE); @@ -202,6 +181,7 @@ void detectAndProcessExceptionDumps(void) } posY += 3 * SPACING_Y; + for(u32 i = 0; i < 17; i += 2) { posY = drawString(registerNames[i], 10, posY, COLOR_WHITE); @@ -211,7 +191,7 @@ void detectAndProcessExceptionDumps(void) if(dumpHeader->processor != 9 || i != 16) { posY = drawString(registerNames[i + 1], 10 + 22 * SPACING_X, posY, COLOR_WHITE); - hexItoa((i == 16) ? regs[20] : regs[i + 1], hexstring); + hexItoa(i == 16 ? regs[20] : regs[i + 1], hexstring); posY = drawString(hexstring, 10 + 29 * SPACING_X, posY, COLOR_WHITE); } @@ -223,19 +203,18 @@ void detectAndProcessExceptionDumps(void) u32 mode = regs[16] & 0xF; if(dumpHeader->type == 3 && (mode == 7 || mode == 11)) { - posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //in yellow + posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //In yellow if(dumpHeader->processor != 9) posY -= SPACING_Y; } posY = drawString("You can find a dump in the following file:", 10, posY, COLOR_WHITE) + SPACING_Y; - posY = drawString((dumpHeader->processor == 9) ? path9 : path11, 10, posY, COLOR_WHITE) + 2 * SPACING_Y; + posY = drawString(path, 10, posY, COLOR_WHITE) + 2 * SPACING_Y; drawString("Press any button to shutdown", 10, posY, COLOR_WHITE); waitInput(); - - for(u32 i = 0; i < size / 4; i++) dump[i] = 0; - - clearScreens(); + + memset32((void *)dumpHeader, 0, size); + mcuPowerOff(); } } \ No newline at end of file diff --git a/source/exceptions.h b/source/exceptions.h index 5574cb1..0d6d8ba 100644 --- a/source/exceptions.h +++ b/source/exceptions.h @@ -24,6 +24,24 @@ #include "types.h" +#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) +#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) + +typedef struct __attribute__((packed)) +{ + u32 magic[2]; + u16 versionMinor, versionMajor; + + u16 processor, core; + u32 type; + + u32 totalSize; + u32 registerDumpSize; + u32 codeDumpSize; + u32 stackDumpSize; + u32 additionalDataSize; +} ExceptionDumpHeader; + void installArm9Handlers(void); void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset); void detectAndProcessExceptionDumps(void); \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 1d28b39..6084b97 100755 --- a/source/firm.c +++ b/source/firm.c @@ -43,7 +43,9 @@ static const firmSectionHeader *section; u32 emuOffset; -bool isN3DS, isDevUnit, isFirmlaunch; +bool isN3DS, + isDevUnit, + isFirmlaunch; cfgData configData; FirmwareSource firmSource; @@ -239,6 +241,7 @@ void main(void) static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource) { section = firm->section; + const char *firmwareFiles[4] = { "/luma/firmware.bin", "/luma/firmware_twl.bin", @@ -248,13 +251,10 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource) u32 firmVersion; - if(fileRead(firm, firmwareFiles[(u32)firmType])) - { - firmVersion = 0xFFFFFFFF; - } + if(fileRead(firm, firmwareFiles[(u32)*firmType])) firmVersion = 0xFFFFFFFF; else { - firmVersion = firmRead(firm, (u32)firmType); + firmVersion = firmRead(firm, (u32)*firmType); if(!isN3DS && *firmType == NATIVE_FIRM) { @@ -279,9 +279,9 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource) firmVersion = 0xFFFFFFFF; } } - } - if(firmVersion != 0xFFFFFFFF) decryptExeFs((u8 *)firm); + decryptExeFs((u8 *)firm); + } return firmVersion; } @@ -340,22 +340,23 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 } implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space); - + //Apply UNITINFO patch if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size); if(DEV_OPTIONS != 2) { //Install arm11 exception handlers - u32 stackAddress, codeSetOffset; + u32 stackAddress, + codeSetOffset; getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &stackAddress, &codeSetOffset); installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset); - + //Kernel9/Process9 debugging patchArm9ExceptionHandlersInstall(arm9Section, section[2].size); - patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address)); + patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address); patchKernel9Panic(arm9Section, section[2].size, NATIVE_FIRM); - + //Stub svcBreak11 with "bkpt 65535" patchSvcBreak11(arm11Section1, arm11SvcTable); @@ -389,7 +390,7 @@ static inline void patchLegacyFirm(FirmwareType firmType) { //Kernel9/Process9 debugging patchArm9ExceptionHandlersInstall(arm9Section, section[3].size); - patchSvcBreak9(arm9Section, section[3].size, (u32)(section[3].address)); + patchSvcBreak9(arm9Section, section[3].size, (u32)section[3].address); patchKernel9Panic(arm9Section, section[3].size, firmType); } @@ -416,71 +417,49 @@ static inline void patch2xNativeAndSafeFirm(void) { //Kernel9/Process9 debugging patchArm9ExceptionHandlersInstall(arm9Section, section[2].size); - patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address)); + patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address); } } static inline void copySection0AndInjectSystemModules(FirmwareType firmType) { - u8 *arm11Section0 = (u8 *)firm + section[0].offset; - char fileName[] = "/luma/sysmodules/--------.cxi"; - const char *ext = ".cxi"; + u32 srcModuleSize, + dstModuleSize; - struct + for(u8 *src = (u8 *)firm + section[0].offset, *srcEnd = src + section[0].size, *dst = section[0].address; + src < srcEnd; src += srcModuleSize, dst += dstModuleSize) { - u32 size; - char name[8]; - const u8 *addr; - } modules[5]; + srcModuleSize = *(u32 *)(src + 0x104) * 0x200; + char *moduleName = (char *)(src + 0x200); - u8 *pos = arm11Section0; - u32 n = 0; + char fileName[30] = "/luma/sysmodules/"; + const char *ext = ".cxi"; - u32 loaderIndex = 0; - - for(u8 *end = pos + section[0].size; pos < end; pos += modules[n++].size) - { - modules[n].addr = pos; - modules[n].size = *(u32 *)(pos + 0x104) * 0x200; - - memcpy(modules[n].name, pos + 0x200, 8); - //Read modules from files if they exist u32 nameOff; - for(nameOff = 0; nameOff < 8 && modules[n].name[nameOff] != 0; nameOff++); - memcpy(fileName + 17, modules[n].name, nameOff); + for(nameOff = 0; nameOff < 8 && moduleName[nameOff] != 0; nameOff++); + memcpy(fileName + 17, moduleName, nameOff); memcpy(fileName + 17 + nameOff, ext, 5); - - u32 fileSize = getFileSize(fileName); - if(fileSize != 0) - { - modules[n].addr = NULL; - modules[n].size = fileSize; - } - if(firmType == NATIVE_FIRM && memcmp(modules[n].name, "loader", 7) == 0) loaderIndex = n; - } - - if(firmType == NATIVE_FIRM && modules[loaderIndex].addr != NULL) - { - modules[loaderIndex].size = injector_size; - modules[loaderIndex].addr = injector; - } - - pos = section[0].address; - for(u32 i = 0; i < n; pos += modules[i++].size) - { - if(modules[i].addr != NULL) - memcpy(pos, modules[i].addr, modules[i].size); + u32 fileSize = fileRead(dst, fileName); + if(fileSize) dstModuleSize = fileSize; else { - //Read modules from files if they exist - u32 nameOff; - for(nameOff = 0; nameOff < 8 && modules[i].name[nameOff] != 0; nameOff++); - memcpy(fileName + 17, modules[i].name, nameOff); - memcpy(fileName + 17 + nameOff, ext, 5); - fileRead(pos, fileName); - } + void *module; + + if(firmType == NATIVE_FIRM && memcmp(moduleName, "loader", 6) == 0) + { + module = (void *)injector; + dstModuleSize = injector_size; + } + else + { + module = src; + dstModuleSize = srcModuleSize; + } + + memcpy(dst, module, dstModuleSize); + } } } @@ -516,4 +495,4 @@ static inline void launchFirm(FirmwareType firmType) //Final jump to ARM9 kernel ((void (*)())firm->arm9Entry)(); -} +} \ No newline at end of file diff --git a/source/patches.c b/source/patches.c index bb3a11d..b9129a0 100644 --- a/source/patches.c +++ b/source/patches.c @@ -260,14 +260,12 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) 0x20, 0x10, 0x80, 0xE5, 0x28, 0x10, 0x80, 0xE5, }; //i.e when it stores ldr pc, [pc, #-4] - + u32* off = (u32 *)(memsearch(pos, pattern, size, sizeof(pattern))); if(off == NULL) return; off += sizeof(pattern)/4; - u32 r0 = 0x08000000; - - for(; *off != 0xE3A01040; off++) //Until mov r1, #0x40 + for(u32 r0 = 0x08000000; *off != 0xE3A01040; off++) //Until mov r1, #0x40 { if((*off >> 26) != 0x39 || ((*off >> 16) & 0xF) != 0 || ((*off >> 25) & 1) != 0 || ((*off >> 20) & 5) != 0) continue; //Discard everything that's not str rX, [r0, #imm](!) @@ -288,7 +286,7 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) } } -void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr) +void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address) { //Stub svcBreak with "bkpt 65535" so we can debug the panic. //Thanks @yellows8 and others for mentioning this idea on #3dsdev. @@ -296,14 +294,14 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr) u32 *arm9SvcTable = (u32 *)memsearch(pos, svcHandlerPattern, size, 4); while(*arm9SvcTable) arm9SvcTable++; //Look for SVC0 (NULL) - u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9addr); + + u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9Address); *addr = 0xE12FFF7F; } void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable) { //Same as above, for NFIRM arm11 - u32 *addr = (u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000); *addr = 0xE12FFF7F; } @@ -312,12 +310,11 @@ void patchKernel9Panic(u8 *pos, u32 size, FirmwareType firmType) { if(firmType == TWL_FIRM || firmType == AGB_FIRM) { - u8 *off = pos + ((isN3DS) ? 0x723C : 0x69A8); + u8 *off = pos + (isN3DS ? 0x723C : 0x69A8); *(u16 *)off = 0x4778; //bx pc *(u16 *)(off + 2) = 0x46C0; //nop *(u32 *)(off + 4) = 0xE12FFF7E; //bkpt 65534 } - else { const u8 pattern[] = {0x00, 0x20, 0xA0, 0xE3, 0x02, 0x30, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x05, 0x00, 0xA0, 0xE3}; @@ -337,41 +334,34 @@ void patchKernel11Panic(u8 *pos, u32 size) void patchArm11SvcAccessChecks(u32 *arm11SvcHandler) { - u32 *off = arm11SvcHandler; - while(*off != 0xE11A0E1B) off++; //TST R10, R11,LSL LR - - *off = 0xE3B0A001; //MOVS R10, #1 + while(*arm11SvcHandler != 0xE11A0E1B) arm11SvcHandler++; //TST R10, R11,LSL LR + *arm11SvcHandler = 0xE3B0A001; //MOVS R10, #1 } //It's mainly Subv's code here: void patchK11ModuleChecks(u8 *pos, u32 size, u8 **freeK11Space) { - // We have to detour a function in the ARM11 kernel because builtin modules - // are compressed in memory and are only decompressed at runtime. - - u8 *freeSpace = *freeK11Space; - *freeK11Space += k11modules_size; + //We have to detour a function in the ARM11 kernel because builtin modules + //are compressed in memory and are only decompressed at runtime. - // Inject our code into the free space - memcpy(freeSpace, k11modules, k11modules_size); + //Inject our code into the free space + memcpy(*freeK11Space, k11modules, k11modules_size); + (*freeK11Space) += k11modules_size; - // Find the code that decompresses the .code section of the builtin modules and detour it with a jump to our code + //Find the code that decompresses the .code section of the builtin modules and detour it with a jump to our code const u8 pattern[] = { 0x00, 0x00, 0x94, 0xE5, 0x18, 0x10, 0x90, 0xE5, 0x28, 0x20, 0x90, 0xE5, 0x48, 0x00, 0x9D, 0xE5 }; - u8 *off = memsearch(pos, pattern, size, 16); + u32 *off = (u32 *)memsearch(pos, pattern, size, 16); - // We couldn't find the code that decompresses the module - if (off == NULL) - return; + //We couldn't find the code that decompresses the module + if(off == NULL) return; - // Inject a jump instruction to our code at the offset we found - // Construct a jump (BL) instruction to our code - u32 offset = ((((u32)freeSpace) - ((u32)off + 8)) >> 2) & 0xFFFFFF; - u32 instruction = offset | (1 << 24) | (0x5 << 25) | (0xE << 28); + //Inject a jump instruction to our code at the offset we found + //Construct a jump (BL) instruction to our code + u32 offset = ((((u32)*freeK11Space) - ((u32)off + 8)) >> 2) & 0xFFFFFF; - // Write our jump - memcpy(off, &instruction, 4); + *off = offset | (1 << 24) | (0x5 << 25) | (0xE << 28); } void patchP9AccessChecks(u8 *pos, u32 size) @@ -384,7 +374,6 @@ void patchP9AccessChecks(u8 *pos, u32 size) off[1] = 0x4770; //bx lr } - void patchUnitInfoValueSet(u8 *pos, u32 size) { //Look for UNITINFO value being set during kernel sync @@ -392,6 +381,6 @@ void patchUnitInfoValueSet(u8 *pos, u32 size) u8 *off = memsearch(pos, pattern, size, 4); - off[0] = (isDevUnit) ? 0 : 1; + off[0] = isDevUnit ? 0 : 1; off[3] = 0xE3; } \ No newline at end of file diff --git a/source/patches.h b/source/patches.h index ae0cd62..fe80a94 100644 --- a/source/patches.h +++ b/source/patches.h @@ -63,7 +63,7 @@ void patchTwlBg(u8 *pos); void getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset); void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size); -void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr); +void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address); void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable); void patchKernel9Panic(u8 *pos, u32 size, FirmwareType firmType); void patchKernel11Panic(u8 *pos, u32 size);