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)
This commit is contained in:
TuxSH 2017-06-16 04:21:48 +02:00
parent 9ccfacd06d
commit b71dedccfc
10 changed files with 43 additions and 21 deletions

View File

@ -64,6 +64,7 @@ extern Result (*SendSyncRequest)(Handle handle);
extern Result (*OpenProcess)(Handle *out, u32 processId); extern Result (*OpenProcess)(Handle *out, u32 processId);
extern Result (*GetProcessId)(u32 *out, Handle process); extern Result (*GetProcessId)(u32 *out, Handle process);
extern Result (*DebugActiveProcess)(Handle *out, u32 processId); 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 Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3);
extern void (*flushDataCacheRange)(void *addr, u32 len); extern void (*flushDataCacheRange)(void *addr, u32 len);

View File

@ -60,6 +60,7 @@ Result (*SendSyncRequest)(Handle handle);
Result (*OpenProcess)(Handle *out, u32 processId); Result (*OpenProcess)(Handle *out, u32 processId);
Result (*GetProcessId)(u32 *out, Handle process); Result (*GetProcessId)(u32 *out, Handle process);
Result (*DebugActiveProcess)(Handle *out, u32 processId); Result (*DebugActiveProcess)(Handle *out, u32 processId);
Result (*UnmapProcessMemory)(Handle processHandle, void *dst, u32 size);
Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3); Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3);
void (*flushDataCacheRange)(void *addr, u32 len); void (*flushDataCacheRange)(void *addr, u32 len);

View File

@ -96,7 +96,6 @@ void configHook(vu8 *cfgPage)
*isDevUnit = true; // enable debug features *isDevUnit = true; // enable debug features
} }
void wat(u32 a, ...);
static void findUsefulSymbols(void) static void findUsefulSymbols(void)
{ {
u32 *off; u32 *off;
@ -116,11 +115,11 @@ static void findUsefulSymbols(void)
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]); KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]);
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE28DD014; off++); for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++);
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off - 1); KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off + 1);
for(; *off != 0xE8BD80F0; off++); for(; *off != 0xE320F000; off++);
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 2); KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 1);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++); for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
off -= 2; off -= 2;
@ -142,8 +141,8 @@ static void findUsefulSymbols(void)
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++); for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6); WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE20030FF; off++); for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++);
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off + 2); KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off - 1);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++); for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
threadList = *(KObjectList **)(off + 1); threadList = *(KObjectList **)(off + 1);
@ -159,6 +158,7 @@ static void findUsefulSymbols(void)
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++); for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1); 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++); for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1); 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); OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3);
GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3); GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3);
DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 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); KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++); for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);

View File

@ -45,7 +45,7 @@ Result SendSyncRequestHook(Handle handle)
isValidClientSession = tok.flags == 0xA5; isValidClientSession = tok.flags == 0xA5;
} }
else if(clientSession != NULL) // not the exact same test but it should work 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) if(isValidClientSession)
{ {

View File

@ -24,10 +24,14 @@
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include "globals.h"
#include "svc/MapProcessMemoryEx.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); KProcessHwInfo *currentHwInfo = hwInfoOfProcess(currentCoreContext->objectContext.currentProcess);
Result res = KProcessHwInfo__UnmapProcessMemory(currentHwInfo, dst, size >> 12); Result res = KProcessHwInfo__UnmapProcessMemory(currentHwInfo, dst, size >> 12);

View File

@ -118,11 +118,6 @@ safecpy:
_safecpy_end: _safecpy_end:
.global wat
.type wat, %function
wat:
bkpt 1
bx lr
.section .rodata .section .rodata
.global safecpy_sz .global safecpy_sz

View File

@ -283,6 +283,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
res = HBLDR_Init(&hbldr); res = HBLDR_Init(&hbldr);
if (R_FAILED(res)) if (R_FAILED(res))
{ {
svcBreak(USERBREAK_ASSERT);
return res; return res;
} }
u32* cmdbuf = getThreadCommandBuffer(); u32* cmdbuf = getThreadCommandBuffer();
@ -300,6 +301,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
} }
if (R_FAILED(res)) if (R_FAILED(res))
{ {
svcBreak(USERBREAK_ASSERT);
return res; return res;
} }
codeset = (Handle)cmdbuf[3]; codeset = (Handle)cmdbuf[3];

View File

@ -223,9 +223,10 @@ Result InputRedirection_DoOrUndoPatches(void)
res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize);
} }
svcCloseHandle(processHandle);
res = OpenProcessByName("ir", &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(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data
svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003);
@ -238,6 +239,7 @@ Result InputRedirection_DoOrUndoPatches(void)
if(R_SUCCEEDED(res)) if(R_SUCCEEDED(res))
{ {
static bool useOldSyncCode;
static u32 irOrigReadingCode[5] = { static u32 irOrigReadingCode[5] = {
0xE5940000, // ldr r0, [r4] 0xE5940000, // ldr r0, [r4]
0xE1A01005, // mov r1, r5 0xE1A01005, // mov r1, r5
@ -250,7 +252,10 @@ Result InputRedirection_DoOrUndoPatches(void)
0xEF000024, // svc 0x24 (WaitSynchronization) 0xEF000024, // svc 0x24 (WaitSynchronization)
0xE1B01FA0, // movs r1, r0, lsr#31 0xE1B01FA0, // movs r1, r0, lsr#31
0xE1A0A000, // mov r10, r0 0xE1A0A000, // mov r10, r0
}; }, irOrigWaitSyncCodeOld[] = {
0xE0AC6000, // adc r6, r12, r0
0xE5D70000, // ldrb r0, [r7]
}; // pattern for 8.1
static const u32 irOrigCppFlagCode[] = { static const u32 irOrigCppFlagCode[] = {
0xE3550000, // cmp r5, #0 0xE3550000, // cmp r5, #0
@ -262,6 +267,9 @@ Result InputRedirection_DoOrUndoPatches(void)
if(inputRedirectionEnabled) if(inputRedirectionEnabled)
{ {
memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode)); memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode));
if(useOldSyncCode)
memcpy(irWaitSyncLoc, &irOrigWaitSyncCodeOld, sizeof(irOrigWaitSyncCodeOld));
else
memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode)); memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode));
memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode)); memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode));
} }
@ -287,11 +295,19 @@ Result InputRedirection_DoOrUndoPatches(void)
u32 *off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCode, totalSize, sizeof(irOrigWaitSyncCode)); u32 *off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCode, totalSize, sizeof(irOrigWaitSyncCode));
if(off2 == NULL) if(off2 == NULL)
{
off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCodeOld, totalSize, sizeof(irOrigWaitSyncCodeOld));
if(off2 == NULL)
{ {
svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize);
return -5; return -5;
} }
useOldSyncCode = true;
}
else
useOldSyncCode = false;
u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &irOrigCppFlagCode, totalSize, sizeof(irOrigCppFlagCode)); u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &irOrigCppFlagCode, totalSize, sizeof(irOrigCppFlagCode));
if(off3 == NULL) if(off3 == NULL)
{ {
@ -310,7 +326,7 @@ Result InputRedirection_DoOrUndoPatches(void)
memcpy(irHookLoc, &irHook, sizeof(irHook)); 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 *irWaitSyncLoc = 0xE3A00000; // mov r0, #0
// This NOPs out a flag check in ir:user's CPP emulation // 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); res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize);
} }
svcCloseHandle(processHandle);
return res; return res;
} }

View File

@ -41,6 +41,7 @@ void __appInit()
{ {
srvSysInit(); srvSysInit();
fsregInit(); fsregInit();
fsSysInit(); fsSysInit();
s64 dummy; s64 dummy;

View File

@ -145,7 +145,7 @@ static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result
res = func(textTotalRoundedSize); res = func(textTotalRoundedSize);
svcUnmapProcessMemory(processHandle, 0x00100000, textTotalRoundedSize); svcUnmapProcessMemoryEx(processHandle, 0x00100000, textTotalRoundedSize);
return res; return res;
} }