Clean-up, optimized the SDMMC struct searching function, lots of useless casts removed, Process9 only gets searched once

This commit is contained in:
Aurora 2016-03-21 18:56:41 +01:00
parent cb84a6c7ea
commit 1f5b824c27
6 changed files with 90 additions and 96 deletions

View File

@ -243,8 +243,10 @@ static void getNandCTR(u8 *buf, u32 console){
void nandFirm0(u8 *outbuf, u32 size, u32 console){ void nandFirm0(u8 *outbuf, u32 size, u32 console){
u8 CTR[0x10]; u8 CTR[0x10];
getNandCTR(CTR, console); getNandCTR(CTR, console);
aes_advctr(CTR, 0x0B130000/0x10, AES_INPUT_BE | AES_INPUT_NORMAL);
sdmmc_nand_readsectors(0x0B130000 / 0x200, size / 0x200, outbuf); sdmmc_nand_readsectors(0x0B130000 / 0x200, size / 0x200, outbuf);
aes_advctr(CTR, 0x0B130000/0x10, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x06); aes_use_keyslot(0x06);
aes(outbuf, outbuf, size / AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(outbuf, outbuf, size / AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
} }

View File

@ -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 //Look for struct code
const unsigned char pattern[] = {0x21, 0x20, 0x18, 0x20}; const unsigned char pattern[] = {0x21, 0x20, 0x18, 0x20};
*off = (u32)memsearch(pos, pattern, size, 4) - 1; const u8 *off = (u8 *)memsearch(pos, pattern, size, 4) - 1;
//Get DCD values return *(u32 *)(off+0x0A) + *(u32 *)(off+0x0E);
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;
} }
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){ 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; *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 //Look for MPU pattern
const unsigned char pattern[] = {0x03, 0x00, 0x24, 0x00}; 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 *getEmuCode(void *pos, u32 size, u8 *proc9Offset){
u8 *proc9 = (u8 *)memsearch(pos, "ess9", size, 4);
const unsigned char pattern[] = {0x00, 0xFF, 0xFF, 0xFF}; const unsigned char pattern[] = {0x00, 0xFF, 0xFF, 0xFF};
//Looking for the last spot before Process9 //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;
} }

View File

@ -11,7 +11,7 @@
#define NCSD_MAGIC (0x4453434E) #define NCSD_MAGIC (0x4453434E)
void getEmunandSect(u32 *off, u32 *head, u32 emuNAND); 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 getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff);
void getMPU(void *pos, u32 *off, u32 size); void *getMPU(void *pos, u32 size);
void getEmuCode(void *pos, u32 *off, u32 size); u8 *getEmuCode(void *pos, u32 size, u8 *proc9Offset);

View File

@ -15,14 +15,13 @@
static firmHeader *const firmLocation = (firmHeader *)0x24000000; static firmHeader *const firmLocation = (firmHeader *)0x24000000;
static const firmSectionHeader *section; static const firmSectionHeader *section;
static u32 firmSize = 0, static u32 firmSize,
mode = 1, mode = 1,
console = 1, console = 1,
emuNAND = 0, emuNAND = 0,
a9lhSetup = 0, a9lhSetup = 0,
updatedSys = 0,
usePatchedFirm = 0; usePatchedFirm = 0;
static u16 pressed; static u8 *arm9Section;
static const char *firmPathPatched = NULL; static const char *firmPathPatched = NULL;
void setupCFW(void){ void setupCFW(void){
@ -31,6 +30,7 @@ void setupCFW(void){
u32 a9lhBoot = (PDN_SPI_CNT == 0x0) ? 1 : 0; u32 a9lhBoot = (PDN_SPI_CNT == 0x0) ? 1 : 0;
//Retrieve the last booted FIRM //Retrieve the last booted FIRM
u8 previousFirm = CFG_BOOTENV; u8 previousFirm = CFG_BOOTENV;
u32 updatedSys = 0;
u32 overrideConfig = 0; u32 overrideConfig = 0;
const char lastConfigPath[] = "aurei/lastbootcfg"; const char lastConfigPath[] = "aurei/lastbootcfg";
@ -38,7 +38,7 @@ void setupCFW(void){
if(PDN_MPCORE_CFG == 1) console = 0; if(PDN_MPCORE_CFG == 1) console = 0;
//Get pressed buttons //Get pressed buttons
pressed = HID_PAD; u16 pressed = HID_PAD;
//Determine if A9LH is installed //Determine if A9LH is installed
if(a9lhBoot || fileExists("/aurei/installeda9lh")){ if(a9lhBoot || fileExists("/aurei/installeda9lh")){
@ -104,7 +104,7 @@ void setupCFW(void){
} }
} }
//Load firm into FCRAM //Load FIRM into FCRAM
u32 loadFirm(void){ u32 loadFirm(void){
//If not using an A9LH setup or the patched FIRM, load 9.0 FIRM from NAND //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 //Check that the loaded FIRM matches the console
if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 0; if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) return 0;
arm9Section = (u8 *)firmLocation + section[2].offset;
if(console && !usePatchedFirm) if(console && !usePatchedFirm)
decArm9Bin((u8 *)firmLocation + section[2].offset, mode); decArm9Bin(arm9Section, mode);
return 1; return 1;
} }
//Nand redirection //NAND redirection
static u32 loadEmu(void){ static u32 loadEmu(u8 *proc9Offset){
u32 emuOffset = 1, u32 emuOffset = 1,
emuHeader = 1, emuHeader = 1,
emuRead, emuRead,
emuWrite, emuWrite;
sdmmcOffset,
mpuOffset,
emuCodeOffset;
//Read emunand code from SD //Read emunand code from SD
const char path[] = "/aurei/emunand/emunand.bin"; const char path[] = "/aurei/emunand/emunand.bin";
u32 size = fileSize(path); u32 size = fileSize(path);
if(!size) return 0; if(!size) return 0;
getEmuCode(firmLocation, &emuCodeOffset, firmSize); u8 *emuCodeOffset = getEmuCode(arm9Section, section[2].size, proc9Offset);
fileRead((u8 *)emuCodeOffset, path, size); fileRead(emuCodeOffset, path, size);
//Find and patch emunand related offsets //Look for emuNAND
getEmunandSect(&emuOffset, &emuHeader, emuNAND); getEmunandSect(&emuOffset, &emuHeader, emuNAND);
//No emuNAND detected //No emuNAND detected
if(!emuHeader) return 0; if(!emuHeader) return 0;
getSDMMC(firmLocation, &sdmmcOffset, firmSize);
getEmuRW(firmLocation, firmSize, &emuRead, &emuWrite); //Place emuNAND data
getMPU(firmLocation, &mpuOffset, firmSize); u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", size, 4);
u32 *pos_offset = (u32 *)memsearch((void *)emuCodeOffset, "NAND", size, 4); u32 *pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", 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;
*pos_offset = emuOffset; *pos_offset = emuOffset;
*pos_header = emuHeader; *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 //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; section[2].offset + (u32)section[2].address;
//Add emunand hooks //Add emunand hooks
getEmuRW(arm9Section, section[2].size, &emuRead, &emuWrite);
memcpy((void *)emuRead, nandRedir, sizeof(nandRedir)); memcpy((void *)emuRead, nandRedir, sizeof(nandRedir));
memcpy((void *)emuWrite, nandRedir, sizeof(nandRedir)); memcpy((void *)emuWrite, nandRedir, sizeof(nandRedir));
//Set MPU for emu code region //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; return 1;
} }
@ -187,15 +190,39 @@ u32 patchFirm(void){
//Skip patching //Skip patching
if(usePatchedFirm) return 1; if(usePatchedFirm) return 1;
//Apply emuNAND patches if(mode || emuNAND){
if(emuNAND){ //Find the Process9 NCCH location
if(!loadEmu()) return 0; 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 //Patch FIRM partitions writes on SysNAND to protect A9LH
u32 writeOffset = 0; void *writeOffset = getFIRMWrite(arm9Section, section[2].size);
getFIRMWrite(firmLocation, firmSize, &writeOffset); memcpy(writeOffset, FIRMblock, sizeof(FIRMblock));
memcpy((void *)writeOffset, FIRMblock, sizeof(FIRMblock));
} }
//Disable signature checks //Disable signature checks
@ -210,31 +237,6 @@ u32 patchFirm(void){
if(console) if(console)
firmLocation->arm9Entry = (u8 *)0x801B01C; 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 //Write patched FIRM to SD if needed
if(firmPathPatched) if(firmPathPatched)
if(!fileWrite((u8 *)firmLocation, firmPathPatched, firmSize)) return 0; if(!fileWrite((u8 *)firmLocation, firmPathPatched, firmSize)) return 0;
@ -244,12 +246,12 @@ u32 patchFirm(void){
void launchFirm(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 //Copy firm partitions to respective memory locations
memcpy(section[0].address, (u8 *)firmLocation + section[0].offset, section[0].size); 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[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 //Run ARM11 screen stuff
vu32 *const arm11 = (u32 *)0x1FFFFFF8; vu32 *const arm11 = (u32 *)0x1FFFFFF8;

View File

@ -25,12 +25,14 @@ const u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};
const u8 FIRMblock[4] = {0x00, 0x20, 0xC0, 0x46}; const u8 FIRMblock[4] = {0x00, 0x20, 0xC0, 0x46};
const u8 emuInstr[5] = {0xA5, 0x01, 0x08, 0x30, 0xA5};
/************************************************** /**************************************************
* Functions * Functions
**************************************************/ **************************************************/
u8 *getProc9(void *pos, u32 size){
return (u8 *)memsearch(pos, "ess9", size, 4);
}
void getSignatures(void *pos, u32 size, u32 *off, u32 *off2){ void getSignatures(void *pos, u32 size, u32 *off, u32 *off2){
//Look for signature checks //Look for signature checks
const unsigned char pattern[] = {0xC0, 0x1C, 0x76, 0xE7}; 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; *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 //Look for FIRM reboot code
const unsigned char pattern[] = {0xDE, 0x1F, 0x8D, 0xE2}; 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 //Calculate fOpen
u32 p9addr = *(u32 *)((u8 *)memsearch(pos, "ess9", size, 4) + 0xC); u32 p9MemAddr = *(u32 *)(proc9Offset + 0xC);
u32 p9off = (u32)memsearch(pos, "code", size, 4) + 0x1FF; u32 p9CodeOff = (u32)memsearch(pos, "code", size, 4) + 0x1FF;
const unsigned char pattern[] = {0xB0, 0x04, 0x98, 0x0D}; 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 //Look for FIRM writing code
u8 *firmwrite = (u8 *)memsearch(pos, "exe:", size, 4); u8 *firmwrite = (u8 *)memsearch(pos, "exe:", size, 4);
const unsigned char pattern[] = {0x00, 0x28, 0x01, 0xDA}; const unsigned char pattern[] = {0x00, 0x28, 0x01, 0xDA};
*off = (u32)memsearch(firmwrite - 0x100, pattern, 0x100, 4); return memsearch(firmwrite - 0x100, pattern, 0x100, 4);
} }

View File

@ -16,12 +16,12 @@ u8 nandRedir[0x08];
const u8 sigPat1[2]; const u8 sigPat1[2];
const u8 sigPat2[4]; const u8 sigPat2[4];
const u8 FIRMblock[4]; const u8 FIRMblock[4];
const u8 emuInstr[5];
/************************************************** /**************************************************
* Functions * Functions
**************************************************/ **************************************************/
u8 *getProc9(void *pos, u32 size);
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); u8 *getReboot(void *pos, u32 size);
void getfOpen(void *pos, u32 size, u32 *off); u32 getfOpen(void *pos, u32 size, u8 *proc9Offset);
void getFIRMWrite(void *pos, u32 size, u32 *off); void *getFIRMWrite(void *pos, u32 size);