diff --git a/Makefile b/Makefile index 70bf2f9..2dec52b 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ dir_out := out ASFLAGS := -mcpu=arm946e-s CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -flto -ffast-math LDFLAGS := -nostartfiles -FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Aurora Wright" --no-print-directory +FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Aurora Wright/TuxSH" --no-print-directory objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ diff --git a/injector/source/patcher.c b/injector/source/patcher.c index b7075cf..b78ddf8 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -476,13 +476,13 @@ void patchCode(u64 progId, u8 *code, u32 size) case 0x0004013000003702LL: // RO { static const u8 sigCheckPattern[] = { - 0x30, 0x40, 0x2D, 0xE9, 0x02, 0x50, 0xA0, 0xE1 + 0x30, 0x40, 0x2D, 0xE9, 0x02 }; static const u8 sha256ChecksPattern1[] = { - 0x30, 0x40, 0x2D, 0xE9, 0x24, 0xD0, 0x4D, 0xE2 + 0x30, 0x40, 0x2D, 0xE9, 0x24 }; static const u8 sha256ChecksPattern2[] = { - 0xF8, 0x4F, 0x2D, 0xE9, 0x01, 0x70, 0xA0, 0xE1 + 0xF8, 0x4F, 0x2D, 0xE9, 0x01 }; static const u8 stub[] = { diff --git a/source/buttons.h b/source/buttons.h index fd50eb3..d8a8f69 100644 --- a/source/buttons.h +++ b/source/buttons.h @@ -22,7 +22,6 @@ #define BUTTON_DOWN (1 << 7) #define SAFE_MODE (BUTTON_R1 | BUTTON_L1 | BUTTON_A | BUTTON_UP) -#define OVERRIDE_BUTTONS (BUTTON_B ^ 0xFFF) #define SINGLE_PAYLOAD_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START | BUTTON_X | BUTTON_Y) #define L_PAYLOAD_BUTTONS (BUTTON_R1 | BUTTON_A | BUTTON_SELECT) #define MENU_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_A | BUTTON_START) \ No newline at end of file diff --git a/source/emunand.c b/source/emunand.c index c58f9c5..99ba3f3 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -64,8 +64,8 @@ static inline void patchNANDRW(u8 *pos, u32 size, u32 branchOffset) //Look for read/write code const u8 pattern[] = {0x1E, 0x00, 0xC8, 0x05}; - u16 *readOffset = (u16 *)memsearch(pos, pattern, size, 4) - 3; - u16 *writeOffset = (u16 *)memsearch((u8 *)(readOffset + 5), pattern, 0x100, 4) - 3; + u16 *readOffset = (u16 *)memsearch(pos, pattern, size, 4) - 3, + *writeOffset = (u16 *)memsearch((u8 *)(readOffset + 5), pattern, 0x100, 4) - 3; *readOffset = nandRedir[0]; readOffset[1] = nandRedir[1]; @@ -96,8 +96,8 @@ void patchEmuNAND(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 memcpy(emuCodeOffset, emunand, emunand_size); //Add the data of the found emuNAND - u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", emunand_size, 4); - u32 *pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", emunand_size, 4); + u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", emunand_size, 4), + *pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", emunand_size, 4); *pos_offset = emuOffset; *pos_header = emuHeader; diff --git a/source/firm.c b/source/firm.c index 1d6420b..ecf5952 100755 --- a/source/firm.c +++ b/source/firm.c @@ -122,29 +122,29 @@ void main(void) { nandType = 0; firmSource = updatedSys ? 0 : BOOTCONFIG(2, 1); - needConfig--; + needConfig = 0; //Flag to prevent multiple boot options-forcing newConfig |= 1 << 4; } - /* Else, force the last used boot options unless a payload button or A/L/R are pressed + /* Else, force the last used boot options unless a button is pressed or the no-forcing flag is set */ - else if(!(pressed & OVERRIDE_BUTTONS) && !BOOTCONFIG(4, 1)) + else if(!pressed && !BOOTCONFIG(4, 1)) { nandType = BOOTCONFIG(0, 3); firmSource = BOOTCONFIG(2, 1); - needConfig--; + needConfig = 0; } } //If the SAFE MODE combo is held, force a sysNAND boot else if(pressed == SAFE_MODE) { - a9lhMode++; + a9lhMode = 2; nandType = 0; firmSource = 0; - needConfig--; + needConfig = 0; } } @@ -180,7 +180,7 @@ void main(void) /* If we're booting emuNAND the second emuNAND is set as default and B isn't pressed, or vice-versa, boot the second emuNAND */ - if(nandType && (CONFIG(3) == !(pressed & BUTTON_B))) nandType++; + if(nandType && (CONFIG(3) == !(pressed & BUTTON_B))) nandType = 2; } } @@ -260,8 +260,9 @@ static inline void loadFirm(u32 firmType, u32 externalFirm) static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode) { - u8 *arm9Section = (u8 *)firm + section[2].offset; - + u8 *arm9Section = (u8 *)firm + section[2].offset, + *arm11Section1 = (u8 *)firm + section[1].offset; + u32 nativeFirmType; if(console) @@ -298,10 +299,7 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode) //Apply signature patches patchSignatureChecks(process9Offset, process9Size); - - //Apply anti-anti-DG patches for >= 11.0 firmwares - if(nativeFirmType == 1) patchTitleInstallMinVersionCheck(process9Offset, process9Size); - + //Apply emuNAND patches if(nandType) { @@ -315,16 +313,22 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode) //Apply firmlaunch patches, not on 9.0 FIRM as it breaks firmlaunchhax if(nativeFirmType || a9lhMode == 2) patchFirmlaunches(process9Offset, process9Size, process9MemAddr); - //Does nothing if svcBackdoor is still there - if(nativeFirmType == 1) reimplementSvcBackdoor((u8 *)firm + section[1].offset, section[1].size); + if(nativeFirmType == 1) + { + //Apply anti-anti-DG patches for >= 11.0 firmwares + patchTitleInstallMinVersionCheck(process9Offset, process9Size); + + //Does nothing if svcBackdoor is still there + reimplementSvcBackdoor(arm11Section1, section[1].size); + } if(DEVMODE) { //Apply UNITINFO patch patchUnitInfoValueSet(arm9Section, section[2].size); - + //Make FCRAM (and VRAM as a side effect) globally executable from arm11 kernel - patchKernelFCRAMAndVRAMMappingPermissions(arm9Section, section[2].size); + patchKernelFCRAMAndVRAMMappingPermissions(arm11Section1, section[1].size); } } diff --git a/source/patches.c b/source/patches.c index 32e3a4b..6d5f853 100644 --- a/source/patches.c +++ b/source/patches.c @@ -34,18 +34,9 @@ void patchSignatureChecks(u8 *pos, u32 size) off2[1] = sigPatch[1]; } -void patchTitleInstallMinVersionCheck(u8 *pos, u32 size) -{ - const u8 pattern[] = {0x89, 0x0A, 0x81, 0x42, 0x02, 0xD2}; - - u8 *off = memsearch(pos, pattern, size, 6); - - if(off != NULL) off[5] = 0xE0; -} - void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr) { - //Look for FIRM reboot code + //Look for firmlaunch code const u8 pattern[] = {0xDE, 0x1F, 0x8D, 0xE2}; u8 *off = memsearch(pos, pattern, size, 4) - 0x10; @@ -90,34 +81,28 @@ void patchFirmWriteSafe(u8 *pos, u32 size) void patchExceptionHandlersInstall(u8 *pos, u32 size) { - static const u8 pattern[] = { - 0x18, 0x10, 0x80, 0xE5, - 0x10, 0x10, 0x80, 0xE5, - 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; - + const u8 pattern[] = {0x50, 0x50, 0x9F, 0xE5}; + + u32 *off = (u32 *)memsearch(pos, pattern, size, 4) - 1; + u32 r0 = 0x08000000; - - for(; *off != 0xE3A01040; off++) //until mov r1, #0x40 + + for(; *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](!) - - int rD = (*off >> 12) & 0xf; - int offset = (*off & 0xfff) * ((((*off >> 23) & 1) == 0) ? -1 : 1); - int writeback = (*off >> 21) & 1, pre = (*off >> 24) & 1; - + 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](!) + + int rD = (*off >> 12) & 0xF, + offset = (*off & 0xFFF) * ((((*off >> 23) & 1) == 0) ? -1 : 1), + writeback = (*off >> 21) & 1, + pre = (*off >> 24) & 1; + u32 addr = r0 + ((pre || !writeback) ? offset : 0); if(addr != 0x08000014 && addr != 0x08000004) *off = 0xE1A00000; //nop else - *off = 0xE5800000 | (rD << 12) | (addr & 0xfff); //preserve IRQ and svc handlers - + *off = 0xE5800000 | (rD << 12) | (addr & 0xFFF); //Preserve IRQ and SVC handlers + if(!pre) addr += offset; if(writeback) r0 = addr; } @@ -129,20 +114,18 @@ void patchUnitInfoValueSet(u8 *pos, u32 size) const u8 pattern[] = {0x01, 0x10, 0xA0, 0x13}; u8 *off = memsearch(pos, pattern, size, 4); - if(off != NULL) off[3] = 0xE3; + + off[3] = 0xE3; } void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size) { - static const u8 MMUConfigPattern[] = { - 0xC4, 0xDD, 0xFA, 0x1F, - 0x16, 0x64, 0x01, 0x00, - 0xBC, 0xDD, 0xFA, 0x1F, - 0x00, 0x50, 0xFF, 0x1F - }; + //Look for MMU config + const u8 pattern[] = {0xC4, 0xDD, 0xFA, 0x1F}; - u32* off = (u32 *)memsearch(pos, MMUConfigPattern, size, sizeof(MMUConfigPattern)); - if(off != NULL) off[1] &= ~(1 << 4); //clear XN bit + u32* off = (u32 *)memsearch(pos, pattern, size, 4); + + if(off != NULL) off[1] &= ~(1 << 4); //Clear XN bit } void reimplementSvcBackdoor(u8 *pos, u32 size) @@ -178,6 +161,15 @@ void reimplementSvcBackdoor(u8 *pos, u32 size) } } +void patchTitleInstallMinVersionCheck(u8 *pos, u32 size) +{ + const u8 pattern[] = {0x0A, 0x81, 0x42, 0x02}; + + u8 *off = memsearch(pos, pattern, size, 4); + + if(off != NULL) off[4] = 0xE0; +} + void applyLegacyFirmPatches(u8 *pos, u32 firmType, u32 console) { const patchData twlPatches[] = {