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 (*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);

View File

@ -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);

View File

@ -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++);

View File

@ -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)
{

View File

@ -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);

View File

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

View File

@ -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];

View File

@ -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;
}

View File

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

View File

@ -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;
}