Improved checks for installable FIRMs

This commit is contained in:
d0k3 2017-09-28 05:09:15 +02:00
parent 0221839299
commit fa3daea740
3 changed files with 10 additions and 3 deletions

View File

@ -108,6 +108,10 @@ u32 ValidateFirm(void* firm, u32 firm_size, bool installable) {
if (installable && (header->reserved0[0]&0x1)) if (installable && (header->reserved0[0]&0x1))
return 1; return 1;
// Nintendo style entrypoints?
if (installable && ((header->entry_arm9 % 0x10) || (header->entry_arm11 % 0x10)))
return 1;
return 0; return 0;
} }
@ -232,6 +236,7 @@ u32 DecryptFirm(void* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeade
u32 DecryptFirmSequential(void* data, u32 offset, u32 size) { u32 DecryptFirmSequential(void* data, u32 offset, u32 size) {
// warning: this will only work for sequential processing // warning: this will only work for sequential processing
// also, only for blocks aligned to 0x200 bytes
// unexpected results otherwise // unexpected results otherwise
static FirmHeader firm = { 0 }; static FirmHeader firm = { 0 };
static FirmA9LHeader a9l = { 0 }; static FirmA9LHeader a9l = { 0 };

View File

@ -1432,7 +1432,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
optionstr[0] = "Install to FIRM0"; optionstr[0] = "Install to FIRM0";
optionstr[1] = "Install to FIRM1"; optionstr[1] = "Install to FIRM1";
optionstr[2] = "Install to both"; optionstr[2] = "Install to both";
// this only works up to FIRM1; // this only works up to FIRM1
slots = ShowSelectPrompt(3, optionstr, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024); slots = ShowSelectPrompt(3, optionstr, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024);
} else slots = ShowPrompt(true, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024) ? 1 : 0; } else slots = ShowPrompt(true, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024) ? 1 : 0;
if (slots) ShowPrompt(false, "%s (%dkB)\nInstall %s", pathstr, firm_size / 1024, if (slots) ShowPrompt(false, "%s (%dkB)\nInstall %s", pathstr, firm_size / 1024,
@ -1644,7 +1644,7 @@ u32 GodMode(bool is_b9s) {
FirmHeader* firm_in_mem = (FirmHeader*) (void*) (TEMP_BUFFER + TEMP_BUFFER_SIZE); // should be safe here FirmHeader* firm_in_mem = (FirmHeader*) (void*) (TEMP_BUFFER + TEMP_BUFFER_SIZE); // should be safe here
memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops
if (bootloader) { // check for FIRM in FCRAM, but prevent bootloops if (bootloader) { // check for FIRM in FCRAM, but prevent bootloops
for (u8* addr = (u8*) 0x20000200; addr < (u8*) 0x24000000; addr += 0x400000) { for (u8* addr = (u8*) 0x20000200; addr < (u8*) 0x22000000; addr += 0x400000) {
if (memcmp(addr - 0x200, "A9NC", 4) != 0) continue; if (memcmp(addr - 0x200, "A9NC", 4) != 0) continue;
u32 firm_size = GetFirmSize((FirmHeader*) (void*) addr); u32 firm_size = GetFirmSize((FirmHeader*) (void*) addr);
if (!firm_size || (firm_size > (0x400000 - 0x200))) continue; if (!firm_size || (firm_size > (0x400000 - 0x200))) continue;
@ -1734,6 +1734,8 @@ u32 GodMode(bool is_b9s) {
break; break;
} }
} }
// bootloader handler
if (bootloader) { if (bootloader) {
const char* bootfirm_paths[] = { BOOTFIRM_PATHS }; const char* bootfirm_paths[] = { BOOTFIRM_PATHS };
if (ValidateFirm(firm_in_mem, FIRM_MAX_SIZE, false) == 0) BootFirm(firm_in_mem, "0:/bootonce.firm"); if (ValidateFirm(firm_in_mem, FIRM_MAX_SIZE, false) == 0) BootFirm(firm_in_mem, "0:/bootonce.firm");

View File

@ -452,7 +452,7 @@ u32 SafeInstallFirm(const char* path, u32 slots) {
u8* firm = (u8*) TEMP_BUFFER; u8* firm = (u8*) TEMP_BUFFER;
UINT firm_size; UINT firm_size;
if ((fvx_qread(path, firm, 0, TEMP_BUFFER_SIZE, &firm_size) != FR_OK) || if ((fvx_qread(path, firm, 0, TEMP_BUFFER_SIZE, &firm_size) != FR_OK) ||
!firm_size || (firm_size >= TEMP_BUFFER_SIZE) || (ValidateFirm(firm, firm_size, true) != 0)) { !firm_size || (ValidateFirm(firm, firm_size, true) != 0)) {
ShowPrompt(false, "%s\nFIRM load/verify error.", pathstr); ShowPrompt(false, "%s\nFIRM load/verify error.", pathstr);
return 1; return 1;
} }