Fix bug(s), refactor svcConnectToPortInitHook.s, cleanup

This commit is contained in:
TuxSH 2017-06-08 21:35:41 +02:00
parent 427a05997d
commit 461035b212
8 changed files with 42 additions and 53 deletions

View File

@ -2,15 +2,19 @@
.create "build/svcConnectToPortInitHook.bin", 0 .create "build/svcConnectToPortInitHook.bin", 0
.arm .arm
b skip_vars
vars:
orig: .word 0
SleepThread: .word 0
skip_vars:
push {r0-r4, lr} push {r0-r4, lr}
adr r0, jumpAddress ldr r4, =0x1ff81108
bl convertVAToPA
orr r4, r0, #(1 << 31)
loop: loop:
ldr r12, [r4] ldrb r12, [r4]
cmp r12, #0 cmp r12, #0
bne loop_end bne loop_end
ldr r12, [SleepThread] ldr r12, [SleepThread]
ldr r0, =(10 * 1000 * 1000) ldr r0, =(10 * 1000 * 1000)
mov r1, #0 mov r1, #0
@ -19,25 +23,10 @@
loop_end: loop_end:
pop {r0-r4, lr} pop {r0-r4, lr}
mov r12, #0x40000000
add r12, #4
bx r12 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 .pool
_base: .ascii "base"
jumpAddressOrig: .ascii "orig"
SleepThread: .ascii "SlpT"
jumpAddress: .word 0
.close .close

View File

@ -186,9 +186,9 @@ void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPag
arm11SvcTable[0x2D] = addr; arm11SvcTable[0x2D] = addr;
memcpy(*freeK11Space, svcConnectToPortInitHook_bin, svcConnectToPortInitHook_bin_size); memcpy(*freeK11Space, svcConnectToPortInitHook_bin, svcConnectToPortInitHook_bin_size);
u32 *off = (u32 *)memsearch(*freeK11Space, "orig", svcConnectToPortInitHook_bin_size, 4); u32 *off = (u32 *)(*freeK11Space);
off[0] = svcConnectToPortAddr; off[1] = svcConnectToPortAddr;
off[1] = svcSleepThreadAddr; off[2] = svcSleepThreadAddr;
(*freeK11Space) += svcConnectToPortInitHook_bin_size; (*freeK11Space) += svcConnectToPortInitHook_bin_size;
} }

View File

@ -56,6 +56,6 @@ void SessionInfo_ChangeVtable(KSession *session);
void SessionInfo_Add(KSession *session, const char *name); void SessionInfo_Add(KSession *session, const char *name);
void SessionInfo_Remove(KSession *session); 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); Result doPublishToProcessHook(Handle handle, u32 *cmdbuf);
bool doErrfThrowHook(u32 *cmdbuf); bool doErrfThrowHook(u32 *cmdbuf);

View File

@ -182,7 +182,7 @@ void SessionInfo_ChangeVtable(KSession *session)
session->autoObject.vtable = (Vtable__KAutoObject *)customSessionVtable; 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(criticalSectionLock);
KRecursiveLock__Lock(&processLangemuLock); KRecursiveLock__Lock(&processLangemuLock);

View File

@ -58,7 +58,6 @@ static inline void swapHandlerInVeneer(enum VECTORS vector, void *handler)
*(void**)PA_FROM_VA_PTR(dst) = handler; *(void**)PA_FROM_VA_PTR(dst) = handler;
} }
static u32 *trampo_;
static bool **enableUserExceptionHandlersForCPUExcLoc; static bool **enableUserExceptionHandlersForCPUExcLoc;
static bool enableUserExceptionHandlersForCPUExc = true; static bool enableUserExceptionHandlersForCPUExc = true;
@ -70,15 +69,12 @@ static void setupSvcHandler(void)
while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL) while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL)
memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E); memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E);
u32 *off; officialSVCs[0x2D] = *((void **)officialSVCs[0x2D] + 1);
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);
CustomBackdoor = (Result (*)(void *, ...))((u32 *)officialSVCs[0x2F] + 2); 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); while(*off++ != 0xE1A00009);
svcFallbackHandler = (void (*)(u8))decodeARMBranch(off); svcFallbackHandler = (void (*)(u8))decodeARMBranch(off);
for(; *off != 0xE92D000F; off++); for(; *off != 0xE92D000F; off++);
@ -201,12 +197,12 @@ static void findUsefulSymbols(void)
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1); KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++); 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++); for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2); 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); isDevUnit = *(bool **)(off - 1);
enableUserExceptionHandlersForCPUExcLoc = (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 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[0][6].interruptEvent->vtable) & ~0xFFF;
u32 textSize = rodataStart - textStart; 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) if(off[0] == 0xE5D13034 && off[1] == 0xE1530002)
KScheduler__AdjustThread = (void (*)(KScheduler *, KThread *, u32))off; KScheduler__AdjustThread = (void (*)(KScheduler *, KThread *, u32))off;
@ -253,14 +249,14 @@ struct Parameters
static void enableDebugFeatures(void) static void enableDebugFeatures(void)
{ {
*isDevUnit = true; // for debug SVCs and user exc. handlers, etc. *isDevUnit = true; // for debug SVCs and user exc. handlers, etc.
*(bool **)PA_FROM_VA_PTR(enableUserExceptionHandlersForCPUExcLoc) = &enableUserExceptionHandlersForCPUExc; *enableUserExceptionHandlersForCPUExcLoc = &enableUserExceptionHandlersForCPUExc;
u32 *off; u32 *off;
for(off = (u32 *)officialSVCs[0x7C]; off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++); for(off = (u32 *)PA_FROM_VA_PTR(KernelSetState); off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++);
*(u32 *)PA_FROM_VA_PTR(off + 2) = 0xE1A00000; // in case 6: beq -> nop off[2] = 0xE1A00000; // in case 6: beq -> nop
for(off = (u32 *)DebugActiveProcess; *off != 0xE3110001; off++); for(off = (u32 *)PA_FROM_VA_PTR(DebugActiveProcess); *off != 0xE3110001; off++);
*(u32 *)PA_FROM_VA_PTR(off) = 0xE3B01001; // tst r1, #1 -> movs r1, #1 *off = 0xE3B01001; // tst r1, #1 -> movs r1, #1
} }
static void doOtherPatches(void) static void doOtherPatches(void)
@ -269,7 +265,7 @@ static void doOtherPatches(void)
*(u32 *)PA_FROM_VA_PTR(kpanic) = 0xE12FFF7E; // bkpt 0xFFFE *(u32 *)PA_FROM_VA_PTR(kpanic) = 0xE12FFF7E; // bkpt 0xFFFE
u32 *off; 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; off -= 2;
/* /*
@ -279,8 +275,7 @@ static void doOtherPatches(void)
It effectively changes the prototype of the ControlMemory function which It effectively changes the prototype of the ControlMemory function which
only caller is the svc 0x01 handler on OFW. 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) void main(volatile struct Parameters *p)
@ -306,5 +301,4 @@ void main(volatile struct Parameters *p)
rosalinaState = 0; rosalinaState = 0;
hasStartedRosalinaNetworkFuncsOnce = false; hasStartedRosalinaNetworkFuncsOnce = false;
*trampo_ = (u32)ConnectToPortHookWrapper;
} }

View File

@ -26,6 +26,10 @@
.balign 4 .balign 4
.global _start .global _start
_start: _start:
b start
b ConnectToPortHookWrapper
start:
push {r4, lr} push {r4, lr}
mrc p15, 0, r4, c0, c0, 5 @ CPUID register mrc p15, 0, r4, c0, c0, 5 @ CPUID register

View File

@ -73,7 +73,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); 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 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; break;
} }
@ -91,7 +91,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); 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 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; break;
} }
@ -176,7 +176,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4 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; break;
} }
@ -185,7 +185,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk8 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; break;
} }
@ -194,7 +194,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4 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; break;
} }
@ -203,7 +203,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && strcmp(info->name, "cfg:i") == 0) // GetConfigInfoBlk8 if(info != NULL && strcmp(info->name, "cfg:i") == 0) // GetConfigInfoBlk8
skip = doLangEmu(&res, handle, cmdbuf); skip = doLangEmu(&res, cmdbuf);
break; break;
} }
@ -212,7 +212,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) 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; break;
} }
@ -221,7 +221,7 @@ Result SendSyncRequestHook(Handle handle)
{ {
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion
if(info != NULL && strcmp(info->name, "cfg:i") == 0) if(info != NULL && strcmp(info->name, "cfg:i") == 0)
skip = doLangEmu(&res, handle, cmdbuf); skip = doLangEmu(&res, cmdbuf);
break; break;
} }

View File

@ -143,4 +143,6 @@ void installKernelExtension(void)
flushAllCaches(); flushAllCaches();
svc0x2F(K_SendSGI0ToAllCores); svc0x2F(K_SendSGI0ToAllCores);
flushAllCaches(); flushAllCaches();
*(volatile bool *)0x1FF81108 = true;
} }