Skip to content

Commit

Permalink
Added "updated sysNAND" mode, FIRM writes patch, propered emuNAND cod…
Browse files Browse the repository at this point in the history
…e location

Thanks to delebile for the patch!
  • Loading branch information
AuroraWright committed Feb 19, 2016
1 parent 8872a24 commit b4d94da
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 47 deletions.
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)"
Expand All @@ -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 $<
Expand Down
8 changes: 0 additions & 8 deletions source/emunand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
1 change: 0 additions & 1 deletion source/emunand.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
73 changes: 47 additions & 26 deletions source/firm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,47 @@ 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);
if(memcmp((u8*)firmLocation, "FIRM", 4) != 0) return 1;
}
//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;

Expand All @@ -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);
Expand All @@ -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));

Expand All @@ -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;
Expand All @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions source/patches.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
2 changes: 2 additions & 0 deletions source/patches.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit b4d94da

Please sign in to comment.