Fix derps (thanks to @Mrrraou), general cleaup, rewrite of the modules copying function

This commit is contained in:
Aurora 2016-08-30 02:03:56 +02:00
parent cb9576b10e
commit e8b9e49f57
9 changed files with 148 additions and 190 deletions

View File

@ -24,7 +24,7 @@
#define FINAL_BUFFER 0xE5000000 //0x25000000
#define REG_DUMP_SIZE (4*23)
#define REG_DUMP_SIZE 4 * 23
#define CODE_DUMP_SIZE 48
#define CODESET_OFFSET 0xBEEFBEEF
@ -69,7 +69,7 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type
//Dump registers
//Current order of saved regs: dfsr, ifsr, far, fpexc, fpinst, fpinst2, cpsr, pc, r8-r12, sp, lr, r0-r7
u32 cpsr = regs[6];
u32 pc = regs[7] - ((type < 3) ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
u32 pc = regs[7] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
registerDump[15] = pc;
registerDump[16] = cpsr;
@ -90,8 +90,8 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type
dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1);
final += dumpHeader.stackDumpSize;
vu8 *currentKProcess = (cannotAccessVA((u8 *)0xFFFF9004)) ? NULL : *(vu8 **)0xFFFF9004;
vu8 *currentKCodeSet = (currentKProcess != NULL) ? *(vu8 **)(currentKProcess + CODESET_OFFSET) : NULL;
vu8 *currentKProcess = cannotAccessVA((u8 *)0xFFFF9004) ? NULL : *(vu8 **)0xFFFF9004;
vu8 *currentKCodeSet = currentKProcess != NULL ? *(vu8 **)(currentKProcess + CODESET_OFFSET) : NULL;
if(currentKCodeSet != NULL)
{
@ -101,8 +101,7 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type
additionalData[0] = *(vu64 *)(currentKCodeSet + 0x50); //Process name
additionalData[1] = *(vu64 *)(currentKCodeSet + 0x5C); //Title ID
}
else
dumpHeader.additionalDataSize = 0;
else dumpHeader.additionalDataSize = 0;
//Copy header (actually optimized by the compiler)
final = (u8 *)FINAL_BUFFER;

View File

@ -23,12 +23,9 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#ifndef NULL
#define NULL 0
#endif
//Common data types
typedef uint8_t u8;
typedef uint16_t u16;

View File

@ -25,7 +25,7 @@
#define FINAL_BUFFER 0x25000000
#define REG_DUMP_SIZE (4*17)
#define REG_DUMP_SIZE 4 * 17
#define CODE_DUMP_SIZE 48
bool cannotAccessAddress(const void *address)
@ -37,7 +37,7 @@ bool cannotAccessAddress(const void *address)
for(u32 i = 0; i < 8; i++)
{
if((dataAccessPermissions & 0xF) == 0 || (regionSettings[i] & 1) == 0)
continue; //no access / region not enabled
continue; //No access / region not enabled
u32 regionAddrBase = regionSettings[i] & ~0xFFF;
u32 regionSize = 1 << (((regionSettings[i] >> 1) & 0x1F) + 1);
@ -88,7 +88,7 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type
//Dump registers
//Current order of saved regs: cpsr, pc, r8-r14, r0-r7
u32 cpsr = regs[0];
u32 pc = regs[1] - ((type < 3) ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
u32 pc = regs[1] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
registerDump[15] = pc;
registerDump[16] = cpsr;

View File

@ -23,12 +23,9 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#ifndef NULL
#define NULL 0
#endif
//Common data types
typedef uint8_t u8;
typedef uint16_t u16;

View File

@ -30,27 +30,11 @@
#include "../build/arm9_exceptions.h"
#include "../build/arm11_exceptions.h"
typedef struct __attribute__((packed))
{
u32 magic[2];
u16 versionMinor, versionMajor;
u16 processor, core;
u32 type;
u32 totalSize;
u32 registerDumpSize;
u32 codeDumpSize;
u32 stackDumpSize;
u32 additionalDataSize;
} ExceptionDumpHeader;
void installArm9Handlers(void)
{
void *payloadAddress = (void *)0x01FF8000;
const u32 offsets[] = {0x08, 0x18, 0x20, 0x28};
memcpy(payloadAddress, arm9_exceptions + 32, arm9_exceptions_size - 32);
memcpy((void *)0x01FF8000, arm9_exceptions + 32, arm9_exceptions_size - 32);
//IRQHandler is at 0x08000000, but we won't handle it for some reasons
//svcHandler is at 0x08000010, but we won't handle svc either
@ -62,20 +46,18 @@ void installArm9Handlers(void)
}
}
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset)
{
u32 *initFPU;
for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU += 1);
for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++);
u32 *mcuReboot;
for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot += 1);
for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++);
mcuReboot--;
u32 *freeSpace;
for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace += 1);
for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++);
memcpy(freeSpace, arm11_exceptions + 32, arm11_exceptions_size - 32);
exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 8) - 32); //Undefined Instruction
@ -90,8 +72,8 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset)
case 0xFFFF3000: *pos = stackAddr; 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;
case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler)
case 0xBEEFBEEF: *pos = codeSetOffset; break;
default: break;
}
}
@ -113,64 +95,61 @@ static void hexItoa(u32 n, char *out)
void detectAndProcessExceptionDumps(void)
{
const char *handledExceptionNames[] = {
"FIQ", "undefined instruction", "prefetch abort", "data abort"
};
const char *registerNames[] = {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
"SP", "LR", "PC", "CPSR", "FPEXC"
};
char hexstring[] = "00000000";
volatile ExceptionDumpHeader *dumpHeader = (volatile ExceptionDumpHeader *)0x25000000;
vu32 *dump = (vu32 *)dumpHeader;
vu32 *regs = (vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader));
vu8 *additionalData = (vu8 *)dumpHeader + dumpHeader->totalSize - dumpHeader->additionalDataSize;
if(dumpHeader->magic[0] == 0xDEADC0DE && dumpHeader->magic[1] == 0xDEADCAFE && (dumpHeader->processor == 9 || dumpHeader->processor == 11))
{
char path9[41] = "/luma/dumps/arm9";
char path11[42] = "/luma/dumps/arm11";
char path[42];
char fileName[] = "crash_dump_00000000.dmp";
u32 size = dumpHeader->totalSize;
char *pathFolder;
u32 fileNameSpot;
if(dumpHeader->processor == 9)
{
findDumpFile(path9, fileName);
path9[16] = '/';
memcpy(&path9[17], fileName, sizeof(fileName));
if(!fileWrite((void *)dump, path9, size))
{
createDirectory("/luma");
createDirectory("/luma/dumps");
createDirectory("/luma/dumps/arm9");
fileWrite((void *)dump, path9, size);
}
pathFolder = "/luma/dumps/arm9";
fileNameSpot = 16;
}
else
{
findDumpFile(path11, fileName);
path11[17] = '/';
memcpy(&path11[18], fileName, sizeof(fileName));
if(!fileWrite((void *)dump, path11, size))
{
createDirectory("/luma");
createDirectory("/luma/dumps");
createDirectory("/luma/dumps/arm11");
fileWrite((void *)dump, path11, size);
}
pathFolder = "/luma/dumps/arm11";
fileNameSpot = 17;
}
findDumpFile(pathFolder, fileName);
memcpy(path, pathFolder, 17);
path[fileNameSpot] = '/';
memcpy(&path[fileNameSpot + 1], fileName, sizeof(fileName));
if(!fileWrite((void *)dumpHeader, path, size))
{
createDirectory("/luma");
createDirectory("/luma/dumps");
createDirectory(pathFolder);
fileWrite((void *)dumpHeader, path, size);
}
vu32 *regs = (vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader));
vu8 *additionalData = (vu8 *)dumpHeader + dumpHeader->totalSize - dumpHeader->additionalDataSize;
const char *handledExceptionNames[] = {
"FIQ", "undefined instruction", "prefetch abort", "data abort"
};
const char *registerNames[] = {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
"SP", "LR", "PC", "CPSR", "FPEXC"
};
char hexstring[] = "00000000";
char arm11Str[] = "Processor: ARM11 (core X)";
if(dumpHeader->processor == 11) arm11Str[29] = '0' + (char)(dumpHeader->core);
initScreens();
drawString("An exception occurred", 10, 10, COLOR_RED);
int posY = drawString((dumpHeader->processor == 11) ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y;
int posY = drawString(dumpHeader->processor == 11 ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y;
posY = drawString("Exception type: ", 10, posY, COLOR_WHITE);
posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE);
@ -202,6 +181,7 @@ void detectAndProcessExceptionDumps(void)
}
posY += 3 * SPACING_Y;
for(u32 i = 0; i < 17; i += 2)
{
posY = drawString(registerNames[i], 10, posY, COLOR_WHITE);
@ -211,7 +191,7 @@ void detectAndProcessExceptionDumps(void)
if(dumpHeader->processor != 9 || i != 16)
{
posY = drawString(registerNames[i + 1], 10 + 22 * SPACING_X, posY, COLOR_WHITE);
hexItoa((i == 16) ? regs[20] : regs[i + 1], hexstring);
hexItoa(i == 16 ? regs[20] : regs[i + 1], hexstring);
posY = drawString(hexstring, 10 + 29 * SPACING_X, posY, COLOR_WHITE);
}
@ -223,19 +203,18 @@ void detectAndProcessExceptionDumps(void)
u32 mode = regs[16] & 0xF;
if(dumpHeader->type == 3 && (mode == 7 || mode == 11))
{
posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //in yellow
posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //In yellow
if(dumpHeader->processor != 9) posY -= SPACING_Y;
}
posY = drawString("You can find a dump in the following file:", 10, posY, COLOR_WHITE) + SPACING_Y;
posY = drawString((dumpHeader->processor == 9) ? path9 : path11, 10, posY, COLOR_WHITE) + 2 * SPACING_Y;
posY = drawString(path, 10, posY, COLOR_WHITE) + 2 * SPACING_Y;
drawString("Press any button to shutdown", 10, posY, COLOR_WHITE);
waitInput();
for(u32 i = 0; i < size / 4; i++) dump[i] = 0;
memset32((void *)dumpHeader, 0, size);
clearScreens();
mcuPowerOff();
}
}

View File

@ -24,6 +24,24 @@
#include "types.h"
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
typedef struct __attribute__((packed))
{
u32 magic[2];
u16 versionMinor, versionMajor;
u16 processor, core;
u32 type;
u32 totalSize;
u32 registerDumpSize;
u32 codeDumpSize;
u32 stackDumpSize;
u32 additionalDataSize;
} ExceptionDumpHeader;
void installArm9Handlers(void);
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset);
void detectAndProcessExceptionDumps(void);

View File

@ -43,7 +43,9 @@ static const firmSectionHeader *section;
u32 emuOffset;
bool isN3DS, isDevUnit, isFirmlaunch;
bool isN3DS,
isDevUnit,
isFirmlaunch;
cfgData configData;
FirmwareSource firmSource;
@ -239,6 +241,7 @@ void main(void)
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
{
section = firm->section;
const char *firmwareFiles[4] = {
"/luma/firmware.bin",
"/luma/firmware_twl.bin",
@ -248,13 +251,10 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
u32 firmVersion;
if(fileRead(firm, firmwareFiles[(u32)firmType]))
{
firmVersion = 0xFFFFFFFF;
}
if(fileRead(firm, firmwareFiles[(u32)*firmType])) firmVersion = 0xFFFFFFFF;
else
{
firmVersion = firmRead(firm, (u32)firmType);
firmVersion = firmRead(firm, (u32)*firmType);
if(!isN3DS && *firmType == NATIVE_FIRM)
{
@ -279,9 +279,9 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
firmVersion = 0xFFFFFFFF;
}
}
}
if(firmVersion != 0xFFFFFFFF) decryptExeFs((u8 *)firm);
decryptExeFs((u8 *)firm);
}
return firmVersion;
}
@ -347,13 +347,14 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
if(DEV_OPTIONS != 2)
{
//Install arm11 exception handlers
u32 stackAddress, codeSetOffset;
u32 stackAddress,
codeSetOffset;
getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &stackAddress, &codeSetOffset);
installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset);
//Kernel9/Process9 debugging
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address));
patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address);
patchKernel9Panic(arm9Section, section[2].size, NATIVE_FIRM);
//Stub svcBreak11 with "bkpt 65535"
@ -389,7 +390,7 @@ static inline void patchLegacyFirm(FirmwareType firmType)
{
//Kernel9/Process9 debugging
patchArm9ExceptionHandlersInstall(arm9Section, section[3].size);
patchSvcBreak9(arm9Section, section[3].size, (u32)(section[3].address));
patchSvcBreak9(arm9Section, section[3].size, (u32)section[3].address);
patchKernel9Panic(arm9Section, section[3].size, firmType);
}
@ -416,70 +417,48 @@ static inline void patch2xNativeAndSafeFirm(void)
{
//Kernel9/Process9 debugging
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address));
patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address);
}
}
static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
{
u8 *arm11Section0 = (u8 *)firm + section[0].offset;
char fileName[] = "/luma/sysmodules/--------.cxi";
const char *ext = ".cxi";
u32 srcModuleSize,
dstModuleSize;
struct
for(u8 *src = (u8 *)firm + section[0].offset, *srcEnd = src + section[0].size, *dst = section[0].address;
src < srcEnd; src += srcModuleSize, dst += dstModuleSize)
{
u32 size;
char name[8];
const u8 *addr;
} modules[5];
srcModuleSize = *(u32 *)(src + 0x104) * 0x200;
char *moduleName = (char *)(src + 0x200);
u8 *pos = arm11Section0;
u32 n = 0;
u32 loaderIndex = 0;
for(u8 *end = pos + section[0].size; pos < end; pos += modules[n++].size)
{
modules[n].addr = pos;
modules[n].size = *(u32 *)(pos + 0x104) * 0x200;
memcpy(modules[n].name, pos + 0x200, 8);
char fileName[30] = "/luma/sysmodules/";
const char *ext = ".cxi";
//Read modules from files if they exist
u32 nameOff;
for(nameOff = 0; nameOff < 8 && modules[n].name[nameOff] != 0; nameOff++);
memcpy(fileName + 17, modules[n].name, nameOff);
for(nameOff = 0; nameOff < 8 && moduleName[nameOff] != 0; nameOff++);
memcpy(fileName + 17, moduleName, nameOff);
memcpy(fileName + 17 + nameOff, ext, 5);
u32 fileSize = getFileSize(fileName);
if(fileSize != 0)
{
modules[n].addr = NULL;
modules[n].size = fileSize;
}
if(firmType == NATIVE_FIRM && memcmp(modules[n].name, "loader", 7) == 0) loaderIndex = n;
}
if(firmType == NATIVE_FIRM && modules[loaderIndex].addr != NULL)
{
modules[loaderIndex].size = injector_size;
modules[loaderIndex].addr = injector;
}
pos = section[0].address;
for(u32 i = 0; i < n; pos += modules[i++].size)
{
if(modules[i].addr != NULL)
memcpy(pos, modules[i].addr, modules[i].size);
u32 fileSize = fileRead(dst, fileName);
if(fileSize) dstModuleSize = fileSize;
else
{
//Read modules from files if they exist
u32 nameOff;
for(nameOff = 0; nameOff < 8 && modules[i].name[nameOff] != 0; nameOff++);
memcpy(fileName + 17, modules[i].name, nameOff);
memcpy(fileName + 17 + nameOff, ext, 5);
fileRead(pos, fileName);
void *module;
if(firmType == NATIVE_FIRM && memcmp(moduleName, "loader", 6) == 0)
{
module = (void *)injector;
dstModuleSize = injector_size;
}
else
{
module = src;
dstModuleSize = srcModuleSize;
}
memcpy(dst, module, dstModuleSize);
}
}
}

View File

@ -265,9 +265,7 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size)
if(off == NULL) return;
off += sizeof(pattern)/4;
u32 r0 = 0x08000000;
for(; *off != 0xE3A01040; off++) //Until mov r1, #0x40
for(u32 r0 = 0x08000000; *off != 0xE3A01040; off++) //Until mov r1, #0x40
{
if((*off >> 26) != 0x39 || ((*off >> 16) & 0xF) != 0 || ((*off >> 25) & 1) != 0 || ((*off >> 20) & 5) != 0)
continue; //Discard everything that's not str rX, [r0, #imm](!)
@ -288,7 +286,7 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size)
}
}
void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr)
void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address)
{
//Stub svcBreak with "bkpt 65535" so we can debug the panic.
//Thanks @yellows8 and others for mentioning this idea on #3dsdev.
@ -296,14 +294,14 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr)
u32 *arm9SvcTable = (u32 *)memsearch(pos, svcHandlerPattern, size, 4);
while(*arm9SvcTable) arm9SvcTable++; //Look for SVC0 (NULL)
u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9addr);
u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9Address);
*addr = 0xE12FFF7F;
}
void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable)
{
//Same as above, for NFIRM arm11
u32 *addr = (u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000);
*addr = 0xE12FFF7F;
}
@ -312,12 +310,11 @@ void patchKernel9Panic(u8 *pos, u32 size, FirmwareType firmType)
{
if(firmType == TWL_FIRM || firmType == AGB_FIRM)
{
u8 *off = pos + ((isN3DS) ? 0x723C : 0x69A8);
u8 *off = pos + (isN3DS ? 0x723C : 0x69A8);
*(u16 *)off = 0x4778; //bx pc
*(u16 *)(off + 2) = 0x46C0; //nop
*(u32 *)(off + 4) = 0xE12FFF7E; //bkpt 65534
}
else
{
const u8 pattern[] = {0x00, 0x20, 0xA0, 0xE3, 0x02, 0x30, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x05, 0x00, 0xA0, 0xE3};
@ -337,41 +334,34 @@ void patchKernel11Panic(u8 *pos, u32 size)
void patchArm11SvcAccessChecks(u32 *arm11SvcHandler)
{
u32 *off = arm11SvcHandler;
while(*off != 0xE11A0E1B) off++; //TST R10, R11,LSL LR
*off = 0xE3B0A001; //MOVS R10, #1
while(*arm11SvcHandler != 0xE11A0E1B) arm11SvcHandler++; //TST R10, R11,LSL LR
*arm11SvcHandler = 0xE3B0A001; //MOVS R10, #1
}
//It's mainly Subv's code here:
void patchK11ModuleChecks(u8 *pos, u32 size, u8 **freeK11Space)
{
// We have to detour a function in the ARM11 kernel because builtin modules
// are compressed in memory and are only decompressed at runtime.
//We have to detour a function in the ARM11 kernel because builtin modules
//are compressed in memory and are only decompressed at runtime.
u8 *freeSpace = *freeK11Space;
*freeK11Space += k11modules_size;
//Inject our code into the free space
memcpy(*freeK11Space, k11modules, k11modules_size);
(*freeK11Space) += k11modules_size;
// Inject our code into the free space
memcpy(freeSpace, k11modules, k11modules_size);
// Find the code that decompresses the .code section of the builtin modules and detour it with a jump to our code
//Find the code that decompresses the .code section of the builtin modules and detour it with a jump to our code
const u8 pattern[] = { 0x00, 0x00, 0x94, 0xE5, 0x18, 0x10, 0x90, 0xE5, 0x28, 0x20,
0x90, 0xE5, 0x48, 0x00, 0x9D, 0xE5 };
u8 *off = memsearch(pos, pattern, size, 16);
u32 *off = (u32 *)memsearch(pos, pattern, size, 16);
// We couldn't find the code that decompresses the module
if (off == NULL)
return;
//We couldn't find the code that decompresses the module
if(off == NULL) return;
// Inject a jump instruction to our code at the offset we found
// Construct a jump (BL) instruction to our code
u32 offset = ((((u32)freeSpace) - ((u32)off + 8)) >> 2) & 0xFFFFFF;
u32 instruction = offset | (1 << 24) | (0x5 << 25) | (0xE << 28);
//Inject a jump instruction to our code at the offset we found
//Construct a jump (BL) instruction to our code
u32 offset = ((((u32)*freeK11Space) - ((u32)off + 8)) >> 2) & 0xFFFFFF;
// Write our jump
memcpy(off, &instruction, 4);
*off = offset | (1 << 24) | (0x5 << 25) | (0xE << 28);
}
void patchP9AccessChecks(u8 *pos, u32 size)
@ -384,7 +374,6 @@ void patchP9AccessChecks(u8 *pos, u32 size)
off[1] = 0x4770; //bx lr
}
void patchUnitInfoValueSet(u8 *pos, u32 size)
{
//Look for UNITINFO value being set during kernel sync
@ -392,6 +381,6 @@ void patchUnitInfoValueSet(u8 *pos, u32 size)
u8 *off = memsearch(pos, pattern, size, 4);
off[0] = (isDevUnit) ? 0 : 1;
off[0] = isDevUnit ? 0 : 1;
off[3] = 0xE3;
}

View File

@ -63,7 +63,7 @@ void patchTwlBg(u8 *pos);
void getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset);
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr);
void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address);
void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable);
void patchKernel9Panic(u8 *pos, u32 size, FirmwareType firmType);
void patchKernel11Panic(u8 *pos, u32 size);