kernel ext: perf improvements
This commit is contained in:
parent
3463effeae
commit
c64f94bc82
@ -27,6 +27,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern u32 kernelVersion;
|
extern u32 kernelVersion;
|
||||||
|
|
||||||
@ -1161,29 +1162,37 @@ offsetof(classname##O3DSPre8x, field)))
|
|||||||
#define KPROCESSHWINFO_GET_RVALUE(obj, field) *(KPROCESSHWINFO_GET_PTR(obj, field))
|
#define KPROCESSHWINFO_GET_RVALUE(obj, field) *(KPROCESSHWINFO_GET_PTR(obj, field))
|
||||||
#define KPROCESSHWINFO_GET_RVALUE_TYPE(type, obj, field) *(KPROCESSHWINFO_GET_PTR_TYPE(type, obj, field))
|
#define KPROCESSHWINFO_GET_RVALUE_TYPE(type, obj, field) *(KPROCESSHWINFO_GET_PTR_TYPE(type, obj, field))
|
||||||
|
|
||||||
|
extern u32 pidOffsetKProcess, hwInfoOffsetKProcess, codeSetOffsetKProcess, handleTableOffsetKProcess, debugOffsetKProcess;
|
||||||
|
|
||||||
static inline u32 idOfProcess(KProcess *process)
|
static inline u32 idOfProcess(KProcess *process)
|
||||||
{
|
{
|
||||||
return KPROCESS_GET_RVALUE(process, processId);
|
u32 id;
|
||||||
|
memcpy(&id, (const u8 *)process + pidOffsetKProcess, 4);
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline KProcessHwInfo *hwInfoOfProcess(KProcess *process)
|
static inline KProcessHwInfo *hwInfoOfProcess(KProcess *process)
|
||||||
{
|
{
|
||||||
return KPROCESS_GET_PTR_TYPE(KProcessHwInfo, process, hwInfo);
|
return (KProcessHwInfo *)((uintptr_t)process + hwInfoOffsetKProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline KCodeSet *codeSetOfProcess(KProcess *process)
|
static inline KCodeSet *codeSetOfProcess(KProcess *process)
|
||||||
{
|
{
|
||||||
return KPROCESS_GET_RVALUE(process, codeSet);
|
KCodeSet *cs;
|
||||||
|
memcpy(&cs, (const u8 *)process + codeSetOffsetKProcess, 4);
|
||||||
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline KProcessHandleTable *handleTableOfProcess(KProcess *process)
|
static inline KProcessHandleTable *handleTableOfProcess(KProcess *process)
|
||||||
{
|
{
|
||||||
return KPROCESS_GET_PTR(process, handleTable);
|
return (KProcessHandleTable *)((uintptr_t)process + handleTableOffsetKProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline KDebug *debugOfProcess(KProcess *process)
|
static inline KDebug *debugOfProcess(KProcess *process)
|
||||||
{
|
{
|
||||||
return KPROCESS_GET_RVALUE(process, debug);
|
KDebug *debug;
|
||||||
|
memcpy(&debug, (const u8 *)process + debugOffsetKProcess, 4);
|
||||||
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *classNameOfAutoObject(KAutoObject *object)
|
static inline const char *classNameOfAutoObject(KAutoObject *object)
|
||||||
|
@ -32,7 +32,9 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
extern void *officialSVCs[0x7E];
|
extern void *officialSVCs[0x7E];
|
||||||
|
extern void *alteredSvcTable[0x100];
|
||||||
|
|
||||||
|
void buildAlteredSvcTable(void);
|
||||||
|
|
||||||
void postprocessSvc(void);
|
void postprocessSvc(void);
|
||||||
void svcDefaultHandler(u8 svcId);
|
void svcDefaultHandler(u8 svcId);
|
||||||
void *svcHook(u8 *pageEnd);
|
|
||||||
|
@ -30,5 +30,7 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
|
|
||||||
|
extern bool svcSignalingEnabled;
|
||||||
|
|
||||||
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId);
|
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId);
|
||||||
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
||||||
|
@ -113,3 +113,5 @@ u32 stolenSystemMemRegionSize;
|
|||||||
|
|
||||||
vu32 rosalinaState;
|
vu32 rosalinaState;
|
||||||
bool hasStartedRosalinaNetworkFuncsOnce;
|
bool hasStartedRosalinaNetworkFuncsOnce;
|
||||||
|
|
||||||
|
u32 pidOffsetKProcess, hwInfoOffsetKProcess, codeSetOffsetKProcess, handleTableOffsetKProcess, debugOffsetKProcess;
|
||||||
|
@ -121,6 +121,12 @@ void configHook(vu8 *cfgPage)
|
|||||||
*(vu32 *)(configPage + 0x44) = fcramLayout.systemSize;
|
*(vu32 *)(configPage + 0x44) = fcramLayout.systemSize;
|
||||||
*(vu32 *)(configPage + 0x48) = fcramLayout.baseSize;
|
*(vu32 *)(configPage + 0x48) = fcramLayout.baseSize;
|
||||||
*isDevUnit = true; // enable debug features
|
*isDevUnit = true; // enable debug features
|
||||||
|
|
||||||
|
pidOffsetKProcess = KPROCESS_OFFSETOF(processId);
|
||||||
|
hwInfoOffsetKProcess = KPROCESS_OFFSETOF(hwInfo);
|
||||||
|
codeSetOffsetKProcess = KPROCESS_OFFSETOF(codeSet);
|
||||||
|
handleTableOffsetKProcess = KPROCESS_OFFSETOF(handleTable);
|
||||||
|
debugOffsetKProcess = KPROCESS_OFFSETOF(debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findUsefulSymbols(void)
|
static void findUsefulSymbols(void)
|
||||||
@ -302,6 +308,7 @@ void main(FcramLayout *layout, KCoreContext *ctxs)
|
|||||||
void **arm11SvcTable = (void**)originalHandlers[2];
|
void **arm11SvcTable = (void**)originalHandlers[2];
|
||||||
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);
|
||||||
|
buildAlteredSvcTable();
|
||||||
|
|
||||||
findUsefulSymbols();
|
findUsefulSymbols();
|
||||||
|
|
||||||
|
@ -47,28 +47,68 @@
|
|||||||
#include "svc/TranslateHandle.h"
|
#include "svc/TranslateHandle.h"
|
||||||
|
|
||||||
void *officialSVCs[0x7E] = {NULL};
|
void *officialSVCs[0x7E] = {NULL};
|
||||||
|
void *alteredSvcTable[0x100] = {NULL};
|
||||||
|
|
||||||
void signalSvcEntry(u8 *pageEnd)
|
static Result BreakHook(UserBreakType breakReason, const void* croInfo, u32 croInfoSize)
|
||||||
{
|
{
|
||||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
|
||||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||||
|
|
||||||
if(svcId == 0xFE)
|
void *funptr = (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
|
||||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
return ((Result (*)(UserBreakType, const void *, u32))funptr)(breakReason, croInfo, croInfoSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildAlteredSvcTable(void)
|
||||||
|
{
|
||||||
|
memcpy(alteredSvcTable, officialSVCs, 4 * 0x7E);
|
||||||
|
|
||||||
|
alteredSvcTable[0x01] = ControlMemoryHookWrapper;
|
||||||
|
|
||||||
|
alteredSvcTable[0x29] = GetHandleInfoHookWrapper;
|
||||||
|
alteredSvcTable[0x2A] = GetSystemInfoHookWrapper;
|
||||||
|
alteredSvcTable[0x2B] = GetProcessInfoHookWrapper;
|
||||||
|
alteredSvcTable[0x2C] = GetThreadInfoHookWrapper;
|
||||||
|
alteredSvcTable[0x2D] = ConnectToPortHookWrapper;
|
||||||
|
|
||||||
|
alteredSvcTable[0x32] = SendSyncRequestHook;
|
||||||
|
alteredSvcTable[0x3C] = BreakHook;
|
||||||
|
|
||||||
|
alteredSvcTable[0x59] = SetGpuProt;
|
||||||
|
alteredSvcTable[0x5A] = SetWifiEnabled;
|
||||||
|
|
||||||
|
alteredSvcTable[0x7B] = Backdoor;
|
||||||
|
alteredSvcTable[0x7C] = KernelSetStateHook;
|
||||||
|
|
||||||
|
// Custom SVCs past that point
|
||||||
|
alteredSvcTable[0x80] = CustomBackdoor;
|
||||||
|
|
||||||
|
alteredSvcTable[0x90] = convertVAToPA;
|
||||||
|
alteredSvcTable[0x91] = flushDataCacheRange;
|
||||||
|
alteredSvcTable[0x92] = flushEntireDataCache;
|
||||||
|
alteredSvcTable[0x93] = invalidateInstructionCacheRange;
|
||||||
|
alteredSvcTable[0x94] = invalidateEntireInstructionCache;
|
||||||
|
|
||||||
|
alteredSvcTable[0xA0] = MapProcessMemoryEx;
|
||||||
|
alteredSvcTable[0xA1] = UnmapProcessMemoryEx;
|
||||||
|
alteredSvcTable[0xA2] = ControlMemoryEx;
|
||||||
|
|
||||||
|
alteredSvcTable[0xB0] = ControlService;
|
||||||
|
alteredSvcTable[0xB1] = CopyHandleWrapper;
|
||||||
|
alteredSvcTable[0xB2] = TranslateHandleWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
void signalSvcEntry(u32 svcId)
|
||||||
|
{
|
||||||
|
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||||
|
|
||||||
// Since DBGEVENT_SYSCALL_ENTRY is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
// Since DBGEVENT_SYSCALL_ENTRY is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFE, svcId);
|
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFE, svcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signalSvcReturn(u8 *pageEnd)
|
void signalSvcReturn(u32 svcId)
|
||||||
{
|
{
|
||||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
|
||||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||||
|
|
||||||
if(svcId == 0xFE)
|
|
||||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x1FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
|
||||||
|
|
||||||
// Since DBGEVENT_SYSCALL_RETURN is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
// Since DBGEVENT_SYSCALL_RETURN is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFF, svcId);
|
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFF, svcId);
|
||||||
@ -82,71 +122,3 @@ void postprocessSvc(void)
|
|||||||
|
|
||||||
officialPostProcessSvc();
|
officialPostProcessSvc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *svcHook(u8 *pageEnd)
|
|
||||||
{
|
|
||||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
|
||||||
|
|
||||||
u32 svcId = *(u8 *)(pageEnd - 0xB5);
|
|
||||||
if(svcId == 0xFE)
|
|
||||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
|
||||||
switch(svcId)
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
return ControlMemoryHookWrapper;
|
|
||||||
case 0x29:
|
|
||||||
return GetHandleInfoHookWrapper;
|
|
||||||
case 0x2A:
|
|
||||||
return GetSystemInfoHookWrapper;
|
|
||||||
case 0x2B:
|
|
||||||
return GetProcessInfoHookWrapper;
|
|
||||||
case 0x2C:
|
|
||||||
return GetThreadInfoHookWrapper;
|
|
||||||
case 0x2D:
|
|
||||||
return ConnectToPortHookWrapper;
|
|
||||||
case 0x32:
|
|
||||||
return SendSyncRequestHook;
|
|
||||||
case 0x3C:
|
|
||||||
return (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
|
|
||||||
case 0x59:
|
|
||||||
return SetGpuProt;
|
|
||||||
case 0x5A:
|
|
||||||
return SetWifiEnabled;
|
|
||||||
case 0x7B:
|
|
||||||
return Backdoor;
|
|
||||||
case 0x7C:
|
|
||||||
return KernelSetStateHook;
|
|
||||||
|
|
||||||
|
|
||||||
case 0x80:
|
|
||||||
return CustomBackdoor;
|
|
||||||
|
|
||||||
case 0x90:
|
|
||||||
return convertVAToPA;
|
|
||||||
case 0x91:
|
|
||||||
return flushDataCacheRange;
|
|
||||||
case 0x92:
|
|
||||||
return flushEntireDataCache;
|
|
||||||
case 0x93:
|
|
||||||
return invalidateInstructionCacheRange;
|
|
||||||
case 0x94:
|
|
||||||
return invalidateEntireInstructionCache;
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
return MapProcessMemoryEx;
|
|
||||||
case 0xA1:
|
|
||||||
return UnmapProcessMemoryEx;
|
|
||||||
case 0xA2:
|
|
||||||
return ControlMemoryEx;
|
|
||||||
|
|
||||||
case 0xB0:
|
|
||||||
return ControlService;
|
|
||||||
case 0xB1:
|
|
||||||
return CopyHandleWrapper;
|
|
||||||
case 0xB2:
|
|
||||||
return TranslateHandleWrapper;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return (svcId <= 0x7D) ? officialSVCs[svcId] : NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -36,6 +36,8 @@ static u32 nbEnabled = 0;
|
|||||||
static u32 maskedPids[MAX_DEBUG];
|
static u32 maskedPids[MAX_DEBUG];
|
||||||
static u32 masks[MAX_DEBUG][8] = {0};
|
static u32 masks[MAX_DEBUG][8] = {0};
|
||||||
|
|
||||||
|
bool svcSignalingEnabled = false;
|
||||||
|
|
||||||
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId)
|
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId)
|
||||||
{
|
{
|
||||||
u32 pid = idOfProcess(process);
|
u32 pid = idOfProcess(process);
|
||||||
@ -65,6 +67,7 @@ Result SetSyscallDebugEventMask(u32 pid, bool enable, const u32 *mask)
|
|||||||
{
|
{
|
||||||
maskedPids[nbEnabled] = pid;
|
maskedPids[nbEnabled] = pid;
|
||||||
memcpy(&masks[nbEnabled++], tmpMask, 32);
|
memcpy(&masks[nbEnabled++], tmpMask, 32);
|
||||||
|
svcSignalingEnabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -84,6 +87,7 @@ Result SetSyscallDebugEventMask(u32 pid, bool enable, const u32 *mask)
|
|||||||
}
|
}
|
||||||
maskedPids[--nbEnabled] = 0;
|
maskedPids[--nbEnabled] = 0;
|
||||||
memset(&masks[nbEnabled], 0, 32);
|
memset(&masks[nbEnabled], 0, 32);
|
||||||
|
svcSignalingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
KRecursiveLock__Unlock(&syscallDebugEventMaskLock);
|
KRecursiveLock__Unlock(&syscallDebugEventMaskLock);
|
||||||
|
@ -43,22 +43,24 @@ svcHandler:
|
|||||||
strb r9, [sp, #0x58+3] @ page end - 0xb8 + 3: svc being handled
|
strb r9, [sp, #0x58+3] @ page end - 0xb8 + 3: svc being handled
|
||||||
strb r10, [sp, #0x58+1] @ page end - 0xb8 + 1: "allow debug" flag
|
strb r10, [sp, #0x58+1] @ page end - 0xb8 + 1: "allow debug" flag
|
||||||
|
|
||||||
@ sp = page end - 0x110
|
ldr r8, =alteredSvcTable
|
||||||
|
ldr r8, [r8, r9,lsl#2]
|
||||||
|
/*@ sp = page end - 0x110
|
||||||
add r0, sp, #0x110 @ page end
|
add r0, sp, #0x110 @ page end
|
||||||
bl svcHook
|
bl svcHook
|
||||||
cpsid i
|
cpsid i
|
||||||
mov r8, r0
|
mov r8, r0
|
||||||
ldmfd sp, {r0-r7, r12, lr}
|
ldmfd sp, {r0-r7, r12, lr}
|
||||||
|
*/
|
||||||
|
|
||||||
cmp r8, #0
|
cmp r8, #0
|
||||||
beq _fallback @ invalid svc, or svc 0xff (stop point)
|
beq _fallback @ invalid svc, or svc 0xff (stop point)
|
||||||
|
|
||||||
_handled_svc: @ unused label, just here for formatting
|
_handled_svc: @ unused label, just here for formatting
|
||||||
push {r0-r12, lr}
|
ldr r10, =svcSignalingEnabled @ should work, I guess
|
||||||
add r0, sp, #0x148
|
ldrb r10, [r10]
|
||||||
cpsie i
|
cmp r10, #0
|
||||||
bl signalSvcEntry
|
bne _call_svc_debugged @ returns to _fallback_end*/
|
||||||
cpsid i
|
|
||||||
pop {r0-r12, lr}
|
|
||||||
|
|
||||||
cpsie i
|
cpsie i
|
||||||
blx r8
|
blx r8
|
||||||
@ -82,16 +84,10 @@ svcHandler:
|
|||||||
popne {r0-r7, r12}
|
popne {r0-r7, r12}
|
||||||
add sp, #4
|
add sp, #4
|
||||||
|
|
||||||
cmp r9, #0xff
|
ldr r10, =svcSignalingEnabled @ should work, I guess
|
||||||
beq _no_signal_return
|
ldr r10, [r10]
|
||||||
|
cmp r10, #0
|
||||||
push {r0-r7, r12, lr}
|
bne _signal_svc_end @ returns to _no_signal_return
|
||||||
add r0, sp, #0x110 @ page end
|
|
||||||
cpsie i
|
|
||||||
bl signalSvcReturn
|
|
||||||
cpsid i
|
|
||||||
pop {r0-r7, r12}
|
|
||||||
add sp, #4
|
|
||||||
|
|
||||||
_no_signal_return:
|
_no_signal_return:
|
||||||
|
|
||||||
@ -123,3 +119,24 @@ svcHandler:
|
|||||||
popne {r0-r7, r12}
|
popne {r0-r7, r12}
|
||||||
add sp, #4
|
add sp, #4
|
||||||
b _svc_finished
|
b _svc_finished
|
||||||
|
|
||||||
|
_call_svc_debugged:
|
||||||
|
push {r0-r3, r12, lr}
|
||||||
|
mov r0, r9
|
||||||
|
cpsie i
|
||||||
|
bl signalSvcEntry
|
||||||
|
pop {r0-r3, r12, lr}
|
||||||
|
blx r8
|
||||||
|
|
||||||
|
cpsid i
|
||||||
|
ldrb lr, [sp, #0x58+0] @ page end - 0xb8 + 0: scheduling flags
|
||||||
|
b _fallback_end
|
||||||
|
|
||||||
|
_signal_svc_end:
|
||||||
|
push {r0-r3, r12, lr}
|
||||||
|
mov r0, r9
|
||||||
|
cpsie i
|
||||||
|
bl signalSvcReturn
|
||||||
|
cpsid i
|
||||||
|
pop {r0-r3, r12, lr}
|
||||||
|
b _no_signal_return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user