diff --git a/Makefile b/Makefile index d53996c..a9238e4 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/injector.h $(dir_build)/loader.h -ifeq ($(strip $(BUILD)),DEV) +ifeq ($(strip $(DEV)),TRUE) CFLAGS += -DDEV bundled += $(dir_build)/k11modulespatch.h $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h title := \"$(name) $(revision) (dev) configuration\" @@ -59,7 +59,7 @@ a9lh: $(dir_out)/arm9loaderhax.bin ninjhax: $(dir_out)/3ds/$(name) .PHONY: release -ifeq ($(strip $(BUILD)),DEV) +ifeq ($(strip $(DEV)),TRUE) release: $(dir_out)/$(name)$(revision)-dev.7z else release: $(dir_out)/$(name)$(revision).7z @@ -119,7 +119,7 @@ $(dir_build)/svcGetCFWInfopatch.h: $(dir_patches)/svcGetCFWInfo.s $(dir_build)/injector.h: $(dir_injector)/Makefile @mkdir -p "$(@D)" - @$(MAKE) -C $(dir_injector) BUILD=$(BUILD) + @$(MAKE) -C $(dir_injector) DEV=$(DEV) @bin2c -o $@ -n injector $(@D)/injector.cxi $(dir_build)/loader.h: $(dir_loader)/Makefile diff --git a/injector/Makefile b/injector/Makefile index 36f34bd..8430950 100755 --- a/injector/Makefile +++ b/injector/Makefile @@ -30,7 +30,7 @@ LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ASFLAGS) objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(call rwildcard, $(dir_source), *.s *.c)) -ifeq ($(strip $(BUILD)),DEV) +ifeq ($(strip $(DEV)),TRUE) CFLAGS += -DDEV endif diff --git a/patches/svcGetCFWInfo.s b/patches/svcGetCFWInfo.s index fb2a079..cfb11ee 100644 --- a/patches/svcGetCFWInfo.s +++ b/patches/svcGetCFWInfo.s @@ -35,6 +35,7 @@ blo loop mov r0, #0 + bx lr .pool diff --git a/source/firm.c b/source/firm.c index ede8700..4c99d4c 100755 --- a/source/firm.c +++ b/source/firm.c @@ -365,14 +365,16 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 #ifdef DEV //Find Kernel11 SVC table and handler, exceptions page and free space locations + u32 baseK11VA; u8 *freeK11Space; u32 *arm11SvcHandler, *arm11ExceptionsPage, - *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage); + *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage); #else //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); #endif //Apply signature patches @@ -398,10 +400,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); #ifdef DEV //Apply UNITINFO patch diff --git a/source/patches.c b/source/patches.c index 79d8cdd..ade20fb 100644 --- a/source/patches.c +++ b/source/patches.c @@ -46,13 +46,16 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) } #ifdef DEV -u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage) +u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage) { const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; *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 *arm11SvcHandler = arm11SvcTable; while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL) @@ -63,13 +66,16 @@ u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler return arm11SvcTable; } #else -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}; @@ -137,7 +143,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 @@ -155,12 +161,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); @@ -186,7 +192,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space) info->flags = 0 /* master branch */ | ((isRelease ? 1 : 0) << 1) /* is release */; #endif - 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 0c2d652..4f63d11 100644 --- a/source/patches.h +++ b/source/patches.h @@ -60,9 +60,9 @@ extern bool isDevUnit; u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); #ifdef DEV -u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage); +u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage); #else -u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space); +u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space); #endif void patchSignatureChecks(u8 *pos, u32 size); @@ -70,8 +70,8 @@ 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); #ifdef DEV