diff --git a/source/crypto.c b/source/crypto.c index 0bb6fdc..bf7de66 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -243,8 +243,10 @@ static void getNandCTR(u8 *buf, u32 console){ void nandFirm0(u8 *outbuf, u32 size, u32 console){ u8 CTR[0x10]; getNandCTR(CTR, console); - aes_advctr(CTR, 0x0B130000/0x10, AES_INPUT_BE | AES_INPUT_NORMAL); + sdmmc_nand_readsectors(0x0B130000 / 0x200, size / 0x200, outbuf); + + aes_advctr(CTR, 0x0B130000/0x10, AES_INPUT_BE | AES_INPUT_NORMAL); aes_use_keyslot(0x06); aes(outbuf, outbuf, size / AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); } diff --git a/source/emunand.c b/source/emunand.c index c892a35..eb26f1b 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -29,23 +29,12 @@ void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){ } } -void getSDMMC(void *pos, u32 *off, u32 size){ +u32 getSDMMC(void *pos, u32 size){ //Look for struct code const unsigned char pattern[] = {0x21, 0x20, 0x18, 0x20}; - *off = (u32)memsearch(pos, pattern, size, 4) - 1; - - //Get DCD values - u8 buf[4]; - u32 addr = 0, - additive = 0, - p; - memcpy(buf, (void *)(*off+0x0A), 4); - for (p = 0; p < 4; p++) addr |= ((u32) buf[p]) << (8 * p); - memcpy(buf, (void *)(*off+0x0E), 4); - for (p = 0; p < 4; p++) additive |= ((u32) buf[p]) << (8 * p); - - //Return result - *off = addr + additive; + const u8 *off = (u8 *)memsearch(pos, pattern, size, 4) - 1; + + return *(u32 *)(off+0x0A) + *(u32 *)(off+0x0E); } void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){ @@ -56,17 +45,16 @@ void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){ *readOff = (u32)memsearch((void *)(*writeOff - 0x1000), pattern, 0x1000, 4) - 6; } -void getMPU(void *pos, u32 *off, u32 size){ +void *getMPU(void *pos, u32 size){ //Look for MPU pattern const unsigned char pattern[] = {0x03, 0x00, 0x24, 0x00}; - *off = (u32)memsearch(pos, pattern, size, 4); + return memsearch(pos, pattern, size, 4); } -void getEmuCode(void *pos, u32 *off, u32 size){ - u8 *proc9 = (u8 *)memsearch(pos, "ess9", size, 4); +u8 *getEmuCode(void *pos, u32 size, u8 *proc9Offset){ const unsigned char pattern[] = {0x00, 0xFF, 0xFF, 0xFF}; //Looking for the last spot before Process9 - *off = (u32)memsearch(pos, pattern, size - (size - (u32)(proc9 - (u8 *)pos)), 4) + 0xD; + return (u8 *)memsearch(pos, pattern, size - (size - (u32)(proc9Offset - (u8 *)pos)), 4) + 0xD; } \ No newline at end of file diff --git a/source/emunand.h b/source/emunand.h index c10465b..add0887 100644 --- a/source/emunand.h +++ b/source/emunand.h @@ -11,7 +11,7 @@ #define NCSD_MAGIC (0x4453434E) void getEmunandSect(u32 *off, u32 *head, u32 emuNAND); -void getSDMMC(void *pos, u32 *off, u32 size); +u32 getSDMMC(void *pos, 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); \ No newline at end of file +void *getMPU(void *pos, u32 size); +u8 *getEmuCode(void *pos, u32 size, u8 *proc9Offset); \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 92b8e33..68723a7 100755 --- a/source/firm.c +++ b/source/firm.c @@ -15,14 +15,13 @@ static firmHeader *const firmLocation = (firmHeader *)0x24000000; static const firmSectionHeader *section; -static u32 firmSize = 0, +static u32 firmSize, mode = 1, console = 1, emuNAND = 0, a9lhSetup = 0, - updatedSys = 0, usePatchedFirm = 0; -static u16 pressed; +static u8 *arm9Section; static const char *firmPathPatched = NULL; void setupCFW(void){ @@ -31,6 +30,7 @@ void setupCFW(void){ u32 a9lhBoot = (PDN_SPI_CNT == 0x0) ? 1 : 0; //Retrieve the last booted FIRM u8 previousFirm = CFG_BOOTENV; + u32 updatedSys = 0; u32 overrideConfig = 0; const char lastConfigPath[] = "aurei/lastbootcfg"; @@ -38,7 +38,7 @@ void setupCFW(void){ if(PDN_MPCORE_CFG == 1) console = 0; //Get pressed buttons - pressed = HID_PAD; + u16 pressed = HID_PAD; //Determine if A9LH is installed if(a9lhBoot || fileExists("/aurei/installeda9lh")){ @@ -104,7 +104,7 @@ void setupCFW(void){ } } -//Load firm into FCRAM +//Load FIRM into FCRAM u32 loadFirm(void){ //If not using an A9LH setup or the patched FIRM, load 9.0 FIRM from NAND @@ -129,54 +129,57 @@ u32 loadFirm(void){ //Check that the loaded FIRM matches the console if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 0; + arm9Section = (u8 *)firmLocation + section[2].offset; + if(console && !usePatchedFirm) - decArm9Bin((u8 *)firmLocation + section[2].offset, mode); + decArm9Bin(arm9Section, mode); return 1; } -//Nand redirection -static u32 loadEmu(void){ +//NAND redirection +static u32 loadEmu(u8 *proc9Offset){ u32 emuOffset = 1, emuHeader = 1, emuRead, - emuWrite, - sdmmcOffset, - mpuOffset, - emuCodeOffset; + emuWrite; //Read emunand code from SD const char path[] = "/aurei/emunand/emunand.bin"; u32 size = fileSize(path); if(!size) return 0; - getEmuCode(firmLocation, &emuCodeOffset, firmSize); - fileRead((u8 *)emuCodeOffset, path, size); + u8 *emuCodeOffset = getEmuCode(arm9Section, section[2].size, proc9Offset); + fileRead(emuCodeOffset, path, size); - //Find and patch emunand related offsets + //Look for emuNAND getEmunandSect(&emuOffset, &emuHeader, emuNAND); + //No emuNAND detected if(!emuHeader) return 0; - getSDMMC(firmLocation, &sdmmcOffset, firmSize); - getEmuRW(firmLocation, firmSize, &emuRead, &emuWrite); - getMPU(firmLocation, &mpuOffset, firmSize); - u32 *pos_offset = (u32 *)memsearch((void *)emuCodeOffset, "NAND", size, 4); - u32 *pos_header = (u32 *)memsearch((void *)emuCodeOffset, "NCSD", size, 4); - u32 *pos_sdmmc = (u32 *)memsearch((void *)emuCodeOffset, "SDMC", size, 4); - *pos_sdmmc = sdmmcOffset; + + //Place emuNAND data + u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", size, 4); + u32 *pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", size, 4); *pos_offset = emuOffset; *pos_header = emuHeader; + //Find and place the SDMMC struct + u32 *pos_sdmmc = (u32 *)memsearch(emuCodeOffset, "SDMC", size, 4); + *pos_sdmmc = getSDMMC(arm9Section, section[2].size); + //Calculate offset for the hooks - *(u32 *)(nandRedir + 4) = emuCodeOffset - (u32)firmLocation - + *(u32 *)(nandRedir + 4) = (u32)emuCodeOffset - (u32)firmLocation - section[2].offset + (u32)section[2].address; //Add emunand hooks + getEmuRW(arm9Section, section[2].size, &emuRead, &emuWrite); memcpy((void *)emuRead, nandRedir, sizeof(nandRedir)); memcpy((void *)emuWrite, nandRedir, sizeof(nandRedir)); //Set MPU for emu code region - memcpy((void *)mpuOffset, mpu, sizeof(mpu)); + void *mpuOffset = getMPU(arm9Section, section[2].size); + memcpy(mpuOffset, mpu, sizeof(mpu)); return 1; } @@ -187,15 +190,39 @@ u32 patchFirm(void){ //Skip patching if(usePatchedFirm) return 1; - //Apply emuNAND patches - if(emuNAND){ - if(!loadEmu()) return 0; + if(mode || emuNAND){ + //Find the Process9 NCCH location + u8 *proc9Offset = getProc9(arm9Section, section[2].size); + + //Apply emuNAND patches + if(emuNAND) + if(!loadEmu(proc9Offset)) return 0; + + //Patch FIRM reboots, not on 9.0 FIRM as it breaks firmlaunchhax + if(mode){ + //Read reboot code from SD + const char path[] = "/aurei/reboot/reboot.bin"; + u32 size = fileSize(path); + if(!size) return 0; + u8 *rebootOffset = getReboot(arm9Section, section[2].size); + fileRead(rebootOffset, path, size); + + //Calculate the fOpen offset and put it in the right location + u32 *pos_fopen = (u32 *)memsearch(rebootOffset, "OPEN", size, 4); + *pos_fopen = getfOpen(arm9Section, section[2].size, proc9Offset); + + //Patch path for emuNAND-patched FIRM + if(emuNAND){ + void *pos_path = memsearch(rebootOffset, L"sy", size, 4); + memcpy(pos_path, emuNAND == 1 ? L"emu" : L"em2", 5); + } + } } - else if(a9lhSetup){ + + if(a9lhSetup && !emuNAND){ //Patch FIRM partitions writes on SysNAND to protect A9LH - u32 writeOffset = 0; - getFIRMWrite(firmLocation, firmSize, &writeOffset); - memcpy((void *)writeOffset, FIRMblock, sizeof(FIRMblock)); + void *writeOffset = getFIRMWrite(arm9Section, section[2].size); + memcpy(writeOffset, FIRMblock, sizeof(FIRMblock)); } //Disable signature checks @@ -210,31 +237,6 @@ u32 patchFirm(void){ if(console) firmLocation->arm9Entry = (u8 *)0x801B01C; - //Patch FIRM reboots, not on 9.0 FIRM as it breaks firmlaunchhax - if(mode){ - u32 rebootOffset, - fOpenOffset; - - //Read reboot code from SD - const char path[] = "/aurei/reboot/reboot.bin"; - u32 size = fileSize(path); - if(!size) return 0; - getReboot(firmLocation, firmSize, &rebootOffset); - fileRead((u8 *)rebootOffset, path, size); - - //Calculate the fOpen offset and put it in the right location - getfOpen(firmLocation, firmSize, &fOpenOffset); - u32 *pos_fopen = (u32 *)memsearch((void *)rebootOffset, "OPEN", size, 4); - *pos_fopen = fOpenOffset; - - //Patch path for emuNAND-patched FIRM - if(emuNAND){ - void *pos_path = memsearch((void *)rebootOffset, L"sy", size, 4); - const wchar_t *path = emuNAND == 1 ? L"emu" : L"em2"; - memcpy(pos_path, path, 5); - } - } - //Write patched FIRM to SD if needed if(firmPathPatched) if(!fileWrite((u8 *)firmLocation, firmPathPatched, firmSize)) return 0; @@ -244,12 +246,12 @@ u32 patchFirm(void){ void launchFirm(void){ - if(console && mode) setKeyXs((u8 *)firmLocation + section[2].offset); + if(console && mode) setKeyXs(arm9Section); //Copy firm partitions to respective memory locations memcpy(section[0].address, (u8 *)firmLocation + section[0].offset, section[0].size); memcpy(section[1].address, (u8 *)firmLocation + section[1].offset, section[1].size); - memcpy(section[2].address, (u8 *)firmLocation + section[2].offset, section[2].size); + memcpy(section[2].address, arm9Section, section[2].size); //Run ARM11 screen stuff vu32 *const arm11 = (u32 *)0x1FFFFFF8; diff --git a/source/patches.c b/source/patches.c index 9fb89f1..2b619ce 100644 --- a/source/patches.c +++ b/source/patches.c @@ -25,12 +25,14 @@ const u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47}; const u8 FIRMblock[4] = {0x00, 0x20, 0xC0, 0x46}; -const u8 emuInstr[5] = {0xA5, 0x01, 0x08, 0x30, 0xA5}; - /************************************************** * Functions **************************************************/ +u8 *getProc9(void *pos, u32 size){ + return (u8 *)memsearch(pos, "ess9", size, 4); +} + void getSignatures(void *pos, u32 size, u32 *off, u32 *off2){ //Look for signature checks const unsigned char pattern[] = {0xC0, 0x1C, 0x76, 0xE7}; @@ -40,26 +42,26 @@ void getSignatures(void *pos, u32 size, u32 *off, u32 *off2){ *off2 = (u32)memsearch(pos, pattern2, size, 4) - 1; } -void getReboot(void *pos, u32 size, u32 *off){ +u8 *getReboot(void *pos, u32 size){ //Look for FIRM reboot code const unsigned char pattern[] = {0xDE, 0x1F, 0x8D, 0xE2}; - *off = (u32)memsearch(pos, pattern, size, 4) - 0x10; + return (u8 *)memsearch(pos, pattern, size, 4) - 0x10; } -void getfOpen(void *pos, u32 size, u32 *off){ +u32 getfOpen(void *pos, u32 size, u8 *proc9Offset){ //Calculate fOpen - u32 p9addr = *(u32 *)((u8 *)memsearch(pos, "ess9", size, 4) + 0xC); - u32 p9off = (u32)memsearch(pos, "code", size, 4) + 0x1FF; + u32 p9MemAddr = *(u32 *)(proc9Offset + 0xC); + u32 p9CodeOff = (u32)memsearch(pos, "code", size, 4) + 0x1FF; const unsigned char pattern[] = {0xB0, 0x04, 0x98, 0x0D}; - *off = (u32)memsearch(pos, pattern, size, 4) - 2 - p9off + p9addr; + return (u32)memsearch(pos, pattern, size, 4) - 2 - p9CodeOff + p9MemAddr; } -void getFIRMWrite(void *pos, u32 size, u32 *off){ +void *getFIRMWrite(void *pos, u32 size){ //Look for FIRM writing code u8 *firmwrite = (u8 *)memsearch(pos, "exe:", size, 4); const unsigned char pattern[] = {0x00, 0x28, 0x01, 0xDA}; - *off = (u32)memsearch(firmwrite - 0x100, pattern, 0x100, 4); + return memsearch(firmwrite - 0x100, pattern, 0x100, 4); } \ No newline at end of file diff --git a/source/patches.h b/source/patches.h index fb7d0e4..db8beef 100644 --- a/source/patches.h +++ b/source/patches.h @@ -16,12 +16,12 @@ u8 nandRedir[0x08]; const u8 sigPat1[2]; const u8 sigPat2[4]; const u8 FIRMblock[4]; -const u8 emuInstr[5]; /************************************************** * Functions **************************************************/ +u8 *getProc9(void *pos, u32 size); void getSignatures(void *pos, u32 size, u32 *off, u32 *off2); -void getReboot(void *pos, u32 size, u32 *off); -void getfOpen(void *pos, u32 size, u32 *off); -void getFIRMWrite(void *pos, u32 size, u32 *off); \ No newline at end of file +u8 *getReboot(void *pos, u32 size); +u32 getfOpen(void *pos, u32 size, u8 *proc9Offset); +void *getFIRMWrite(void *pos, u32 size); \ No newline at end of file