From 461035b2127b0d404350a115cdee5ea23905ba9d Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 8 Jun 2017 21:35:41 +0200 Subject: [PATCH] Fix bug(s), refactor svcConnectToPortInitHook.s, cleanup --- patches/svcConnectToPortInitHook.s | 31 ++++++------------ source/patches.c | 6 ++-- .../rosalina/kernel_extension/include/ipc.h | 2 +- .../rosalina/kernel_extension/source/ipc.c | 2 +- .../rosalina/kernel_extension/source/main.c | 32 ++++++++----------- .../rosalina/kernel_extension/source/start.s | 4 +++ .../source/svc/SendSyncRequest.c | 16 +++++----- .../rosalina/source/kernel_extension_setup.c | 2 ++ 8 files changed, 42 insertions(+), 53 deletions(-) diff --git a/patches/svcConnectToPortInitHook.s b/patches/svcConnectToPortInitHook.s index b5daadd..258794c 100644 --- a/patches/svcConnectToPortInitHook.s +++ b/patches/svcConnectToPortInitHook.s @@ -2,15 +2,19 @@ .create "build/svcConnectToPortInitHook.bin", 0 .arm + b skip_vars +vars: + orig: .word 0 + SleepThread: .word 0 +skip_vars: push {r0-r4, lr} - adr r0, jumpAddress - bl convertVAToPA - orr r4, r0, #(1 << 31) + ldr r4, =0x1ff81108 loop: - ldr r12, [r4] + ldrb r12, [r4] cmp r12, #0 bne loop_end + ldr r12, [SleepThread] ldr r0, =(10 * 1000 * 1000) mov r1, #0 @@ -19,25 +23,10 @@ loop_end: pop {r0-r4, lr} + mov r12, #0x40000000 + add r12, #4 bx r12 -convertVAToPA: - mov r1, #0x1000 - sub r1, #1 - and r2, r0, r1 - bic r0, r1 - mcr p15, 0, r0, c7, c8, 0 ; VA to PA translation with privileged read permission check - mrc p15, 0, r0, c7, c4, 0 ; read PA register - tst r0, #1 ; failure bit - bic r0, r1 - addeq r0, r2 - movne r0, #0 - bx lr - .pool -_base: .ascii "base" -jumpAddressOrig: .ascii "orig" -SleepThread: .ascii "SlpT" -jumpAddress: .word 0 .close diff --git a/source/patches.c b/source/patches.c index df193ee..b76de60 100644 --- a/source/patches.c +++ b/source/patches.c @@ -186,9 +186,9 @@ void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPag arm11SvcTable[0x2D] = addr; memcpy(*freeK11Space, svcConnectToPortInitHook_bin, svcConnectToPortInitHook_bin_size); - u32 *off = (u32 *)memsearch(*freeK11Space, "orig", svcConnectToPortInitHook_bin_size, 4); - off[0] = svcConnectToPortAddr; - off[1] = svcSleepThreadAddr; + u32 *off = (u32 *)(*freeK11Space); + off[1] = svcConnectToPortAddr; + off[2] = svcSleepThreadAddr; (*freeK11Space) += svcConnectToPortInitHook_bin_size; } diff --git a/sysmodules/rosalina/kernel_extension/include/ipc.h b/sysmodules/rosalina/kernel_extension/include/ipc.h index c307d19..6e8a5ec 100644 --- a/sysmodules/rosalina/kernel_extension/include/ipc.h +++ b/sysmodules/rosalina/kernel_extension/include/ipc.h @@ -56,6 +56,6 @@ void SessionInfo_ChangeVtable(KSession *session); void SessionInfo_Add(KSession *session, const char *name); void SessionInfo_Remove(KSession *session); -bool doLangEmu(Result *res, Handle handle, u32 *cmdbuf); +bool doLangEmu(Result *res, u32 *cmdbuf); Result doPublishToProcessHook(Handle handle, u32 *cmdbuf); bool doErrfThrowHook(u32 *cmdbuf); diff --git a/sysmodules/rosalina/kernel_extension/source/ipc.c b/sysmodules/rosalina/kernel_extension/source/ipc.c index 9f8f296..148d6eb 100644 --- a/sysmodules/rosalina/kernel_extension/source/ipc.c +++ b/sysmodules/rosalina/kernel_extension/source/ipc.c @@ -182,7 +182,7 @@ void SessionInfo_ChangeVtable(KSession *session) session->autoObject.vtable = (Vtable__KAutoObject *)customSessionVtable; } -bool doLangEmu(Result *res, Handle handle, u32 *cmdbuf) +bool doLangEmu(Result *res, u32 *cmdbuf) { KRecursiveLock__Lock(criticalSectionLock); KRecursiveLock__Lock(&processLangemuLock); diff --git a/sysmodules/rosalina/kernel_extension/source/main.c b/sysmodules/rosalina/kernel_extension/source/main.c index 0b20ef9..237e917 100644 --- a/sysmodules/rosalina/kernel_extension/source/main.c +++ b/sysmodules/rosalina/kernel_extension/source/main.c @@ -58,7 +58,6 @@ static inline void swapHandlerInVeneer(enum VECTORS vector, void *handler) *(void**)PA_FROM_VA_PTR(dst) = handler; } -static u32 *trampo_; static bool **enableUserExceptionHandlersForCPUExcLoc; static bool enableUserExceptionHandlersForCPUExc = true; @@ -70,15 +69,12 @@ static void setupSvcHandler(void) while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL) memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E); - u32 *off; - for(off = (u32 *)officialSVCs[0x2D]; *off != 0x65736162; off++); - *(void **)PA_FROM_VA_PTR(arm11SvcTable + 0x2D) = officialSVCs[0x2D] = (void *)off[1]; - trampo_ = (u32 *)PA_FROM_VA_PTR(off + 3); + officialSVCs[0x2D] = *((void **)officialSVCs[0x2D] + 1); CustomBackdoor = (Result (*)(void *, ...))((u32 *)officialSVCs[0x2F] + 2); - *(void **)PA_FROM_VA_PTR(arm11SvcTable + 0x2F) = officialSVCs[0x2F] = (void *)*((u32 *)officialSVCs[0x2F] + 1); + officialSVCs[0x2F] = *((void **)officialSVCs[0x2F] + 1); - off = (u32 *)originalHandlers[(u32) SVC]; + u32 *off = (u32 *)originalHandlers[(u32) SVC]; while(*off++ != 0xE1A00009); svcFallbackHandler = (void (*)(u8))decodeARMBranch(off); for(; *off != 0xE92D000F; off++); @@ -201,12 +197,12 @@ static void findUsefulSymbols(void) KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1); for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++); - kernelpanic = (void (*)(void))off; + kernelpanic = (void (*)(void))decodeARMBranch(off + 1); for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++); SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2); - for(; *off != 0x96007F9; off++); + for(off = (u32 *)PA_FROM_VA_PTR(off); *off != 0x96007F9; off++); isDevUnit = *(bool **)(off - 1); enableUserExceptionHandlersForCPUExcLoc = (bool **)(off + 1); @@ -217,7 +213,7 @@ static void findUsefulSymbols(void) u32 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[0][6].interruptEvent->vtable) & ~0xFFF; u32 textSize = rodataStart - textStart; - for(off = (u32 *)textStart; off < (u32 *)(textStart + textSize) - 3; off++) + for(off = (u32 *)textStart; off < (u32 *)(textStart + textSize - 12); off++) { if(off[0] == 0xE5D13034 && off[1] == 0xE1530002) KScheduler__AdjustThread = (void (*)(KScheduler *, KThread *, u32))off; @@ -253,14 +249,14 @@ struct Parameters static void enableDebugFeatures(void) { *isDevUnit = true; // for debug SVCs and user exc. handlers, etc. - *(bool **)PA_FROM_VA_PTR(enableUserExceptionHandlersForCPUExcLoc) = &enableUserExceptionHandlersForCPUExc; + *enableUserExceptionHandlersForCPUExcLoc = &enableUserExceptionHandlersForCPUExc; u32 *off; - for(off = (u32 *)officialSVCs[0x7C]; off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++); - *(u32 *)PA_FROM_VA_PTR(off + 2) = 0xE1A00000; // in case 6: beq -> nop + for(off = (u32 *)PA_FROM_VA_PTR(KernelSetState); off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++); + off[2] = 0xE1A00000; // in case 6: beq -> nop - for(off = (u32 *)DebugActiveProcess; *off != 0xE3110001; off++); - *(u32 *)PA_FROM_VA_PTR(off) = 0xE3B01001; // tst r1, #1 -> movs r1, #1 + for(off = (u32 *)PA_FROM_VA_PTR(DebugActiveProcess); *off != 0xE3110001; off++); + *off = 0xE3B01001; // tst r1, #1 -> movs r1, #1 } static void doOtherPatches(void) @@ -269,7 +265,7 @@ static void doOtherPatches(void) *(u32 *)PA_FROM_VA_PTR(kpanic) = 0xE12FFF7E; // bkpt 0xFFFE u32 *off; - for(off = (u32 *)ControlMemory; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++); + for(off = (u32 *)PA_FROM_VA_PTR(ControlMemory); (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++); off -= 2; /* @@ -279,8 +275,7 @@ static void doOtherPatches(void) It effectively changes the prototype of the ControlMemory function which only caller is the svc 0x01 handler on OFW. */ - *(u32 *)PA_FROM_VA_PTR(off) = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)ControlMemory)); // ldr r0, [sp, #(frameSize + 8)] - + *(u32 *)PA_FROM_VA_PTR(off) = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)PA_FROM_VA_PTR(ControlMemory))); // ldr r0, [sp, #(frameSize + 8)] } void main(volatile struct Parameters *p) @@ -306,5 +301,4 @@ void main(volatile struct Parameters *p) rosalinaState = 0; hasStartedRosalinaNetworkFuncsOnce = false; - *trampo_ = (u32)ConnectToPortHookWrapper; } diff --git a/sysmodules/rosalina/kernel_extension/source/start.s b/sysmodules/rosalina/kernel_extension/source/start.s index 8c7aedf..f401779 100644 --- a/sysmodules/rosalina/kernel_extension/source/start.s +++ b/sysmodules/rosalina/kernel_extension/source/start.s @@ -26,6 +26,10 @@ .balign 4 .global _start _start: + b start + b ConnectToPortHookWrapper + +start: push {r4, lr} mrc p15, 0, r4, c0, c0, 5 @ CPUID register diff --git a/sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c b/sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c index a70c8aa..8cd4012 100644 --- a/sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c +++ b/sysmodules/rosalina/kernel_extension/source/svc/SendSyncRequest.c @@ -73,7 +73,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && (strcmp(info->name, "cfg:u") == 0 || strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk2 - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -91,7 +91,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && (strcmp(info->name, "cfg:u") == 0 || strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // SecureInfoGetRegion - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -176,7 +176,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4 - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -185,7 +185,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk8 - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -194,7 +194,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4 - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -203,7 +203,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); if(info != NULL && strcmp(info->name, "cfg:i") == 0) // GetConfigInfoBlk8 - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -212,7 +212,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } @@ -221,7 +221,7 @@ Result SendSyncRequestHook(Handle handle) { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion if(info != NULL && strcmp(info->name, "cfg:i") == 0) - skip = doLangEmu(&res, handle, cmdbuf); + skip = doLangEmu(&res, cmdbuf); break; } diff --git a/sysmodules/rosalina/source/kernel_extension_setup.c b/sysmodules/rosalina/source/kernel_extension_setup.c index 24bc07f..d0ed5fa 100644 --- a/sysmodules/rosalina/source/kernel_extension_setup.c +++ b/sysmodules/rosalina/source/kernel_extension_setup.c @@ -143,4 +143,6 @@ void installKernelExtension(void) flushAllCaches(); svc0x2F(K_SendSGI0ToAllCores); flushAllCaches(); + + *(volatile bool *)0x1FF81108 = true; }