From 0f83d1ffaa5f026b81447757bf4ae03d2fd9e826 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 10 Sep 2016 21:12:53 +0200 Subject: [PATCH] Fix broken assumptions and bugs --- injector/source/CFWInfo.h | 2 +- patches/svcGetCFWInfo.s | 2 ++ source/firm.c | 7 ++++--- source/patches.c | 16 ++++++++++------ source/patches.h | 6 +++--- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/injector/source/CFWInfo.h b/injector/source/CFWInfo.h index cc9eb6b..30b4781 100644 --- a/injector/source/CFWInfo.h +++ b/injector/source/CFWInfo.h @@ -16,4 +16,4 @@ typedef struct __attribute__((packed)) u32 config; } CFWInfo; -void svcGetCFWInfo(CFWInfo *info); \ No newline at end of file +int svcGetCFWInfo(CFWInfo *info); \ No newline at end of file diff --git a/patches/svcGetCFWInfo.s b/patches/svcGetCFWInfo.s index 3950ead..cfb11ee 100644 --- a/patches/svcGetCFWInfo.s +++ b/patches/svcGetCFWInfo.s @@ -34,6 +34,8 @@ cmp r0, r2 blo loop + mov r0, #0 + bx lr .pool diff --git a/source/firm.c b/source/firm.c index 5bd750d..dfd8377 100755 --- a/source/firm.c +++ b/source/firm.c @@ -299,8 +299,9 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr); //Find Kernel11 SVC table and free space locations + u32 baseK11VA; u8 *freeK11Space; - u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space); + u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space); //Apply signature patches patchSignatureChecks(process9Offset, process9Size); @@ -325,10 +326,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 patchTitleInstallMinVersionCheck(process9Offset, process9Size); //Restore svcBackdoor - reimplementSvcBackdoor(arm11Section1, arm11SvcTable, &freeK11Space); + reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space); } - implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space); + implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space); } static inline void patchLegacyFirm(FirmwareType firmType) diff --git a/source/patches.c b/source/patches.c index c61c1b2..40b2076 100644 --- a/source/patches.c +++ b/source/patches.c @@ -37,13 +37,17 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200; } -u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space) +u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space) { const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, sizeof(pattern)) - 0xB; u32 svcOffset = (-((arm11ExceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch - u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address + + u32 pointedInstructionVA = 0xFFFF0008 - svcOffset; + *baseK11VA = pointedInstructionVA & 0xFFFF0000; //this assumes that the pointed instruction has an offset < 0x10000; iirc that's always the case + + u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + pointedInstructionVA - *baseK11VA + 8) - *baseK11VA); //SVC handler address while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL) const u8 pattern2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; @@ -110,7 +114,7 @@ void patchOldFirmWrites(u8 *pos, u32 size) off[1] = 0xE01D; } -void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space) +void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space) { //Official implementation of svcBackdoor const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff @@ -128,12 +132,12 @@ void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space) { memcpy(*freeK11Space, svcBackdoor, 40); - arm11SvcTable[0x7B] = 0xFFF00000 + *freeK11Space - pos; + arm11SvcTable[0x7B] = baseK11VA + *freeK11Space - pos; *freeK11Space += 40; } } -void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space) +void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space) { memcpy(*freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size); @@ -155,7 +159,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space) info->flags = 0 /* master branch */ | ((isRelease ? 1 : 0) << 1) /* is release */; - arm11SvcTable[0x2E] = 0xFFF00000 + *freeK11Space - pos; //Stubbed svc + arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc *freeK11Space += svcGetCFWInfo_size; } diff --git a/source/patches.h b/source/patches.h index c545105..d7651bf 100644 --- a/source/patches.h +++ b/source/patches.h @@ -50,12 +50,12 @@ typedef struct __attribute__((packed)) extern bool isN3DS; u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); -u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space); +u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space); void patchSignatureChecks(u8 *pos, u32 size); void patchTitleInstallMinVersionCheck(u8 *pos, u32 size); void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr); void patchFirmWrites(u8 *pos, u32 size); void patchOldFirmWrites(u8 *pos, u32 size); -void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space); -void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space); +void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space); +void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space); void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType); \ No newline at end of file