Added "updated sysNAND" mode, FIRM writes patch, propered emuNAND code location
Thanks to delebile for the patch!
This commit is contained in:
parent
8872a243fc
commit
b4d94da531
16
Makefile
16
Makefile
@ -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 $<
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
@ -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
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
@ -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
|
Reference in New Issue
Block a user