diff --git a/injector/patches/romfsredir.s b/injector/patches/romfsredir.s index 53f7559..2ea2433 100644 --- a/injector/patches/romfsredir.s +++ b/injector/patches/romfsredir.s @@ -7,9 +7,6 @@ .macro load, reg, func ldr reg, [pc, #func-.-8] .endmacro -.macro svc, svcnum - .word 0xef000000 + svcnum -.endmacro ; Patch by delebile @@ -34,7 +31,7 @@ _start: bne _mountSd+4 stmfd sp!, {r0-r4, lr} sub sp, sp, #4 - load r1, archive + load r1, archive mov r0, sp load r4, fsMountArchive blx r4 @@ -106,4 +103,3 @@ _start: sdmcCustomPath : .word 0xdead0004 .close - diff --git a/injector/source/patcher.c b/injector/source/patcher.c index f152952..84ff318 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -278,7 +278,7 @@ static inline void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHa } } -static u32 findStart(u8* code, u32 pos) +static u32 findFunctionStart(u8* code, u32 pos) { while(pos >= 4) { @@ -289,7 +289,7 @@ static u32 findStart(u8* code, u32 pos) return 0xFFFFFFFF; } -static bool findSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *fsRegisterArchive, u32 *fsTryOpenFile, u32 *fsOpenFileDirectly, u32 *throwFatalError) +static bool findLayeredFsSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *fsRegisterArchive, u32 *fsTryOpenFile, u32 *fsOpenFileDirectly, u32 *throwFatalError) { u32 svcConnectToPort = 0xFFFFFFFF; @@ -300,49 +300,28 @@ static bool findSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *fsRegister if(addr <= size - 12 && *(u32 *)(code + addr) == 0xE5970010) { if((*(u32 *)(code + addr + 4) == 0xE1CD20D8) && ((*(u32 *)(code + addr + 8) & 0xFFFFFF) == 0x008D0000)) - *fsMountArchive = findStart(code, addr); + *fsMountArchive = findFunctionStart(code, addr); } else if(addr <= size - 16 && *(u32 *)(code + addr) == 0xE24DD028) { if((*(u32 *)(code + addr + 4) == 0xE1A04000) && (*(u32 *)(code + addr + 8) == 0xE59F60A8) && (*(u32 *)(code + addr + 0xC) == 0xE3A0C001)) - *fsMountArchive = findStart(code, addr); + *fsMountArchive = findFunctionStart(code, addr); } } - if(*fsRegisterArchive == 0xFFFFFFFF && addr <= size - 8) - { - if(*(u32 *)(code + addr) == 0xC82044B4) - { - if(*(u32 *)(code + addr + 4) == 0xD8604659) - *fsRegisterArchive = findStart(code, addr); - } - } + if(addr <= size - 12 && *fsRegisterArchive == 0xFFFFFFFF && *(u32 *)(code + addr) == 0xE3500008 && (*(u32 *)(code + addr + 4) & 0xFFF00FF0) == 0xE1800400 && (*(u32 *)(code + addr + 8) & 0xFFF00FF0) == 0xE1800FC0) + *fsRegisterArchive = findFunctionStart(code, addr); - if(*fsTryOpenFile == 0xFFFFFFFF && addr <= size - 12) - { - if(*(u32 *)(code + addr + 0xC) == 0xE12FFF3C) - { - if(((*(u32 *)(code + addr) == 0xE1A0100D) || (*(u32 *)(code + addr) == 0xE28D1010)) && - (*(u32 *)(code + addr + 4) == 0xE590C000) && ((*(u32 *)(code + addr + 8) == 0xE1A00004) || (*(u32 *)(code + addr + 8) == 0xE1A00005))) - { - *fsTryOpenFile = findStart(code, addr); - } - } - } + if(addr <= size - 16 && *fsTryOpenFile == 0xFFFFFFFF && *(u32 *)(code + addr + 0xC) == 0xE12FFF3C && + ((*(u32 *)(code + addr) == 0xE1A0100D) || (*(u32 *)(code + addr) == 0xE28D1010)) && (*(u32 *)(code + addr + 4) == 0xE590C000) && + ((*(u32 *)(code + addr + 8) == 0xE1A00004) || (*(u32 *)(code + addr + 8) == 0xE1A00005))) + *fsTryOpenFile = findFunctionStart(code, addr); - if(*fsOpenFileDirectly == 0xFFFFFFFF) - { - if(*(u32 *)(code + addr) == 0x08030204) - { - *fsOpenFileDirectly = findStart(code, addr); - } - } + if(*fsOpenFileDirectly == 0xFFFFFFFF && *(u32 *)(code + addr) == 0x08030204) + *fsOpenFileDirectly = findFunctionStart(code, addr); - if(svcConnectToPort == 0xFFFFFFFF && addr >= 4) - { - if(*(u32 *)(code + addr) == 0xEF00002D) - svcConnectToPort = addr - 4; - } + if(addr >= 4 && svcConnectToPort == 0xFFFFFFFF && *(u32 *)(code + addr) == 0xEF00002D) + svcConnectToPort = addr - 4; } if(svcConnectToPort != 0xFFFFFFFF && *fsMountArchive != 0xFFFFFFFF && *fsRegisterArchive != 0xFFFFFFFF && *fsTryOpenFile != 0xFFFFFFFF && *fsOpenFileDirectly != 0xFFFFFFFF) @@ -353,7 +332,7 @@ static bool findSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *fsRegister { if(*(u32 *)(code + i) != MAKE_BRANCH_LINK(i, svcConnectToPort)) continue; - func = findStart(code, i); + func = findFunctionStart(code, i); for(u32 pos = func + 4; func != 0xFFFFFFFF && pos <= size - 4 && *(u16 *)(code + pos + 2) != 0xE92D; pos += 4) if(*(u32 *)(code + pos) == 0xE200167E) func = 0xFFFFFFFF; @@ -509,10 +488,10 @@ exit: return ret; } -static inline bool patchRomfsRedirection(u64 progId, u8* code, u32 size) +static inline bool patchLayeredFs(u64 progId, u8* code, u32 size) { /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/romfs" - If it exists it should be a decrypted raw RomFS */ + If it exists it should be a folder containing ROMFS files */ char path[] = "/luma/titles/0000000000000000/romfs"; progIdToStr(path + 28, progId); @@ -529,7 +508,7 @@ static inline bool patchRomfsRedirection(u64 progId, u8* code, u32 size) fsOpenFileDirectly = 0xFFFFFFFF, throwFatalError; - if(!findSymbols(code, size, &fsMountArchive, &fsRegisterArchive, &fsTryOpenFile, &fsOpenFileDirectly, &throwFatalError)) return false; + if(!findLayeredFsSymbols(code, size, &fsMountArchive, &fsRegisterArchive, &fsTryOpenFile, &fsOpenFileDirectly, &throwFatalError)) return false; //Setup the payload u8 *payload = code + throwFatalError; @@ -788,7 +767,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size) )) goto error; } - else if(progId == 0x0004003000008A02LL) //ErrDisp + else if(CONFIG(ENABLEEXCEPTIONHANDLERS) && !CONFIG(PATCHUNITINFO) && progId == 0x0004003000008A02LL) //ErrDisp { static const u8 pattern[] = { 0x00, 0xD0, 0xE5, 0xDB @@ -839,9 +818,9 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size) languageId; if(!loadTitleCodeSection(progId, code, size) || + !applyCodeIpsPatch(progId, code, size) || !loadTitleLocaleConfig(progId, ®ionId, &languageId) || - !patchRomfsRedirection(progId, code, size) || - !applyCodeIpsPatch(progId, code, size)) goto error; + !patchLayeredFs(progId, code, size)) goto error; if(regionId != 0xFF) { diff --git a/injector/source/patcher.h b/injector/source/patcher.h index 74dd4b0..e7a3ae5 100644 --- a/injector/source/patcher.h +++ b/injector/source/patcher.h @@ -21,7 +21,7 @@ enum multiOptions BRIGHTNESS, SPLASH, PIN, - NEWCPU, + NEWCPU }; enum singleOptions diff --git a/source/config.c b/source/config.c index 524c618..53198f7 100644 --- a/source/config.c +++ b/source/config.c @@ -30,9 +30,13 @@ #include "pin.h" CfgData configData; +ConfigurationStatus needConfig; +static CfgData oldConfig; bool readConfig(void) { + bool ret; + if(fileRead(&configData, CONFIG_FILE, sizeof(CfgData)) != sizeof(CfgData) || memcmp(configData.magic, "CONF", 4) != 0 || configData.formatVersionMajor != CONFIG_VERSIONMAJOR || @@ -40,17 +44,23 @@ bool readConfig(void) { configData.config = 0; - return false; + ret = false; } + else ret = true; - return true; + oldConfig = configData; + + return ret; } -void writeConfig(ConfigurationStatus needConfig, u32 configTemp) +void writeConfig(bool isPayloadLaunch) { /* If the configuration is different from previously, overwrite it. Just the no-forcing flag being set is not enough */ - if(needConfig != CREATE_CONFIGURATION && (configTemp & 0xFFFFFF7F) == configData.config) return; + + if(isPayloadLaunch) configData.config = (configData.config & 0xFFFFFF00) | (oldConfig.config & 0xFF); + + if(needConfig != CREATE_CONFIGURATION && (configData.config & 0xFFFFFF7F) == oldConfig.config) return; if(needConfig == CREATE_CONFIGURATION) { @@ -59,9 +69,6 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp) configData.formatVersionMinor = CONFIG_VERSIONMINOR; } - //Merge the new options and new boot configuration - configData.config = (configData.config & 0xFFFFFF00) | (configTemp & 0xFF); - if(!fileWrite(&configData, CONFIG_FILE, sizeof(CfgData))) error("Error writing the configuration file"); } diff --git a/source/config.h b/source/config.h index 2782912..58e08f9 100644 --- a/source/config.h +++ b/source/config.h @@ -68,5 +68,5 @@ typedef enum ConfigurationStatus } ConfigurationStatus; bool readConfig(void); -void writeConfig(ConfigurationStatus needConfig, u32 configTemp); +void writeConfig(bool isPayloadLaunch); void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode); diff --git a/source/exceptions.c b/source/exceptions.c index bb595db..6a20d76 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -85,8 +85,6 @@ u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffse va_src = dAbtHandlerMemAddress + ((u8 *)pos - (u8 *)dAbtHandler); *pos = MAKE_BRANCH((u8 *)va_src, (u8 *)va_dst); break; - default: - break; } } diff --git a/source/firm.c b/source/firm.c index 70f8e58..bd9d39e 100755 --- a/source/firm.c +++ b/source/firm.c @@ -175,9 +175,8 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo ret += reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space); } - //11.3 FIRM patches - if(firmVersion >= (ISN3DS ? 0x2D : 0x5C)) //Stub svc 0x59 - ret += stubSvcRestrictGpuDma(arm11Section1, arm11SvcTable, baseK11VA); + //Stub svc 0x59 on 11.3+ FIRMs + if(firmVersion >= (ISN3DS ? 0x2D : 0x5C)) ret += stubSvcRestrictGpuDma(arm11Section1, arm11SvcTable, baseK11VA); ret += implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space, isSafeMode); diff --git a/source/fs.c b/source/fs.c index 831c030..fc62534 100644 --- a/source/fs.c +++ b/source/fs.c @@ -28,6 +28,7 @@ #include "screen.h" #include "draw.h" #include "utils.h" +#include "config.h" #include "fatfs/ff.h" #include "buttons.h" #include "../build/bundled.h" @@ -158,6 +159,8 @@ void loadPayload(u32 pressed, const char *payloadPath) if(!payloadSize) return; + writeConfig(true); + memcpy(loaderAddress, loader_bin, loader_bin_size); loaderAddress[1] = payloadSize; diff --git a/source/main.c b/source/main.c index 2694b09..a634617 100644 --- a/source/main.c +++ b/source/main.c @@ -33,17 +33,16 @@ #include "crypto.h" extern CfgData configData; +extern ConfigurationStatus needConfig; extern FirmwareSource firmSource; void main(void) { bool isA9lhInstalled, isSafeMode = false; - u32 configTemp, - emuHeader; + u32 emuHeader; FirmwareType firmType; FirmwareSource nandType; - ConfigurationStatus needConfig; //Mount SD or CTRNAND bool isSdMode; @@ -95,8 +94,8 @@ void main(void) //Get pressed buttons u32 pressed = HID_PAD; - //Save old options and begin saving the new boot configuration - configTemp = (configData.config & 0xFFFFFF00) | ((u32)ISA9LH << 6); + //Begin saving the new boot configuration + configData.config = (configData.config & 0xFFFFFF00) | ((u32)ISA9LH << 6); //If it's a MCU reboot, try to force boot options if(ISA9LH && CFG_BOOTENV && needConfig != CREATE_CONFIGURATION) @@ -109,7 +108,7 @@ void main(void) firmSource = (BOOTCFG_NAND != 0) == (BOOTCFG_FIRM != 0) ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCFG_FIRM; //Flag to prevent multiple boot options-forcing - configTemp |= 1 << 7; + configData.config |= 1 << 7; goto boot; } @@ -234,8 +233,8 @@ boot: if(!ISFIRMLAUNCH) { - configTemp |= (u32)nandType | ((u32)firmSource << 3); - writeConfig(needConfig, configTemp); + configData.config |= (u32)nandType | ((u32)firmSource << 3); + writeConfig(false); } if(isSdMode && !mountFs(false, false)) error("Failed to mount CTRNAND."); diff --git a/source/patches.c b/source/patches.c index def865d..47f500f 100644 --- a/source/patches.c +++ b/source/patches.c @@ -121,19 +121,15 @@ u32 patchSignatureChecks(u8 *pos, u32 size) u32 patchOldSignatureChecks(u8 *pos, u32 size) { // Look for signature checks - // Pattern 2 works for 1.x, 2.x + factory FIRM. - // For patchSignatureChecks-style (temp - 1 instead of temp - 3): - // 1.x+2.x: pattern2[] = {0xB5, 0x23, 0x4E, 0x0C}; - // factory: pattern2[] = {0xB5, 0x16, 0x4E, 0x0C}; const u8 pattern[] = {0xC0, 0x1C, 0xBD, 0xE7}, - pattern2[] = {0x4E, 0x0C, 0x00, 0x71, 0x68}; + pattern2[] = {0xB5, 0x23, 0x4E, 0x0C}; u16 *off = (u16 *)memsearch(pos, pattern, size, sizeof(pattern)); u8 *temp = memsearch(pos, pattern2, size, sizeof(pattern2)); if(off == NULL || temp == NULL) return 1; - u16 *off2 = (u16 *)(temp - 3); + u16 *off2 = (u16 *)(temp - 1); *off = off2[0] = 0x2000; off2[1] = 0x4770;