Compare commits

...

6 Commits
v4.0.1 ... v4.1

10 changed files with 236 additions and 216 deletions

View File

@@ -70,7 +70,7 @@ static int file_open(IFile *file, FS_ArchiveID id, const char *path, int flags){
return IFile_Open(file, archive, ppath, flags);
}
static int patch_secureinfo(){
static int load_secureinfo(){
IFile file;
Result ret;
u64 total;
@@ -78,20 +78,6 @@ static int patch_secureinfo(){
if(secureinfo[0] == 0xFF)
return 0;
ret = file_open(&file, ARCHIVE_SDMC, "/SecureInfo_A", FS_OPEN_READ);
if(R_SUCCEEDED(ret)){
ret = IFile_Read(&file, &total, secureinfo, sizeof(secureinfo));
IFile_Close(&file);
if(R_SUCCEEDED(ret) && total == sizeof(secureinfo)){
ret = file_open(&file, ARCHIVE_NAND_RW, "/sys/SecureInfo_C", FS_OPEN_WRITE | FS_OPEN_CREATE);
if(R_SUCCEEDED(ret)){
ret = IFile_Write(&file, &total, secureinfo, sizeof(secureinfo), FS_WRITE_FLUSH);
IFile_Close(&file);
}
secureinfo[0] = 0xFF; // we repurpose this byte as status
}
}
else { // get file from NAND
ret = file_open(&file, ARCHIVE_NAND_RW, "/sys/SecureInfo_C", FS_OPEN_READ);
if(R_SUCCEEDED(ret)){
ret = IFile_Read(&file, &total, secureinfo, sizeof(secureinfo));
@@ -99,12 +85,11 @@ static int patch_secureinfo(){
if(R_SUCCEEDED(ret) && total == sizeof(secureinfo))
secureinfo[0] = 0xFF;
}
}
return ret;
}
static int open_config(){
static int load_config(){
IFile file;
Result ret;
u64 total;
@@ -122,13 +107,15 @@ static int open_config(){
}
u32 patch_code(u64 progid, u8 *code, u32 size){
if( progid == 0x0004003000008F02LL || // USA Menu
progid == 0x0004003000008202LL || // JPN Menu
progid == 0x0004003000009802LL || // EUR Menu
progid == 0x000400300000A102LL || // CHN Menu
progid == 0x000400300000A902LL || // KOR Menu
progid == 0x000400300000B102LL // TWN Menu
){
switch(progid){
case 0x0004003000008F02LL: // USA Menu
case 0x0004003000008202LL: // EUR Menu
case 0x0004003000009802LL: // JPN Menu
case 0x000400300000A102LL: // CHN Menu
case 0x000400300000A902LL: // KOR Menu
case 0x000400300000B102LL: // TWN Menu
{
static const u8 regionFreePattern[] = {
0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0, 0xE3
};
@@ -142,8 +129,11 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
regionFreePatch,
sizeof(regionFreePatch), 1
);
break;
}
else if(progid == 0x0004013000002C02LL){ // NIM
case 0x0004013000002C02LL: // NIM
{
static const u8 blockAutoUpdatesPattern[] = {
0x25, 0x79, 0x0B, 0x99
};
@@ -156,15 +146,6 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
static const u8 blockEShopUpdateCheckPatch[] = {
0x00, 0x20, 0x08, 0x60, 0x70, 0x47
};
static const u8 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)];
patch_memory(code, size,
blockAutoUpdatesPattern,
@@ -178,7 +159,18 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
blockEShopUpdateCheckPatch,
sizeof(blockEShopUpdateCheckPatch), 1
);
if(R_SUCCEEDED(patch_secureinfo())){
if(R_SUCCEEDED(load_secureinfo())){
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
@@ -188,7 +180,6 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
case 6: country = "TW"; break;
default: case 0: country = "JP"; break;
}
// patch XML response Country
memcpy(countryRespPatch,
countryRespPatchModel,
@@ -203,30 +194,34 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
sizeof(countryRespPatch), 1
);
}
break;
}
else if(
progid == 0x0004001000021000LL || // USA MSET
progid == 0x0004001000020000LL || // JPN MSET
progid == 0x0004001000022000LL || // EUR MSET
progid == 0x0004001000026000LL || // CHN MSET
progid == 0x0004001000027000LL || // KOR MSET
progid == 0x0004001000028000LL // TWN MSET
){
if(R_SUCCEEDED(open_config()) && ((config >> 5) & 0x1)){
static const u16 VerPattern[] = u"Ver.";
const u32 currentFirm = ((config >> 12) & 0x1);
const u32 currentNand = ((config >> 13) & 0x3);
case 0x0004001000021000LL: // USA MSET
case 0x0004001000020000LL: // JPN MSET
case 0x0004001000022000LL: // EUR MSET
case 0x0004001000026000LL: // CHN MSET
case 0x0004001000027000LL: // KOR MSET
case 0x0004001000028000LL: // TWN MSET
{
if(R_SUCCEEDED(load_config()) && ((config >> 5) & 1)){
static const u16 verPattern[] = u"Ver.";
const u32 currentFirm = ((config >> 12) & 1);
const u32 currentNand = ((config >> 13) & 3);
patch_memory(code, size,
VerPattern,
sizeof(VerPattern) - sizeof(u16), 0,
verPattern,
sizeof(verPattern) - sizeof(u16), 0,
currentNand ? ((currentNand == 1) ? ((currentFirm == 1) ? u" Emu" : u"Emu9") : u"Emu2") :
((currentFirm == 1) ? u" Sys" : u"Sys9"),
sizeof(VerPattern) - sizeof(u16), 1
sizeof(verPattern) - sizeof(u16), 1
);
}
break;
}
else if (progid == 0x0004013000008002LL){ // NS
case 0x0004013000008002LL: // NS
{
static const u8 stopCartUpdatesPattern[] = {
0x0C, 0x18, 0xE1, 0xD8
};
@@ -240,16 +235,17 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
stopCartUpdatesPatch,
sizeof(stopCartUpdatesPatch), 2
);
break;
}
else if(progid == 0x0004013000001702LL){ // CFG
case 0x0004013000001702LL: // CFG
{
static const u8 secureinfoSigCheckPattern[] = {
0x06, 0x46, 0x10, 0x48, 0xFC
};
static const u8 secureinfoSigCheckPatch[] = {
0x00, 0x26
};
static const u16 secureinfoFilenamePattern[] = u"SecureInfo_";
static const u16 secureinfoFilenamePatch[] = u"C";
// disable SecureInfo signature check
patch_memory(code, size,
@@ -258,7 +254,11 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
secureinfoSigCheckPatch,
sizeof(secureinfoSigCheckPatch), 1
);
if(R_SUCCEEDED(patch_secureinfo())){
if(R_SUCCEEDED(load_secureinfo())){
static const u16 secureinfoFilenamePattern[] = u"SecureInfo_";
static const u16 secureinfoFilenamePatch[] = u"C";
// use SecureInfo_C
patch_memory(code, size,
secureinfoFilenamePattern,
@@ -268,6 +268,8 @@ u32 patch_code(u64 progid, u8 *code, u32 size){
sizeof(secureinfoFilenamePatch) - sizeof(u16), 2
);
}
break;
}
}
return 0;

View File

@@ -3,7 +3,6 @@
#include "types.h"
#define HID_PAD (*(vu16 *)0x10146000 ^ 0xFFF)
#define BUTTON_B (1 << 1)
#define BUTTON_X (1 << 10)
#define BUTTON_Y (1 << 11)
#define BUTTON_SELECT (1 << 2)

View File

@@ -25,8 +25,7 @@ void main(void){
//Get pressed buttons
u16 pressed = HID_PAD;
if(((pressed & BUTTON_B) && loadPayload("/aurei/payloads/b.bin")) ||
((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) ||
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")) ||

View File

@@ -21,6 +21,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)
#define PAYLOAD_BUTTONS ((BUTTON_L1 | BUTTON_A) ^ 0xFFF)
#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)

View File

@@ -20,7 +20,7 @@ static const struct fb {
u8 *bottom;
} *const fb = (struct fb *)0x23FFFE00;
static int strlen(const char *string){
static inline int strlen(const char *string){
char *stringEnd = (char *)string;
while(*stringEnd) stringEnd++;
return stringEnd - string;

View File

@@ -8,11 +8,11 @@
#include "memory.h"
#include "fatfs/sdmmc/sdmmc.h"
void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){
void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND){
u8 *const temp = (u8 *)0x24300000;
u32 nandSize = getMMCDevice(0)->total_size;
u32 nandOffset = emuNAND == 1 ? 0 :
const u32 nandSize = getMMCDevice(0)->total_size;
u32 nandOffset = *emuNAND == 1 ? 0 :
(nandSize > 0x200000 ? 0x400000 : 0x200000);
//Check for RedNAND
@@ -28,7 +28,11 @@ 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) getEmunandSect(off, head, 1);
else if(*emuNAND == 2){
*emuNAND = 1;
getEmunandSect(off, head, emuNAND);
}
else *emuNAND = 0;
}
}
}

View File

@@ -10,7 +10,7 @@
#define NCSD_MAGIC (0x4453434E)
void getEmunandSect(u32 *off, u32 *head, u32 emuNAND);
void 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);

View File

@@ -18,7 +18,7 @@
#include "../build/patches.h"
//FIRM patches version
#define PATCH_VER 2
#define PATCH_VER 3
static firmHeader *const firm = (firmHeader *)0x24000000;
static const firmSectionHeader *section;
@@ -27,13 +27,16 @@ static const char *patchedFirms[] = { "/aurei/patched_firmware_sys.bin",
"/aurei/patched_firmware_emu.bin",
"/aurei/patched_firmware_em2.bin",
"/aurei/patched_firmware90.bin" };
static u32 firmSize,
console,
mode,
emuNAND,
a9lhSetup,
selectedFirm,
usePatchedFirm;
usePatchedFirm,
emuOffset,
emuHeader;
void setupCFW(void){
@@ -48,36 +51,41 @@ void setupCFW(void){
//Attempt to read the configuration file
const char configPath[] = "aurei/config.bin";
u32 config = 0;
u32 needConfig = fileRead(&config, configPath, 3) ? 1 : 2;
u32 config = 0,
needConfig = fileRead(&config, configPath, 3) ? 1 : 2;
//Determine if A9LH is installed and the user has an updated sysNAND
u32 updatedSys;
if(a9lhBoot || (config >> 2) & 0x1){
if(a9lhBoot || (config >> 2) & 1){
if(pressed == SAFE_MODE)
error("Using Safe Mode would brick you, or remove A9LH!");
a9lhSetup = 1;
//Check setting for > 9.2 sysNAND
updatedSys = config & 0x1;
updatedSys = config & 1;
} else{
a9lhSetup = 0;
updatedSys = 0;
}
u32 tempConfig = (PATCH_VER << 17) | (a9lhSetup << 16);
/* If booting with A9LH, it's a MCU reboot and a previous configuration exists,
try to force boot options */
if(a9lhBoot && previousFirm && needConfig == 1){
//Always force a sysNAND boot when quitting AGB_FIRM
if(previousFirm == 0x7){
mode = updatedSys ? 1 : (config >> 12) & 0x1;
if(previousFirm == 7){
mode = updatedSys ? 1 : (config >> 12) & 1;
emuNAND = 0;
//Flag to prevent multiple boot options-forcing
tempConfig |= 1 << 15;
needConfig = 0;
//Else, force the last used boot options unless A, L or R are pressed
} else if(!(pressed & OPTION_BUTTONS)){
mode = (config >> 12) & 0x1;
emuNAND = (config >> 13) & 0x3;
/* Else, force the last used boot options unless A, L or R are pressed
or the no-forcing flag is set */
} else if(!(pressed & OPTION_BUTTONS) && !((config >> 15) & 1)){
mode = (config >> 12) & 1;
emuNAND = (config >> 13) & 3;
needConfig = 0;
}
}
@@ -94,10 +102,10 @@ void setupCFW(void){
configureCFW(configPath, patchedFirms[3]);
//If screens are inited, load splash screen
if(PDN_GPU_CNT != 0x1) loadSplash();
if(PDN_GPU_CNT != 1) loadSplash();
/* If L is pressed, boot 9.0 FIRM */
mode = ((config >> 3) & 0x1) ? ((!(pressed & BUTTON_L1R1)) ? 0 : 1) :
mode = ((config >> 3) & 1) ? ((!(pressed & BUTTON_L1R1)) ? 0 : 1) :
((pressed & BUTTON_L1) ? 0 : 1);
/* If L or R aren't pressed on a 9.0/9.2 sysNAND, or the 9.0 FIRM is selected
@@ -105,33 +113,48 @@ void setupCFW(void){
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
emuNAND = (mode && ((!(pressed & BUTTON_B)) == ((config >> 4) & 0x1))) ? 2 : 1;
emuNAND = (mode && ((!(pressed & BUTTON_B)) == ((config >> 4) & 1))) ? 2 : 1;
} else emuNAND = 0;
u32 tempConfig = (PATCH_VER << 17) | (a9lhSetup << 16) | (emuNAND << 13) | (mode << 12);
/* If tha FIRM patches version is different or user switched to/from A9LH,
delete all patched FIRMs */
if((tempConfig & 0xFF0000) != (config & 0xFF0000))
deleteFirms(patchedFirms, sizeof(patchedFirms) / sizeof(char *));
}
u32 usePatchedFirmSet = ((config >> 1) & 1);
while(1){
/* Determine which patched FIRM we need to write or attempt to use (if any).
Patched 9.0 FIRM is only needed if "Use pre-patched FIRMs" is set */
selectedFirm = mode ? (emuNAND ? (emuNAND == 1 ? 2 : 3) : 1) :
(usePatchedFirmSet ? 4 : 0);
//If "Use pre-patched FIRMs" is set and the appropriate FIRM exists, use it
if(usePatchedFirmSet && fileExists(patchedFirms[selectedFirm - 1]))
usePatchedFirm = 1;
//Detect EmuNAND
else if(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;
}
}
break;
}
tempConfig |= (emuNAND << 13) | (mode << 12);
//If the boot configuration is different from previously, overwrite it
if((tempConfig & 0xFFF000) != (config & 0xFFF000)){
if(tempConfig != (config & 0xFFF000)){
//Preserve user settings (first 12 bits)
tempConfig |= config & 0xFFF;
fileWrite(&tempConfig, configPath, 3);
}
}
/* Determine which patched FIRM we need to write or attempt to use (if any).
Patched 9.0 FIRM is only needed if "Use pre-patched FIRMs" is set */
selectedFirm = mode ? (emuNAND ? (emuNAND == 1 ? 2 : 3) : 1) :
(((config >> 1) & 0x1) ? 4 : 0);
//If "Use pre-patched FIRMs" is set and the appropriate FIRM exists, use it
usePatchedFirm = (((config >> 1) & 0x1) && fileExists(patchedFirms[selectedFirm - 1])) ? 1 : 0;
}
//Load FIRM into FCRAM
void loadFirm(void){
@@ -165,18 +188,7 @@ void loadFirm(void){
}
//NAND redirection
static void loadEmu(u8 *proc9Offset){
u32 emuOffset,
emuHeader = 0,
emuRead,
emuWrite;
//Look for emuNAND
getEmunandSect(&emuOffset, &emuHeader, emuNAND);
//No emuNAND detected
if(!emuHeader) error("No emuNAND has been detected");
static inline void loadEmu(u8 *proc9Offset){
//Copy emuNAND code
void *emuCodeOffset = getEmuCode(proc9Offset);
@@ -197,6 +209,9 @@ static void loadEmu(u8 *proc9Offset){
section[2].offset + (u32)section[2].address;
//Add emunand hooks
u32 emuRead,
emuWrite;
getEmuRW(arm9Section, section[2].size, &emuRead, &emuWrite);
*(u16 *)emuRead = nandRedir[0];
*((u16 *)emuRead + 1) = nandRedir[1];
@@ -268,9 +283,11 @@ void patchFirm(void){
loaderSize;
getLoader((u8 *)firm + section[0].offset, section[0].size, &loaderOffset, &loaderSize);
//Check that the injector CXI isn't larger than the original
if(injector_size <= (int)loaderSize){
memset((void *)loaderOffset, 0, loaderSize);
memcpy((void *)loaderOffset, injector, injector_size);
//Patch content size and ExeFS size to match the repaced loader's ones
*((u32 *)loaderOffset + 0x41) = loaderSize / 0x200;
*((u32 *)loaderOffset + 0x69) = loaderSize / 0x200 - 5;
}

View File

@@ -32,7 +32,7 @@ void deinitScreens(void){
((void (*)())*arm11)();
}
if(PDN_GPU_CNT != 0x1){
if(PDN_GPU_CNT != 1){
*arm11 = (u32)ARM11;
while(*arm11);
}
@@ -82,7 +82,7 @@ void initScreens(void){
*(vu32 *)0x1040049C = 0x00000000;
// Disco register
for(vu32 i = 0; i < 256; i++)
for(u32 i = 0; i < 256; i++)
*(vu32 *)0x10400484 = 0x10101 * i;
// Bottom screen
@@ -116,7 +116,7 @@ void initScreens(void){
*(vu32 *)0x1040059C = 0x00000000;
// Disco register
for(vu32 i = 0; i < 256; i++)
for(u32 i = 0; i < 256; i++)
*(vu32 *)0x10400584 = 0x10101 * i;
// Enable backlight
@@ -143,7 +143,7 @@ void initScreens(void){
((void (*)())*arm11)();
}
if(PDN_GPU_CNT == 0x1){
if(PDN_GPU_CNT == 1){
*arm11 = (u32)ARM11;
while(*arm11);
}

View File

@@ -63,7 +63,7 @@ void configureCFW(const char *configPath, const char *firm90Path){
u32 tempConfig = 0;
fileRead(&tempConfig, configPath, 3);
for(u32 i = 0; i < optionsAmount; i++)
options[i].enabled = (tempConfig >> i) & 0x1;
options[i].enabled = (tempConfig >> i) & 1;
//Pre-select the first configuration option
u32 selectedOption = 0;
@@ -102,8 +102,7 @@ void configureCFW(const char *configPath, const char *firm90Path){
}
//If the user has been using A9LH and the "Updated SysNAND" setting changed, delete the patched 9.0 FIRM
if(((tempConfig >> 16) & 0x1) && ((tempConfig & 0x1) != options[0].enabled))
fileDelete(firm90Path);
if(((tempConfig >> 16) & 1) && ((tempConfig & 1) != options[0].enabled)) fileDelete(firm90Path);
//Preserve the last-used boot options (last 12 bits)
tempConfig &= 0xFFF000;