mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Detect and use the CFW jit patch.
This commit is contained in:
parent
16cbf1c9f6
commit
fc557cbf2a
@ -19,3 +19,6 @@ bool kernelAbove500(void);
|
||||
bool kernelAbove600(void);
|
||||
/// Returns true if the process has a debugger attached.
|
||||
bool detectDebugger(void);
|
||||
|
||||
/// Returns true if the kernel is patched to allow self-process-jit.
|
||||
bool detectCfwJitPatch(void);
|
||||
|
@ -1,26 +1,32 @@
|
||||
// Copyright 2017 plutoo
|
||||
#include "types.h"
|
||||
#include "result.h"
|
||||
#include "kernel/detect.h"
|
||||
#include "kernel/mutex.h"
|
||||
#include "kernel/svc.h"
|
||||
#include <malloc.h>
|
||||
|
||||
static bool g_VersionCached = 0;
|
||||
static Mutex g_VersionMutex;
|
||||
static bool g_IsAbove200;
|
||||
static bool g_IsAbove300;
|
||||
static bool g_IsAbove400;
|
||||
static bool g_IsAbove500;
|
||||
static bool g_IsAbove600;
|
||||
static bool g_HasCached = 0;
|
||||
static Mutex g_Mutex;
|
||||
|
||||
static void _CacheValues(void)
|
||||
static bool g_CfwJitCached = 0;
|
||||
static Mutex g_CfwJitMutex;
|
||||
static bool g_CfwJitPatchDetected;
|
||||
|
||||
static void _CacheVersion(void)
|
||||
{
|
||||
if (__atomic_load_n(&g_HasCached, __ATOMIC_SEQ_CST))
|
||||
if (__atomic_load_n(&g_VersionCached, __ATOMIC_SEQ_CST))
|
||||
return;
|
||||
|
||||
mutexLock(&g_Mutex);
|
||||
mutexLock(&g_VersionMutex);
|
||||
|
||||
if (g_HasCached) {
|
||||
mutexUnlock(&g_Mutex);
|
||||
if (g_VersionCached) {
|
||||
mutexUnlock(&g_VersionMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -36,33 +42,71 @@ static void _CacheValues(void)
|
||||
g_IsAbove300 |= g_IsAbove400;
|
||||
g_IsAbove200 |= g_IsAbove300;
|
||||
|
||||
__atomic_store_n(&g_HasCached, true, __ATOMIC_SEQ_CST);
|
||||
__atomic_store_n(&g_VersionCached, true, __ATOMIC_SEQ_CST);
|
||||
|
||||
mutexUnlock(&g_Mutex);
|
||||
mutexUnlock(&g_VersionMutex);
|
||||
}
|
||||
|
||||
static void _CacheCfwJit(void)
|
||||
{
|
||||
if (__atomic_load_n(&g_CfwJitCached, __ATOMIC_SEQ_CST))
|
||||
return;
|
||||
|
||||
mutexLock(&g_CfwJitMutex);
|
||||
|
||||
if (g_CfwJitCached) {
|
||||
mutexUnlock(&g_CfwJitMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
void* heap = memalign(0x1000, 0x1000);
|
||||
|
||||
if (heap != NULL)
|
||||
{
|
||||
Handle code;
|
||||
Result rc;
|
||||
rc = svcCreateCodeMemory(&code, heap, 0x1000);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
// On an unpatched kernel on 5.0.0 and above, this would return 0xD401.
|
||||
// It is not allowed for the creator-process of a CodeMemory object to use svcControlCodeMemory on it.
|
||||
rc = svcControlCodeMemory(code, -1, 0, 0x1000, 0);
|
||||
|
||||
g_CfwJitPatchDetected = (rc == 0xF001);
|
||||
__atomic_store_n(&g_CfwJitCached, true, __ATOMIC_SEQ_CST);
|
||||
|
||||
svcCloseHandle(code);
|
||||
}
|
||||
|
||||
free(heap);
|
||||
}
|
||||
|
||||
mutexUnlock(&g_CfwJitMutex);
|
||||
}
|
||||
|
||||
bool kernelAbove200(void) {
|
||||
_CacheValues();
|
||||
_CacheVersion();
|
||||
return g_IsAbove200;
|
||||
}
|
||||
|
||||
bool kernelAbove300(void) {
|
||||
_CacheValues();
|
||||
_CacheVersion();
|
||||
return g_IsAbove300;
|
||||
}
|
||||
|
||||
bool kernelAbove400(void) {
|
||||
_CacheValues();
|
||||
_CacheVersion();
|
||||
return g_IsAbove400;
|
||||
}
|
||||
|
||||
bool kernelAbove500(void) {
|
||||
_CacheValues();
|
||||
_CacheVersion();
|
||||
return g_IsAbove500;
|
||||
}
|
||||
|
||||
bool kernelAbove600(void) {
|
||||
_CacheValues();
|
||||
_CacheVersion();
|
||||
return g_IsAbove600;
|
||||
}
|
||||
|
||||
@ -71,3 +115,8 @@ bool detectDebugger(void) {
|
||||
svcGetInfo(&tmp, 8, 0, 0);
|
||||
return !!tmp;
|
||||
}
|
||||
|
||||
bool detectCfwJitPatch(void) {
|
||||
_CacheCfwJit();
|
||||
return g_CfwJitPatchDetected;
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ Result jitCreate(Jit* j, size_t size)
|
||||
|
||||
// Use new jit primitive introduced in 4.0.0, if available.
|
||||
// Not usable with 5.0.0+ since svcMapJitMemory doesn't allow using that SVC under the same process which owns that object.
|
||||
if (kernelAbove400() && !kernelAbove500() && envIsSyscallHinted(0x4B) && envIsSyscallHinted(0x4C)) {
|
||||
type = JitType_JitMemory;
|
||||
if (kernelAbove400() && envIsSyscallHinted(0x4B) && envIsSyscallHinted(0x4C)
|
||||
&& (!kernelAbove500() || detectCfwJitPatch())) {
|
||||
type = JitType_JitMemory;
|
||||
}
|
||||
// Fall back to MapProcessCodeMemory if available.
|
||||
else if (envIsSyscallHinted(0x73) && envIsSyscallHinted(0x77) && envIsSyscallHinted(0x78)
|
||||
|
Loading…
Reference in New Issue
Block a user