From b71dedccfc712a9fc756a1b71606fdd5ca8811a8 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Fri, 16 Jun 2017 04:21:48 +0200 Subject: [PATCH] Full support for fw >= 6.x (tested) Virtually full support for 5.x except that svcUnmapProcessMemoryEx will be forwarded to svcUnmapProcessMemory (both are equivalent for up to 64MB chunks) --- k11_extension/include/globals.h | 1 + k11_extension/source/globals.c | 1 + k11_extension/source/main.c | 15 +++++----- k11_extension/source/svc/SendSyncRequest.c | 2 +- .../source/svc/UnmapProcessMemoryEx.c | 6 +++- k11_extension/source/utils.s | 5 ---- sysmodules/loader/source/loader.c | 2 ++ .../rosalina/source/input_redirection.c | 29 +++++++++++++++---- sysmodules/rosalina/source/main.c | 1 + .../rosalina/source/menus/process_patches.c | 2 +- 10 files changed, 43 insertions(+), 21 deletions(-) diff --git a/k11_extension/include/globals.h b/k11_extension/include/globals.h index 289e426..8ee6b59 100644 --- a/k11_extension/include/globals.h +++ b/k11_extension/include/globals.h @@ -64,6 +64,7 @@ extern Result (*SendSyncRequest)(Handle handle); extern Result (*OpenProcess)(Handle *out, u32 processId); extern Result (*GetProcessId)(u32 *out, Handle process); extern Result (*DebugActiveProcess)(Handle *out, u32 processId); +extern Result (*UnmapProcessMemory)(Handle processHandle, void *dst, u32 size); extern Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3); extern void (*flushDataCacheRange)(void *addr, u32 len); diff --git a/k11_extension/source/globals.c b/k11_extension/source/globals.c index f648ae2..03bf42d 100644 --- a/k11_extension/source/globals.c +++ b/k11_extension/source/globals.c @@ -60,6 +60,7 @@ Result (*SendSyncRequest)(Handle handle); Result (*OpenProcess)(Handle *out, u32 processId); Result (*GetProcessId)(u32 *out, Handle process); Result (*DebugActiveProcess)(Handle *out, u32 processId); +Result (*UnmapProcessMemory)(Handle processHandle, void *dst, u32 size); Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3); void (*flushDataCacheRange)(void *addr, u32 len); diff --git a/k11_extension/source/main.c b/k11_extension/source/main.c index 6c33ae5..843c0f6 100644 --- a/k11_extension/source/main.c +++ b/k11_extension/source/main.c @@ -96,7 +96,6 @@ void configHook(vu8 *cfgPage) *isDevUnit = true; // enable debug features } -void wat(u32 a, ...); static void findUsefulSymbols(void) { u32 *off; @@ -116,11 +115,11 @@ static void findUsefulSymbols(void) KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]); - for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE28DD014; off++); - KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off - 1); + for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++); + KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off + 1); - for(; *off != 0xE8BD80F0; off++); - KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 2); + for(; *off != 0xE320F000; off++); + KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 1); for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++); off -= 2; @@ -142,8 +141,8 @@ static void findUsefulSymbols(void) for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++); WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6); - for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE20030FF; off++); - KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off + 2); + for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++); + KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off - 1); for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++); threadList = *(KObjectList **)(off + 1); @@ -159,6 +158,7 @@ static void findUsefulSymbols(void) for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++); KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1); + // On < 6.x the pattern will match but the result will be wrong for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++); KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1); @@ -216,6 +216,7 @@ static void findUsefulSymbols(void) OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3); GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3); DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 3); + UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72]; KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1); for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++); diff --git a/k11_extension/source/svc/SendSyncRequest.c b/k11_extension/source/svc/SendSyncRequest.c index 8cd4012..1d3c244 100644 --- a/k11_extension/source/svc/SendSyncRequest.c +++ b/k11_extension/source/svc/SendSyncRequest.c @@ -45,7 +45,7 @@ Result SendSyncRequestHook(Handle handle) isValidClientSession = tok.flags == 0xA5; } else if(clientSession != NULL) // not the exact same test but it should work - isValidClientSession = strcmp(clientSession->syncObject.autoObject.vtable->GetClassName(&clientSession->syncObject.autoObject), "KClientSession"); + isValidClientSession = strcmp(clientSession->syncObject.autoObject.vtable->GetClassName(&clientSession->syncObject.autoObject), "KClientSession") == 0; if(isValidClientSession) { diff --git a/k11_extension/source/svc/UnmapProcessMemoryEx.c b/k11_extension/source/svc/UnmapProcessMemoryEx.c index 780237c..2f3d999 100644 --- a/k11_extension/source/svc/UnmapProcessMemoryEx.c +++ b/k11_extension/source/svc/UnmapProcessMemoryEx.c @@ -24,10 +24,14 @@ * reasonable ways as different from the original version. */ +#include "globals.h" #include "svc/MapProcessMemoryEx.h" -Result UnmapProcessMemoryEx(Handle processHandle UNUSED, void *dst, u32 size) +Result UnmapProcessMemoryEx(Handle processHandle, void *dst, u32 size) { + if(kernelVersion < SYSTEM_VERSION(2, 37, 0)) // < 6.x + return UnmapProcessMemory(processHandle, dst, size); // equivalent when size <= 64MB + KProcessHwInfo *currentHwInfo = hwInfoOfProcess(currentCoreContext->objectContext.currentProcess); Result res = KProcessHwInfo__UnmapProcessMemory(currentHwInfo, dst, size >> 12); diff --git a/k11_extension/source/utils.s b/k11_extension/source/utils.s index 16a48eb..f5ea72a 100644 --- a/k11_extension/source/utils.s +++ b/k11_extension/source/utils.s @@ -118,11 +118,6 @@ safecpy: _safecpy_end: -.global wat -.type wat, %function -wat: - bkpt 1 - bx lr .section .rodata .global safecpy_sz diff --git a/sysmodules/loader/source/loader.c b/sysmodules/loader/source/loader.c index 58a9f8d..3a8e569 100644 --- a/sysmodules/loader/source/loader.c +++ b/sysmodules/loader/source/loader.c @@ -283,6 +283,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle) res = HBLDR_Init(&hbldr); if (R_FAILED(res)) { + svcBreak(USERBREAK_ASSERT); return res; } u32* cmdbuf = getThreadCommandBuffer(); @@ -300,6 +301,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle) } if (R_FAILED(res)) { + svcBreak(USERBREAK_ASSERT); return res; } codeset = (Handle)cmdbuf[3]; diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 2a4f648..311f769 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -223,9 +223,10 @@ Result InputRedirection_DoOrUndoPatches(void) res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); } + svcCloseHandle(processHandle); res = OpenProcessByName("ir", &processHandle); - if(R_SUCCEEDED(res)) + if(R_SUCCEEDED(res) && osGetKernelVersion() >= SYSTEM_VERSION(2, 44, 6)) { svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); @@ -238,6 +239,7 @@ Result InputRedirection_DoOrUndoPatches(void) if(R_SUCCEEDED(res)) { + static bool useOldSyncCode; static u32 irOrigReadingCode[5] = { 0xE5940000, // ldr r0, [r4] 0xE1A01005, // mov r1, r5 @@ -250,7 +252,10 @@ Result InputRedirection_DoOrUndoPatches(void) 0xEF000024, // svc 0x24 (WaitSynchronization) 0xE1B01FA0, // movs r1, r0, lsr#31 0xE1A0A000, // mov r10, r0 - }; + }, irOrigWaitSyncCodeOld[] = { + 0xE0AC6000, // adc r6, r12, r0 + 0xE5D70000, // ldrb r0, [r7] + }; // pattern for 8.1 static const u32 irOrigCppFlagCode[] = { 0xE3550000, // cmp r5, #0 @@ -262,7 +267,10 @@ Result InputRedirection_DoOrUndoPatches(void) if(inputRedirectionEnabled) { memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode)); - memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode)); + if(useOldSyncCode) + memcpy(irWaitSyncLoc, &irOrigWaitSyncCodeOld, sizeof(irOrigWaitSyncCodeOld)); + else + memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode)); memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode)); } else @@ -288,9 +296,17 @@ Result InputRedirection_DoOrUndoPatches(void) u32 *off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCode, totalSize, sizeof(irOrigWaitSyncCode)); if(off2 == NULL) { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -5; + off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCodeOld, totalSize, sizeof(irOrigWaitSyncCodeOld)); + if(off2 == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -5; + } + + useOldSyncCode = true; } + else + useOldSyncCode = false; u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &irOrigCppFlagCode, totalSize, sizeof(irOrigCppFlagCode)); if(off3 == NULL) @@ -310,7 +326,7 @@ Result InputRedirection_DoOrUndoPatches(void) memcpy(irHookLoc, &irHook, sizeof(irHook)); - // This "NOP"s out a WaitSynchronisation1 (on the event bound to the 'IR' interrupt) + // This "NOP"s out a WaitSynchronisation1 (on the event bound to the 'IR' interrupt) or the check of a previous one *irWaitSyncLoc = 0xE3A00000; // mov r0, #0 // This NOPs out a flag check in ir:user's CPP emulation @@ -320,6 +336,7 @@ Result InputRedirection_DoOrUndoPatches(void) res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); } + svcCloseHandle(processHandle); return res; } diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 1714101..e7fe6d8 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -41,6 +41,7 @@ void __appInit() { srvSysInit(); fsregInit(); + fsSysInit(); s64 dummy; diff --git a/sysmodules/rosalina/source/menus/process_patches.c b/sysmodules/rosalina/source/menus/process_patches.c index 86604e9..cfec643 100644 --- a/sysmodules/rosalina/source/menus/process_patches.c +++ b/sysmodules/rosalina/source/menus/process_patches.c @@ -145,7 +145,7 @@ static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result res = func(textTotalRoundedSize); - svcUnmapProcessMemory(processHandle, 0x00100000, textTotalRoundedSize); + svcUnmapProcessMemoryEx(processHandle, 0x00100000, textTotalRoundedSize); return res; }