From b4d94da531962de18957e6e9de90cd2aa7b3a4cf Mon Sep 17 00:00:00 2001 From: Aurora Date: Fri, 19 Feb 2016 21:32:07 +0100 Subject: [PATCH] Added "updated sysNAND" mode, FIRM writes patch, propered emuNAND code location Thanks to delebile for the patch! --- Makefile | 16 +++++------ source/emunand.c | 8 ------ source/emunand.h | 1 - source/firm.c | 73 +++++++++++++++++++++++++++++++----------------- source/main.c | 8 +++--- source/patches.c | 9 ++++++ source/patches.h | 2 ++ 7 files changed, 70 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index 2d518f2..351d037 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ .PHONY: all -all: launcher a9lh emunand emunando3ds reboot reboot2 rebootntr ninjhax +all: launcher a9lh emunand emunando3ds reboot rebootntr ninjhax .PHONY: launcher launcher: $(dir_out)/$(name).dat @@ -42,16 +42,13 @@ launcher: $(dir_out)/$(name).dat a9lh: $(dir_out)/arm9loaderhax.bin .PHONY: emunand -emunand: $(dir_out)/rei-n3ds/emunand/emunand.bin +emunand: $(dir_out)/rei-n3ds/emunand/emunand.bin $(dir_out)/rei-n3ds/emunand/emunand90.bin .PHONY: emunando3ds emunando3ds: $(dir_out)/rei-o3ds/emunand/emunand.bin .PHONY: reboot -reboot: $(dir_out)/rei-o3ds/reboot/reboot1.bin - -.PHONY: reboot2 -reboot2: $(dir_out)/rei-o3ds/reboot/reboot2.bin +reboot: $(dir_out)/rei-o3ds/reboot/reboot1.bin $(dir_out)/rei-o3ds/reboot/reboot2.bin .PHONY: rebootntr rebootntr: $(dir_out)/ntr-o3ds/reboot/reboot1.bin $(dir_out)/ntr-o3ds/reboot/reboot2.bin @@ -70,7 +67,7 @@ $(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)/rei-n3ds/ $(dir_out)/re dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144 $(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)/rei-n3ds/ $(dir_out)/rei-o3ds/ - @cp $(dir_build)/main.bin $(dir_out)/arm9loaderhax.bin + @cp -av $(dir_build)/main.bin $(dir_out)/arm9loaderhax.bin $(dir_out)/3ds/$(name): @mkdir -p "$(dir_out)/3ds/$(name)" @@ -94,7 +91,10 @@ $(dir_out)/rei-n3ds/emunand/emunand.bin: $(dir_emu)/emuCode.s $(dir_out)/rei-o3ds/emunand/emunand.bin: $(dir_emu)/emuCodeo3ds.s @armips $< @mkdir -p "$(dir_out)/rei-o3ds/emunand" - @mv emunand.bin $(dir_out)/rei-o3ds/emunand + @cp -av emunand.bin $(dir_out)/rei-o3ds/emunand + +$(dir_out)/rei-n3ds/emunand/emunand90.bin: $(dir_out)/rei-o3ds/emunand/emunand.bin + @mv emunand.bin $(dir_out)/rei-n3ds/emunand/emunand90.bin $(dir_out)/rei-o3ds/reboot/reboot1.bin: $(dir_reboot)/rebootCode.s @armips $< diff --git a/source/emunand.c b/source/emunand.c index 253e72a..c1c072b 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -53,12 +53,4 @@ void getMPU(void *pos, u32 *off, u32 size){ unsigned char pattern[] = {0x03, 0x00, 0x24, 0x00, 0x00}; *off = (u32)memsearch(pos, pattern, size, 5); -} - -void getEmuCode(void *pos, u32 *off, u32 size){ - void *proc9 = memsearch(pos, "Process9", size, 8); - unsigned char pattern[] = {0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}; - - //Looking for the last spot before Process9 - *off = (u32)memsearch(pos, pattern, size - (size - (u32)(proc9 - pos)), 6) + 0xF; } \ No newline at end of file diff --git a/source/emunand.h b/source/emunand.h index 7304423..702c7c7 100644 --- a/source/emunand.h +++ b/source/emunand.h @@ -15,6 +15,5 @@ void getEmunandSect(u32 *off, u32 *head); void getSDMMC(void *pos, u32 *off, u32 size); void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff); void getMPU(void *pos, u32 *off, u32 size); -void getEmuCode(void *pos, u32 *off, u32 size); #endif \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 686ce45..d5ce318 100755 --- a/source/firm.c +++ b/source/firm.c @@ -15,21 +15,34 @@ firmHeader *firmLocation = (firmHeader *)0x24000000; firmSectionHeader *section; u32 firmSize = 0; u8 mode = 1, - console = 1; + console = 1, + a9lhSetup = 0, + updatedSys = 0; u16 pressed; //Load firm into FCRAM -u8 loadFirm(u8 a9lh){ +u8 loadFirm(u8 a9lhBoot){ + //Detect the console being used if(PDN_MPCORE_CFG == 1) console = 0; + //Get pressed buttons pressed = HID_PAD; + //Determine if A9LH is installed + if(a9lhBoot || fileSize("/rei/installeda9lh")){ + a9lhSetup = 1; + //Check flag for > 9.2 SysNAND + if(fileSize("/rei/updatedsysnand")) updatedSys = 1; + } + section = firmLocation->section; - //If L and R are pressed, boot SysNAND with the 9.0 FIRM - if((pressed & BUTTON_L1R1) == BUTTON_L1R1) mode = 0; + /* If L and R are pressed on a 9.0/2 SysNAND, or L on an updated + SysNAND, boot 9.0 FIRM */ + if((!updatedSys & ((pressed & BUTTON_L1R1) == BUTTON_L1R1)) | + (updatedSys & (pressed == BUTTON_L1))) mode = 0; //If not using an A9LH setup, do so by decrypting FIRM0 - if(!a9lh && !fileSize("/rei/installeda9lh") && !mode){ + if(!a9lhSetup && !mode){ //Read FIRM from NAND and write to FCRAM firmSize = console ? 0xF2000 : 0xE9000; nandFirm0((u8*)firmLocation, firmSize, console); @@ -37,18 +50,12 @@ u8 loadFirm(u8 a9lh){ } //Load FIRM from SD else{ - if (!mode){ - char firmPath[] = "/rei/firmware90.bin"; - firmSize = fileSize(firmPath); - if (!firmSize) return 1; - fileRead((u8*)firmLocation, firmPath, firmSize); - } - else { - char firmPath[] = "/rei/firmware.bin"; - firmSize = fileSize(firmPath); - if (!firmSize) return 1; - fileRead((u8*)firmLocation, firmPath, firmSize); - } + char firmPath[] = "/rei/firmware.bin"; + char firmPath2[] = "/rei/firmware90.bin"; + char *pathPtr = mode ? firmPath : firmPath2; + firmSize = fileSize(pathPtr); + if (!firmSize) return 1; + fileRead((u8*)firmLocation, pathPtr, firmSize); } if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 1; @@ -69,11 +76,16 @@ u8 loadEmu(void){ emuCodeOffset = 0; //Read emunand code from SD - const char path[] = "/rei/emunand/emunand.bin"; - u32 size = fileSize(path); + char path[] = "/rei/emunand/emunand.bin"; + char path2[] = "/rei/emunand/emunand90.bin"; + char *pathPtr = ((!mode) & console) ? path2 : path; + u32 size = fileSize(pathPtr); if (!size) return 1; - getEmuCode(firmLocation, &emuCodeOffset, firmSize); - fileRead((u8*)emuCodeOffset, path, size); + if(!console | !mode) nandRedir[5] = 0xA4; + u8 *emuCodeTmp = &nandRedir[4]; + emuCodeOffset = *(u32*)emuCodeTmp - (u32)section[2].address + + section[2].offset + (u32)firmLocation; + fileRead((u8*)emuCodeOffset, pathPtr, size); //Find and patch emunand related offsets u32 *pos_sdmmc = memsearch((u32*)emuCodeOffset, "SDMC", size, 4); @@ -88,7 +100,6 @@ u8 loadEmu(void){ *pos_header = emuHeader; //Add emunand hooks - if(!console) nandRedir[5] = 0xA4; memcpy((u8*)emuRead, nandRedir, sizeof(nandRedir)); memcpy((u8*)emuWrite, nandRedir, sizeof(nandRedir)); @@ -101,8 +112,18 @@ u8 loadEmu(void){ //Patches u8 patchFirm(void){ - //If L is pressed, boot SysNAND with the SD FIRM - if(mode && !(pressed & BUTTON_L1)) if (loadEmu()) return 1; + /* If L is pressed on a 9.0/9.2 SysNAND, or L+R on a > 9.2 SysNAND, + or the 9.0 FIRM is loaded on a > 9.2 SysNAND, boot emuNAND */ + if((updatedSys & (!mode | (pressed == BUTTON_L1R1))) | + ((!updatedSys) & mode & !(pressed & BUTTON_L1))){ + if (loadEmu()) return 1; + } + else if (a9lhSetup){ + //Patch FIRM partitions writes on SysNAND to protect A9LH + u32 writeOffset = 0; + getFIRMWrite(firmLocation, firmSize, &writeOffset); + memcpy((u8*)writeOffset, FIRMblock, sizeof(FIRMblock)); + } u32 sigOffset = 0, sigOffset2 = 0; @@ -112,8 +133,8 @@ u8 patchFirm(void){ memcpy((u8*)sigOffset, sigPat1, sizeof(sigPat1)); memcpy((u8*)sigOffset2, sigPat2, sizeof(sigPat2)); - //Apply FIRM reboot patch. Not needed with A9LH and N3DS. - if(!console && !a9lh && mode && + //Apply FIRM reboot patch. Not needed with A9LH and N3DS + if(!console && !a9lhSetup && mode && ((fileSize("/rei/reversereboot") > 0) == (pressed & BUTTON_A))){ u32 rebootOffset = 0, rebootOffset2 = 0; diff --git a/source/main.c b/source/main.c index fdebe42..53248cf 100644 --- a/source/main.c +++ b/source/main.c @@ -10,14 +10,14 @@ #include "firm.h" #include "draw.h" -u8 a9lh = 0; +u8 a9lhBoot = 0; u8 main(){ mountSD(); - //Detect A9LH mode checking PDN_GPU_CNT2 register. - if (!*((u32*)0x10141204)) a9lh = 1; + //Detect an A9LH boot checking PDN_GPU_CNT register + if (*((u8*)0x10141200) == 0x1) a9lhBoot = 1; else loadSplash(); - if (loadFirm(a9lh)) return 1; + if (loadFirm(a9lhBoot)) return 1; if (patchFirm()) return 1; launchFirm(); return 0; diff --git a/source/patches.c b/source/patches.c index 17f5a9f..2e59be2 100644 --- a/source/patches.c +++ b/source/patches.c @@ -27,6 +27,7 @@ u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA5, 0x01, 0x08}; //Bran */ u8 sigPat1[2] = {0x00, 0x20}; u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47}; +u8 FIRMblock[4] = {0x00, 0x20, 0xC0, 0x46}; /************************************************** * Functions @@ -48,4 +49,12 @@ void getReboot(void *pos, u32 size, u32 *off, u32 *off2){ *off = (u32)memsearch(pos, pattern, size, 5) + 2; *off2 = (u32)memsearch(pos, pattern2, size, 5); +} + +void getFIRMWrite(void *pos, u32 size, u32 *off){ + //Look for FIRM writing code + void *firmwrite = memsearch(pos, "exe:/", size, 5); + unsigned char pattern[] = {0x00, 0x28, 0x01, 0xDA}; + + *off = (u32)memsearch(firmwrite - 0x100, pattern, 0x100, 4); } \ No newline at end of file diff --git a/source/patches.h b/source/patches.h index 5c28488..f3d55c7 100644 --- a/source/patches.h +++ b/source/patches.h @@ -15,11 +15,13 @@ u8 mpu[0x2C]; u8 nandRedir[0x08]; u8 sigPat1[2]; u8 sigPat2[4]; +u8 FIRMblock[4]; /************************************************** * Functions **************************************************/ void getSignatures(void *pos, u32 size, u32 *off, u32 *off2); void getReboot(void *pos, u32 size, u32 *off, u32 *off2); +void getFIRMWrite(void *pos, u32 size, u32 *off); #endif \ No newline at end of file