Added "updated sysNAND" mode, FIRM writes patch, propered emuNAND code location

Thanks to delebile for the patch!
This commit is contained in:
Aurora 2016-02-19 21:32:07 +01:00
parent 8872a243fc
commit b4d94da531
7 changed files with 70 additions and 47 deletions

View File

@ -33,7 +33,7 @@ objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
.PHONY: all .PHONY: all
all: launcher a9lh emunand emunando3ds reboot reboot2 rebootntr ninjhax all: launcher a9lh emunand emunando3ds reboot rebootntr ninjhax
.PHONY: launcher .PHONY: launcher
launcher: $(dir_out)/$(name).dat launcher: $(dir_out)/$(name).dat
@ -42,16 +42,13 @@ launcher: $(dir_out)/$(name).dat
a9lh: $(dir_out)/arm9loaderhax.bin a9lh: $(dir_out)/arm9loaderhax.bin
.PHONY: emunand .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 .PHONY: emunando3ds
emunando3ds: $(dir_out)/rei-o3ds/emunand/emunand.bin emunando3ds: $(dir_out)/rei-o3ds/emunand/emunand.bin
.PHONY: reboot .PHONY: reboot
reboot: $(dir_out)/rei-o3ds/reboot/reboot1.bin reboot: $(dir_out)/rei-o3ds/reboot/reboot1.bin $(dir_out)/rei-o3ds/reboot/reboot2.bin
.PHONY: reboot2
reboot2: $(dir_out)/rei-o3ds/reboot/reboot2.bin
.PHONY: rebootntr .PHONY: rebootntr
rebootntr: $(dir_out)/ntr-o3ds/reboot/reboot1.bin $(dir_out)/ntr-o3ds/reboot/reboot2.bin 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 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/ $(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): $(dir_out)/3ds/$(name):
@mkdir -p "$(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 $(dir_out)/rei-o3ds/emunand/emunand.bin: $(dir_emu)/emuCodeo3ds.s
@armips $< @armips $<
@mkdir -p "$(dir_out)/rei-o3ds/emunand" @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 $(dir_out)/rei-o3ds/reboot/reboot1.bin: $(dir_reboot)/rebootCode.s
@armips $< @armips $<

View File

@ -53,12 +53,4 @@ void getMPU(void *pos, u32 *off, u32 size){
unsigned char pattern[] = {0x03, 0x00, 0x24, 0x00, 0x00}; unsigned char pattern[] = {0x03, 0x00, 0x24, 0x00, 0x00};
*off = (u32)memsearch(pos, pattern, size, 5); *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;
} }

View File

@ -15,6 +15,5 @@ void getEmunandSect(u32 *off, u32 *head);
void getSDMMC(void *pos, u32 *off, u32 size); void getSDMMC(void *pos, u32 *off, u32 size);
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff); void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff);
void getMPU(void *pos, u32 *off, u32 size); void getMPU(void *pos, u32 *off, u32 size);
void getEmuCode(void *pos, u32 *off, u32 size);
#endif #endif

View File

@ -15,21 +15,34 @@ firmHeader *firmLocation = (firmHeader *)0x24000000;
firmSectionHeader *section; firmSectionHeader *section;
u32 firmSize = 0; u32 firmSize = 0;
u8 mode = 1, u8 mode = 1,
console = 1; console = 1,
a9lhSetup = 0,
updatedSys = 0;
u16 pressed; u16 pressed;
//Load firm into FCRAM //Load firm into FCRAM
u8 loadFirm(u8 a9lh){ u8 loadFirm(u8 a9lhBoot){
//Detect the console being used
if(PDN_MPCORE_CFG == 1) console = 0; if(PDN_MPCORE_CFG == 1) console = 0;
//Get pressed buttons
pressed = HID_PAD; 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; section = firmLocation->section;
//If L and R are pressed, boot SysNAND with the 9.0 FIRM /* If L and R are pressed on a 9.0/2 SysNAND, or L on an updated
if((pressed & BUTTON_L1R1) == BUTTON_L1R1) mode = 0; 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 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 //Read FIRM from NAND and write to FCRAM
firmSize = console ? 0xF2000 : 0xE9000; firmSize = console ? 0xF2000 : 0xE9000;
nandFirm0((u8*)firmLocation, firmSize, console); nandFirm0((u8*)firmLocation, firmSize, console);
@ -37,18 +50,12 @@ u8 loadFirm(u8 a9lh){
} }
//Load FIRM from SD //Load FIRM from SD
else{ else{
if (!mode){ char firmPath[] = "/rei/firmware.bin";
char firmPath[] = "/rei/firmware90.bin"; char firmPath2[] = "/rei/firmware90.bin";
firmSize = fileSize(firmPath); char *pathPtr = mode ? firmPath : firmPath2;
if (!firmSize) return 1; firmSize = fileSize(pathPtr);
fileRead((u8*)firmLocation, firmPath, firmSize); if (!firmSize) return 1;
} fileRead((u8*)firmLocation, pathPtr, firmSize);
else {
char firmPath[] = "/rei/firmware.bin";
firmSize = fileSize(firmPath);
if (!firmSize) return 1;
fileRead((u8*)firmLocation, firmPath, firmSize);
}
} }
if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 1; if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 1;
@ -69,11 +76,16 @@ u8 loadEmu(void){
emuCodeOffset = 0; emuCodeOffset = 0;
//Read emunand code from SD //Read emunand code from SD
const char path[] = "/rei/emunand/emunand.bin"; char path[] = "/rei/emunand/emunand.bin";
u32 size = fileSize(path); char path2[] = "/rei/emunand/emunand90.bin";
char *pathPtr = ((!mode) & console) ? path2 : path;
u32 size = fileSize(pathPtr);
if (!size) return 1; if (!size) return 1;
getEmuCode(firmLocation, &emuCodeOffset, firmSize); if(!console | !mode) nandRedir[5] = 0xA4;
fileRead((u8*)emuCodeOffset, path, size); 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 //Find and patch emunand related offsets
u32 *pos_sdmmc = memsearch((u32*)emuCodeOffset, "SDMC", size, 4); u32 *pos_sdmmc = memsearch((u32*)emuCodeOffset, "SDMC", size, 4);
@ -88,7 +100,6 @@ u8 loadEmu(void){
*pos_header = emuHeader; *pos_header = emuHeader;
//Add emunand hooks //Add emunand hooks
if(!console) nandRedir[5] = 0xA4;
memcpy((u8*)emuRead, nandRedir, sizeof(nandRedir)); memcpy((u8*)emuRead, nandRedir, sizeof(nandRedir));
memcpy((u8*)emuWrite, nandRedir, sizeof(nandRedir)); memcpy((u8*)emuWrite, nandRedir, sizeof(nandRedir));
@ -101,8 +112,18 @@ u8 loadEmu(void){
//Patches //Patches
u8 patchFirm(void){ u8 patchFirm(void){
//If L is pressed, boot SysNAND with the SD FIRM /* If L is pressed on a 9.0/9.2 SysNAND, or L+R on a > 9.2 SysNAND,
if(mode && !(pressed & BUTTON_L1)) if (loadEmu()) return 1; 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, u32 sigOffset = 0,
sigOffset2 = 0; sigOffset2 = 0;
@ -112,8 +133,8 @@ u8 patchFirm(void){
memcpy((u8*)sigOffset, sigPat1, sizeof(sigPat1)); memcpy((u8*)sigOffset, sigPat1, sizeof(sigPat1));
memcpy((u8*)sigOffset2, sigPat2, sizeof(sigPat2)); memcpy((u8*)sigOffset2, sigPat2, sizeof(sigPat2));
//Apply FIRM reboot patch. Not needed with A9LH and N3DS. //Apply FIRM reboot patch. Not needed with A9LH and N3DS
if(!console && !a9lh && mode && if(!console && !a9lhSetup && mode &&
((fileSize("/rei/reversereboot") > 0) == (pressed & BUTTON_A))){ ((fileSize("/rei/reversereboot") > 0) == (pressed & BUTTON_A))){
u32 rebootOffset = 0, u32 rebootOffset = 0,
rebootOffset2 = 0; rebootOffset2 = 0;

View File

@ -10,14 +10,14 @@
#include "firm.h" #include "firm.h"
#include "draw.h" #include "draw.h"
u8 a9lh = 0; u8 a9lhBoot = 0;
u8 main(){ u8 main(){
mountSD(); mountSD();
//Detect A9LH mode checking PDN_GPU_CNT2 register. //Detect an A9LH boot checking PDN_GPU_CNT register
if (!*((u32*)0x10141204)) a9lh = 1; if (*((u8*)0x10141200) == 0x1) a9lhBoot = 1;
else loadSplash(); else loadSplash();
if (loadFirm(a9lh)) return 1; if (loadFirm(a9lhBoot)) return 1;
if (patchFirm()) return 1; if (patchFirm()) return 1;
launchFirm(); launchFirm();
return 0; return 0;

View File

@ -27,6 +27,7 @@ u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA5, 0x01, 0x08}; //Bran
*/ */
u8 sigPat1[2] = {0x00, 0x20}; u8 sigPat1[2] = {0x00, 0x20};
u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47}; u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};
u8 FIRMblock[4] = {0x00, 0x20, 0xC0, 0x46};
/************************************************** /**************************************************
* Functions * Functions
@ -48,4 +49,12 @@ void getReboot(void *pos, u32 size, u32 *off, u32 *off2){
*off = (u32)memsearch(pos, pattern, size, 5) + 2; *off = (u32)memsearch(pos, pattern, size, 5) + 2;
*off2 = (u32)memsearch(pos, pattern2, size, 5); *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);
} }

View File

@ -15,11 +15,13 @@ u8 mpu[0x2C];
u8 nandRedir[0x08]; u8 nandRedir[0x08];
u8 sigPat1[2]; u8 sigPat1[2];
u8 sigPat2[4]; u8 sigPat2[4];
u8 FIRMblock[4];
/************************************************** /**************************************************
* Functions * Functions
**************************************************/ **************************************************/
void getSignatures(void *pos, u32 size, u32 *off, u32 *off2); void getSignatures(void *pos, u32 size, u32 *off, u32 *off2);
void getReboot(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 #endif