diff --git a/injector/source/patcher.c b/injector/source/patcher.c index f60db2d..0db8632 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -176,42 +176,6 @@ void patchCode(u64 progid, u8 *code, u32 size) sizeof(skipEshopUpdateCheckPatch), 1 ); - if(R_SUCCEEDED(loadSecureinfo())) - { - static const char countryRespPattern[] = { - 0x01, 0x20, 0x01, 0x90, 0x22, 0x46, 0x06, 0x9B - }; - static const char countryRespPatchModel[] = { - 0x06, 0x9A, 0x03, 0x20, 0x90, 0x47, 0x55, 0x21, 0x01, 0x70, 0x53, 0x21, 0x41, 0x70, 0x00, 0x21, - 0x81, 0x70, 0x60, 0x61, 0x00, 0x20 - }; - const char *country; - char countryRespPatch[sizeof(countryRespPatchModel)]; - - switch(secureinfo[0x100]) - { - case 1: country = "US"; break; - case 2: country = "GB"; break; // sorry rest-of-Europe, you have to change this - case 4: country = "CN"; break; - case 5: country = "KR"; break; - case 6: country = "TW"; break; - default: case 0: country = "JP"; break; - } - //Patch XML response Country - memcpy(countryRespPatch, - countryRespPatchModel, - sizeof(countryRespPatchModel) - ); - countryRespPatch[6] = country[0]; - countryRespPatch[10] = country[1]; - patchMemory(code, size, - countryRespPattern, - sizeof(countryRespPattern), 0, - countryRespPatch, - sizeof(countryRespPatch), 1 - ); - } - break; } diff --git a/loader/source/buttons.h b/loader/source/buttons.h index 3d3f589..e6897e6 100644 --- a/loader/source/buttons.h +++ b/loader/source/buttons.h @@ -5,8 +5,8 @@ #define HID_PAD (*(vu32 *)0x10146000 ^ 0xFFF) #define BUTTON_X (1 << 10) #define BUTTON_Y (1 << 11) +#define BUTTON_R1 (1 << 8) #define BUTTON_SELECT (1 << 2) -#define BUTTON_START (1 << 3) #define BUTTON_RIGHT (1 << 4) #define BUTTON_LEFT (1 << 5) #define BUTTON_UP (1 << 6) diff --git a/loader/source/main.c b/loader/source/main.c index 8573d0b..bf36e32 100644 --- a/loader/source/main.c +++ b/loader/source/main.c @@ -29,14 +29,14 @@ void main(void) //Get pressed buttons u32 pressed = HID_PAD; - if(((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) || - ((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) || - ((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) || - ((pressed & BUTTON_START) && loadPayload("/aurei/payloads/start.bin")) || - ((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) || + if(((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) || ((pressed & BUTTON_LEFT) && loadPayload("/aurei/payloads/left.bin")) || ((pressed & BUTTON_UP) && loadPayload("/aurei/payloads/up.bin")) || ((pressed & BUTTON_DOWN) && loadPayload("/aurei/payloads/down.bin")) || + ((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) || + ((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) || + ((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) || + ((pressed & BUTTON_R1) && loadPayload("/aurei/payloads/r.bin")) || loadPayload("/aurei/payloads/default.bin")) ((void (*)())PAYLOAD_ADDRESS)(); } \ No newline at end of file diff --git a/source/buttons.h b/source/buttons.h index ea7de82..bf31c33 100644 --- a/source/buttons.h +++ b/source/buttons.h @@ -8,19 +8,22 @@ #include "types.h" -#define HID_PAD (*(vu32 *)0x10146000 ^ 0xFFF) -#define BUTTON_R1 (1 << 8) -#define BUTTON_L1 (1 << 9) -#define BUTTON_A 1 -#define BUTTON_B (1 << 1) -#define BUTTON_SELECT (1 << 2) -#define BUTTON_START (1 << 3) -#define BUTTON_RIGHT (1 << 4) -#define BUTTON_LEFT (1 << 5) -#define BUTTON_UP (1 << 6) -#define BUTTON_DOWN (1 << 7) -#define BUTTON_L1R1 ((1 << 8) | (1 << 9)) -#define SAFE_MODE (BUTTON_L1R1 | BUTTON_A | BUTTON_UP) -#define OPTION_BUTTONS (BUTTON_L1R1 | BUTTON_A | BUTTON_SELECT) -#define PAYLOAD_BUTTONS ((BUTTON_L1 | BUTTON_A | BUTTON_B) ^ 0xFFF) -#define MENU_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_A | BUTTON_START) \ No newline at end of file +#define HID_PAD (*(vu32 *)0x10146000 ^ 0xFFF) +#define BUTTON_R1 (1 << 8) +#define BUTTON_L1 (1 << 9) +#define BUTTON_A 1 +#define BUTTON_B (1 << 1) +#define BUTTON_X (1 << 10) +#define BUTTON_Y (1 << 11) +#define BUTTON_SELECT (1 << 2) +#define BUTTON_START (1 << 3) +#define BUTTON_RIGHT (1 << 4) +#define BUTTON_LEFT (1 << 5) +#define BUTTON_UP (1 << 6) +#define BUTTON_DOWN (1 << 7) +#define BUTTON_L1R1 (BUTTON_R1 | BUTTON_L1) +#define SAFE_MODE (BUTTON_L1R1 | 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_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 93138f2..0fc04dc 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -8,7 +8,7 @@ #include "memory.h" #include "fatfs/sdmmc/sdmmc.h" -void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND) +u32 getEmunandSect(u32 *off, u32 *head, u32 *emuNAND) { u8 *const temp = (u8 *)0x24300000; @@ -33,14 +33,15 @@ void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND) *head = nandOffset + nandSize; } //Fallback to the first emuNAND if there's no second one - else if(*emuNAND == 2) + else { - *emuNAND = 1; - getEmunandSect(off, head, emuNAND); + (*emuNAND)--; + if(*emuNAND) getEmunandSect(off, head, emuNAND); + return 0; } - else *emuNAND = 0; } } + return 1; } u32 getSDMMC(u8 *pos, u32 size) diff --git a/source/emunand.h b/source/emunand.h index 459cadb..c8bf302 100644 --- a/source/emunand.h +++ b/source/emunand.h @@ -10,7 +10,7 @@ #define NCSD_MAGIC (0x4453434E) -void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND); +u32 getEmunandSect(u32 *off, u32 *head, u32 *emuNAND); u32 getSDMMC(u8 *pos, u32 size); void getEmuRW(u8 *pos, u32 size, u32 *readOff, u32 *writeOff); u32 *getMPU(u8 *pos, u32 size); diff --git a/source/firm.c b/source/firm.c index 0436005..bbd40c6 100755 --- a/source/firm.c +++ b/source/firm.c @@ -102,7 +102,7 @@ void setupCFW(void) } /* Else, force the last used boot options unless A/L/R/SELECT are pressed or the no-forcing flag is set */ - else if(!(pressed & OPTION_BUTTONS) && !((config >> 15) & 1)) + else if(!(pressed & OVERRIDE_BUTTONS) && !((config >> 15) & 1)) { mode = (config >> 12) & 1; emuNAND = (config >> 13) & 3; @@ -115,7 +115,8 @@ void setupCFW(void) { /* If L and one of the payload buttons are pressed, and if not using A9LH the Safe Mode combo is not pressed, chainload an external payload */ - if((pressed & BUTTON_L1) && (pressed & PAYLOAD_BUTTONS) && pressed != SAFE_MODE) + if(((pressed & SINGLE_PAYLOAD_BUTTONS) || ((pressed & BUTTON_L1) && (pressed & L_PAYLOAD_BUTTONS))) + && pressed != SAFE_MODE) loadPayload(); //If no configuration file exists or SELECT is held, load configuration menu @@ -134,7 +135,8 @@ void setupCFW(void) or R is pressed on a > 9.2 sysNAND, boot emuNAND */ if((updatedSys && (!mode || (pressed & BUTTON_R1))) || (!updatedSys && mode && !(pressed & BUTTON_R1))) { - //If not 9.0 FIRM and B is pressed, attempt booting the second emuNAND + /* If not 9.0 FIRM and the second emuNAND is set as default and B isn't pressed, or vice-versa, + attempt to boot it */ emuNAND = (mode && ((!(pressed & BUTTON_B)) == ((config >> 4) & 1))) ? 2 : 1; } else emuNAND = 0; @@ -158,17 +160,12 @@ void setupCFW(void) if(usePatchedFirmSet && fileExists(patchedFirms[selectedFirm - 1])) usePatchedFirm = 1; - else if(emuNAND) + /* If the user is booting EmuNAND but the chosen one is not found, + force 9.6/10.x FIRM and re-detect the patched FIRMs */ + else if(emuNAND && !getEmunandSect(&emuOffset, &emuHeader, &emuNAND)) { - //Detect EmuNAND - getEmunandSect(&emuOffset, &emuHeader, &emuNAND); - - //If none exists, force SysNAND + 9.6/10.x FIRM and re-detect patched FIRMs - if(!emuNAND) - { - mode = 1; - continue; - } + mode = 1; + continue; } break; } @@ -205,7 +202,8 @@ void loadFirm(void) const char *path = usePatchedFirm ? patchedFirms[selectedFirm - 1] : (mode ? "/aurei/firmware.bin" : "/aurei/firmware90.bin"); firmSize = fileSize(path); - if(!firmSize) error("aurei/firmware(90).bin doesn't exist"); + if(!firmSize) error(mode ? "aurei/firmware.bin doesn't exist" : + "aurei/firmware90.bin doesn't exist"); fileRead(firm, path, firmSize); } @@ -213,18 +211,24 @@ void loadFirm(void) //Check that the loaded FIRM matches the console if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) - error("aurei/firmware(90).bin doesn't match this\nconsole, or it's encrypted"); + error(mode ? "aurei/firmware.bin doesn't match this console,\nor it's encrypted" : + "aurei/firmware90.bin doesn't match this console,\nor it's encrypted"); arm9Section = (u8 *)firm + section[2].offset; - if(console && !usePatchedFirm) decryptArm9Bin(arm9Section, mode); + //On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip arm9loader + if(console && !usePatchedFirm) + { + decryptArm9Bin(arm9Section, mode); + firm->arm9Entry = (u8 *)0x801B01C; + } } -static inline void patchTwlAgb(u32 mode) +static inline void patchTwlAgb(u32 whichFirm) { static firmHeader *const twlAgbFirm = (firmHeader *)0x25000000; - const char *path = mode ? "/aurei/firmware_agb.bin" : "/aurei/firmware_twl.bin"; + const char *path = whichFirm ? "/aurei/firmware_agb.bin" : "/aurei/firmware_twl.bin"; u32 size = fileSize(path); //Skip patching if the file doesn't exist @@ -236,10 +240,15 @@ static inline void patchTwlAgb(u32 mode) //Check that the loaded FIRM matches the console if((((u32)twlAgbSection[3].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) - error(mode ? "aurei/firmware_agb.bin doesn't match this\nconsole, or it's encrypted" : - "aurei/firmware_twl.bin doesn't match this\nconsole, or it's encrypted"); + error(whichFirm ? "aurei/firmware_agb.bin doesn't match this\nconsole, or it's encrypted" : + "aurei/firmware_twl.bin doesn't match this\nconsole, or it's encrypted"); - if(console) decryptArm9Bin((u8 *)twlAgbFirm + twlAgbSection[3].offset, 0); + //On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip arm9loader + if(console) + { + decryptArm9Bin((u8 *)twlAgbFirm + twlAgbSection[3].offset, 0); + twlAgbFirm->arm9Entry = (u8 *)0x801301C; + } struct patchData { u32 offset[2]; @@ -269,9 +278,9 @@ static inline void patchTwlAgb(u32 mode) /* Calculate the amount of patches to apply. Only count the splash screen patch for AGB_FIRM if the matching option was enabled (keep it as last) */ - u32 numPatches = mode ? (sizeof(agbPatches) / sizeof(struct patchData)) - !((config >> 6) & 1) : - (sizeof(twlPatches) / sizeof(struct patchData)); - const struct patchData *patches = mode ? agbPatches : twlPatches; + u32 numPatches = whichFirm ? (sizeof(agbPatches) / sizeof(struct patchData)) - !((config >> 6) & 1) : + (sizeof(twlPatches) / sizeof(struct patchData)); + const struct patchData *patches = whichFirm ? agbPatches : twlPatches; //Patch for(u32 i = 0; i < numPatches; i++) @@ -289,10 +298,7 @@ static inline void patchTwlAgb(u32 mode) } } - //Patch ARM9 entrypoint on N3DS to skip arm9loader - if(console) twlAgbFirm->arm9Entry = (u8 *)0x801301C; - - fileWrite(twlAgbFirm, mode ? patchedFirms[5] : patchedFirms[4], size); + fileWrite(twlAgbFirm, whichFirm ? patchedFirms[5] : patchedFirms[4], size); } //NAND redirection @@ -380,9 +386,12 @@ static inline void injectLoader(void) //Patches void patchFirm(void) { - //Only patch AGB_FIRM/TWL_FIRM if the patched ones don't already exist - if(!fileExists(patchedFirms[4])) patchTwlAgb(0); - if(!fileExists(patchedFirms[5])) patchTwlAgb(1); + if(mode) + { + //Only patch AGB_FIRM/TWL_FIRM if the patched ones don't already exist + if(!fileExists(patchedFirms[4])) patchTwlAgb(0); + if(!fileExists(patchedFirms[5])) patchTwlAgb(1); + } //Skip patching if(usePatchedFirm) return; @@ -419,9 +428,6 @@ void patchFirm(void) //Replace the FIRM loader with the injector injectLoader(); - //Patch ARM9 entrypoint on N3DS to skip arm9loader - if(console) firm->arm9Entry = (u8 *)0x801B01C; - //Write patched FIRM to SD if needed if(selectedFirm) if(!fileWrite(firm, patchedFirms[selectedFirm - 1], firmSize))