From 697c64abe445065ee9dbb4a5fb9f8d24f5d57299 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Wed, 31 Aug 2016 13:11:41 +0200 Subject: [PATCH 1/2] Fix and restrain module access checks --- source/config.c | 2 +- source/firm.c | 2 +- source/patches.c | 33 +++++++++++++++++++-------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/source/config.c b/source/config.c index ef10f18..cbea164 100644 --- a/source/config.c +++ b/source/config.c @@ -85,7 +85,7 @@ void configMenu(bool oldPinStatus) "( ) Show GBA boot screen in patched AGB_FIRM", "( ) Display splash screen before payloads", "( ) Use a PIN", - "( ) Disable access checks" }; + "( ) Disable access checks (modules: O3DS only)" }; struct multiOption { int posXs[4]; diff --git a/source/firm.c b/source/firm.c index 6084b97..62ff308 100755 --- a/source/firm.c +++ b/source/firm.c @@ -367,7 +367,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 if(CONFIG(9)) { patchArm11SvcAccessChecks(arm11SvcHandler); - patchK11ModuleChecks(arm11Section1, section[1].size, &freeK11Space); + if(!isN3DS) patchK11ModuleChecks(arm11Section1, section[1].size, &freeK11Space); patchP9AccessChecks(process9Offset, process9Size); } } diff --git a/source/patches.c b/source/patches.c index b9129a0..12479a2 100644 --- a/source/patches.c +++ b/source/patches.c @@ -341,27 +341,32 @@ void patchArm11SvcAccessChecks(u32 *arm11SvcHandler) //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. - - //Inject our code into the free space - memcpy(*freeK11Space, k11modules, k11modules_size); - (*freeK11Space) += k11modules_size; + // We have to detour a function in the ARM11 kernel because builtin modules + // are compressed in memory and are only decompressed at runtime. - //Find the code that decompresses the .code section of the builtin modules and detour it with a jump to our code + u8 *freeSpace = *freeK11Space; + (*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 const u8 pattern[] = { 0x00, 0x00, 0x94, 0xE5, 0x18, 0x10, 0x90, 0xE5, 0x28, 0x20, 0x90, 0xE5, 0x48, 0x00, 0x9D, 0xE5 }; - u32 *off = (u32 *)memsearch(pos, pattern, size, 16); + u8 *off = 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)*freeK11Space) - ((u32)off + 8)) >> 2) & 0xFFFFFF; + // 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); - *off = offset | (1 << 24) | (0x5 << 25) | (0xE << 28); + // Write our jump + memcpy(off, &instruction, 4); } void patchP9AccessChecks(u8 *pos, u32 size) From 8ceeca372fbba8353415087a4ee4df770cf03c8a Mon Sep 17 00:00:00 2001 From: TuxSH Date: Wed, 31 Aug 2016 13:24:29 +0200 Subject: [PATCH 2/2] Fix build issue --- source/patches.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/patches.c b/source/patches.c index 12479a2..af0afb5 100644 --- a/source/patches.c +++ b/source/patches.c @@ -237,19 +237,19 @@ void patchTwlBg(u8 *pos) src2[1] = 0xE800 | ((((u32)dst - (u32)src2 - 4) & 0xFFF) >> 1); } -void getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset) +u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset) { //This function has to succeed. Crash if it doesn't (we'll get an exception dump of it anyways) const u8 callExceptionDispatcherPattern[] = {0x0F, 0x00, 0xBD, 0xE8, 0x13, 0x00, 0x02, 0xF1}; const u8 getTitleIDFromCodeSetPattern[] = {0xDC, 0x05, 0xC0, 0xE1, 0x20, 0x04, 0xA0, 0xE1}; - - *stackAddr = *((u32 *)memsearch(pos, callExceptionDispatcherPattern, size, 8) + 3); - + u32 *loadCodeSet = (u32 *)memsearch(pos, getTitleIDFromCodeSetPattern, size, 8); while((*loadCodeSet >> 20) != 0xE59 || ((*loadCodeSet >> 12) & 0xF) != 0) //ldr r0, [rX, #offset] loadCodeSet--; *codeSetOffset = *loadCodeSet & 0xFFF; + + return *((u32 *)memsearch(pos, callExceptionDispatcherPattern, size, 8) + 3); } void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) @@ -286,7 +286,7 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) } } -void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address) +void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address) { //Stub svcBreak with "bkpt 65535" so we can debug the panic. //Thanks @yellows8 and others for mentioning this idea on #3dsdev. @@ -295,7 +295,7 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address) u32 *arm9SvcTable = (u32 *)memsearch(pos, svcHandlerPattern, size, 4); while(*arm9SvcTable) arm9SvcTable++; //Look for SVC0 (NULL) - u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9Address); + u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - kernel9Address); *addr = 0xE12FFF7F; }