Display the number of failed patches, make loader svcBreak on failed patch, minor cleanup
This commit is contained in:
parent
973640f023
commit
d4cf22d370
@ -13,7 +13,7 @@ static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, i
|
||||
{
|
||||
u8 *found = memsearch(start, pattern, size, patSize);
|
||||
|
||||
if(found == NULL) break;
|
||||
if(found == NULL) svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
memcpy(found + offset, replace, repSize);
|
||||
|
||||
@ -143,6 +143,8 @@ static void loadTitleCodeSection(u64 progId, u8 *code, u32 size)
|
||||
{
|
||||
u64 total;
|
||||
IFile_Read(&file, &total, code, fileSize);
|
||||
|
||||
if(total != fileSize) svcBreak(USERBREAK_ASSERT);
|
||||
}
|
||||
|
||||
IFile_Close(&file);
|
||||
@ -374,8 +376,10 @@ void patchCode(u64 progId, u8 *code, u32 size)
|
||||
|
||||
u8 *fpdVer = memsearch(code, fpdVerPattern, size, sizeof(fpdVerPattern));
|
||||
|
||||
if(fpdVer == NULL) svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
//Allow online access to work with old friends modules
|
||||
if(fpdVer != NULL && fpdVer[9] < mostRecentFpdVer) fpdVer[9] = mostRecentFpdVer;
|
||||
if(fpdVer[9] < mostRecentFpdVer) fpdVer[9] = mostRecentFpdVer;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -462,12 +466,11 @@ void patchCode(u64 progId, u8 *code, u32 size)
|
||||
|
||||
u32 *cfgN3dsCpuLoc = (u32 *)memsearch(code, cfgN3dsCpuPattern, size, sizeof(cfgN3dsCpuPattern));
|
||||
|
||||
if(cfgN3dsCpuLoc == NULL) svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
//Patch N3DS CPU Clock and L2 cache setting
|
||||
if(cfgN3dsCpuLoc != NULL)
|
||||
{
|
||||
*(cfgN3dsCpuLoc + 1) = 0xE1A00000;
|
||||
*(cfgN3dsCpuLoc + 8) = 0xE3A00000 | cpuSetting;
|
||||
}
|
||||
*(cfgN3dsCpuLoc + 1) = 0xE1A00000;
|
||||
*(cfgN3dsCpuLoc + 8) = 0xE3A00000 | cpuSetting;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -498,7 +498,7 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
||||
aes_use_keyslot(arm9BinSlot);
|
||||
aes(startOfArm9Bin, startOfArm9Bin, arm9BinSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||
|
||||
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Error decrypting the ARM9 binary.");
|
||||
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary.");
|
||||
}
|
||||
|
||||
//Set >=9.6 KeyXs
|
||||
|
@ -47,38 +47,44 @@ void installArm9Handlers(void)
|
||||
|
||||
u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset)
|
||||
{
|
||||
u32 ret;
|
||||
u32 *endPos = exceptionsPage + 0x400;
|
||||
|
||||
u32 *initFPU;
|
||||
for(initFPU = exceptionsPage; initFPU < exceptionsPage + 0x400 && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++);
|
||||
for(initFPU = exceptionsPage; *initFPU != 0xE1A0D002 && initFPU < endPos; initFPU++);
|
||||
|
||||
u32 *freeSpace;
|
||||
for(freeSpace = initFPU; freeSpace < exceptionsPage + 0x400 && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++);
|
||||
for(freeSpace = initFPU; *freeSpace != 0xFFFFFFFF && freeSpace < endPos; freeSpace++);
|
||||
|
||||
u32 *mcuReboot;
|
||||
for(mcuReboot = exceptionsPage; mcuReboot < exceptionsPage + 0x400 && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++);
|
||||
for(mcuReboot = exceptionsPage; *mcuReboot != 0xE3A0A0C2 && mcuReboot < endPos; mcuReboot++);
|
||||
|
||||
u32 ret = (initFPU == exceptionsPage + 0x400 || freeSpace == exceptionsPage + 0x400 ||
|
||||
mcuReboot == exceptionsPage + 0x400 || *(u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 36) != 0xFFFFFFFF) ? 1 : 0;
|
||||
|
||||
mcuReboot--;
|
||||
|
||||
memcpy(freeSpace, arm11_exceptions_bin + 32, arm11_exceptions_bin_size - 32);
|
||||
|
||||
exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 8) - 32); //Undefined Instruction
|
||||
exceptionsPage[3] = MAKE_BRANCH(exceptionsPage + 3, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 12) - 32); //Prefetch Abort
|
||||
exceptionsPage[4] = MAKE_BRANCH(exceptionsPage + 4, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 16) - 32); //Data Abort
|
||||
exceptionsPage[7] = MAKE_BRANCH(exceptionsPage + 7, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 4) - 32); //FIQ
|
||||
|
||||
for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 32); pos++)
|
||||
if(initFPU == endPos || freeSpace == endPos || mcuReboot == endPos) ret = 1;
|
||||
else
|
||||
{
|
||||
switch(*pos) //Perform relocations
|
||||
initFPU += 3;
|
||||
mcuReboot -= 2;
|
||||
|
||||
memcpy(freeSpace, arm11_exceptions_bin + 32, arm11_exceptions_bin_size - 32);
|
||||
|
||||
exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 8) - 32); //Undefined Instruction
|
||||
exceptionsPage[3] = MAKE_BRANCH(exceptionsPage + 3, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 12) - 32); //Prefetch Abort
|
||||
exceptionsPage[4] = MAKE_BRANCH(exceptionsPage + 4, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 16) - 32); //Data Abort
|
||||
exceptionsPage[7] = MAKE_BRANCH(exceptionsPage + 7, (u8 *)freeSpace + *(u32 *)(arm11_exceptions_bin + 4) - 32); //FIQ
|
||||
|
||||
for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_bin_size - 32); pos++)
|
||||
{
|
||||
case 0xFFFF3000: *pos = stackAddress; break;
|
||||
case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break;
|
||||
case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break;
|
||||
case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler)
|
||||
case 0xBEEFBEEF: *pos = codeSetOffset; break;
|
||||
default: break;
|
||||
switch(*pos) //Perform relocations
|
||||
{
|
||||
case 0xFFFF3000: *pos = stackAddress; break;
|
||||
case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break;
|
||||
case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break;
|
||||
case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler)
|
||||
case 0xBEEFBEEF: *pos = codeSetOffset; break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -145,13 +151,13 @@ void detectAndProcessExceptionDumps(void)
|
||||
for(u32 i = 0; i < 17; i += 2)
|
||||
{
|
||||
posY = drawString(registerNames[i], true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
hexItoa(regs[i], hexString, 8);
|
||||
hexItoa(regs[i], hexString, 8, true);
|
||||
drawString(hexString, true, 10 + 7 * SPACING_X, posY, COLOR_WHITE);
|
||||
|
||||
if(i != 16 || dumpHeader->processor != 9)
|
||||
{
|
||||
drawString(registerNames[i + 1], true, 10 + 22 * SPACING_X, posY, COLOR_WHITE);
|
||||
hexItoa(i == 16 ? regs[20] : regs[i + 1], hexString, 8);
|
||||
hexItoa(i == 16 ? regs[20] : regs[i + 1], hexString, 8, true);
|
||||
drawString(hexString, true, 10 + 29 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
@ -166,14 +172,14 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
for(u32 line = 0; line < 19 && stackDump < additionalData; line++)
|
||||
{
|
||||
hexItoa(regs[13] + 8 * line, hexString, 8);
|
||||
hexItoa(regs[13] + 8 * line, hexString, 8, true);
|
||||
posYBottom = drawString(hexString, false, 10, posYBottom + SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter(':', false, 10 + 8 * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
|
||||
for(u32 i = 0; i < 8 && stackDump < additionalData; i++, stackDump++)
|
||||
{
|
||||
char byteString[] = "00";
|
||||
hexItoa(*stackDump, byteString, 2);
|
||||
hexItoa(*stackDump, byteString, 2, false);
|
||||
drawString(byteString, false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ u32 firmRead(void *dest, u32 firmType)
|
||||
concatenateStrings(path, "/00000000.app");
|
||||
|
||||
//Convert back the .app name from integer to array
|
||||
hexItoa(firmVersion, &path[35], 8);
|
||||
hexItoa(firmVersion, path + 35, 8, false);
|
||||
|
||||
if(!fileRead(dest, path, 0x400200)) firmVersion = 0xFFFFFFFF;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "utils.h"
|
||||
#include "exceptions.h"
|
||||
#include "draw.h"
|
||||
#include "strings.h"
|
||||
#include "buttons.h"
|
||||
#include "pin.h"
|
||||
|
||||
@ -243,7 +244,12 @@ void main(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if(res != 0) error("Error applying FIRM patches.");
|
||||
if(res != 0)
|
||||
{
|
||||
char patchesError[] = "Failed to apply FIRM patch(es).";
|
||||
hexItoa(res, patchesError + 16, 2, false);
|
||||
error(patchesError);
|
||||
}
|
||||
|
||||
launchFirm(firmType, loadFromStorage);
|
||||
}
|
@ -35,7 +35,7 @@ u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||
{
|
||||
u8 *temp = memsearch(pos, "NCCH", size, 4);
|
||||
|
||||
if(temp == NULL) error("Error getting Process9 data.");
|
||||
if(temp == NULL) error("Failed to get Process9 data.");
|
||||
|
||||
Cxi *off = (Cxi *)(temp - 0x100);
|
||||
|
||||
@ -72,7 +72,7 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 *
|
||||
if(*freeK11Space == NULL) ret = false;
|
||||
else (*freeK11Space)++;
|
||||
|
||||
if(!ret) error("Error getting Kernel11 data.");
|
||||
if(!ret) error("Failed to get Kernel11 data.");
|
||||
|
||||
return arm11SvcTable;
|
||||
}
|
||||
@ -359,7 +359,7 @@ u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset)
|
||||
if(temp == NULL) ret = false;
|
||||
else stackAddress = *(u32 *)(temp + 9);
|
||||
|
||||
if(!ret) error("Error getting ARM11 exception handlers data.");
|
||||
if(!ret) error("Failed to get ARM11 exception handlers data.");
|
||||
|
||||
return stackAddress;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void concatenateStrings(char *destination, const char *source)
|
||||
memcpy(&destination[j], source, i + 1);
|
||||
}
|
||||
|
||||
void hexItoa(u32 number, char *out, u32 digits)
|
||||
void hexItoa(u32 number, char *out, u32 digits, bool fillString)
|
||||
{
|
||||
const char hexDigits[] = "0123456789ABCDEF";
|
||||
u32 i = 0;
|
||||
@ -51,5 +51,5 @@ void hexItoa(u32 number, char *out, u32 digits)
|
||||
number >>= 4;
|
||||
}
|
||||
|
||||
while(i < digits) out[digits - 1 - i++] = '0';
|
||||
if(fillString) while(i < digits) out[digits - 1 - i++] = '0';
|
||||
}
|
@ -26,4 +26,4 @@
|
||||
|
||||
u32 strlen(const char *string);
|
||||
void concatenateStrings(char *destination, const char *source);
|
||||
void hexItoa(u32 number, char *out, u32 digits);
|
||||
void hexItoa(u32 number, char *out, u32 digits, bool fillString);
|
Reference in New Issue
Block a user