mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2025-01-15 08:53:53 +08:00
.
This commit is contained in:
parent
330070f0f2
commit
6470f82f91
@ -3,18 +3,18 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd,
|
UnsafeJitFunction->
|
||||||
const char** className,
|
invokeCompileMethodHelper->
|
||||||
const char** namespaceName,
|
jitMgr->m_jit->compileMethod
|
||||||
const char** enclosingClassNames,
|
|
||||||
size_t maxEnclosingClassNames)
|
FlushInstructionCache
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
CorJitResult CILJit::compileMethod(ICorJitInfo* compHnd,
|
unsigned __int8 *__fastcall UnsafeJitFunction(
|
||||||
CORINFO_METHOD_INFO* methodInfo,
|
PrepareCodeConfig *config,
|
||||||
unsigned flags,
|
COR_ILMETHOD_DECODER *ILHeader,
|
||||||
uint8_t** entryAddress,
|
CORJIT_FLAGS *pJitFlags,
|
||||||
uint32_t* nativeSizeOfCode)
|
unsigned int *a4)
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
|
CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
|
||||||
@ -24,6 +24,21 @@ namespace
|
|||||||
BYTE **nativeEntry,
|
BYTE **nativeEntry,
|
||||||
uint32_t *nativeSizeOfCode)
|
uint32_t *nativeSizeOfCode)
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
CorJitResult CILJit::compileMethod(ICorJitInfo* compHnd,
|
||||||
|
CORINFO_METHOD_INFO* methodInfo,
|
||||||
|
unsigned flags,
|
||||||
|
uint8_t** entryAddress,
|
||||||
|
uint32_t* nativeSizeOfCode)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd,
|
||||||
|
const char** className,
|
||||||
|
const char** namespaceName,
|
||||||
|
const char** enclosingClassNames,
|
||||||
|
size_t maxEnclosingClassNames)
|
||||||
|
*/
|
||||||
struct CEEInfo;
|
struct CEEInfo;
|
||||||
struct CORINFO_METHOD_HANDLE;
|
struct CORINFO_METHOD_HANDLE;
|
||||||
struct CORINFO_METHOD_INFO
|
struct CORINFO_METHOD_INFO
|
||||||
@ -42,15 +57,84 @@ namespace
|
|||||||
const char *(*getMethodNameFromMetadata)(CEEInfo *, CORINFO_METHOD_HANDLE *, const char **, const char **, const char **) = 0;
|
const char *(*getMethodNameFromMetadata)(CEEInfo *, CORINFO_METHOD_HANDLE *, const char **, const char **, const char **) = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
struct passinfo
|
||||||
|
{
|
||||||
|
void **nativeEntry;
|
||||||
|
std::string methodname;
|
||||||
|
std::string className;
|
||||||
|
std::string namespaceName;
|
||||||
|
std::string enclosingClassName;
|
||||||
|
};
|
||||||
bool Ryujinx::attach_function()
|
bool Ryujinx::attach_function()
|
||||||
{
|
{
|
||||||
WarningOutput("not support ryuujinx, please use yuzu/sudachi instead.");
|
WarningOutput("not support ryuujinx, please use yuzu/sudachi instead.");
|
||||||
return true;
|
return true;
|
||||||
auto invokeCompileMethodHelper = processStartAddress + 0x84CC0;
|
/*
|
||||||
getMethodNameFromMetadata = (decltype(getMethodNameFromMetadata))(processStartAddress + 0x7AED0);
|
UnsafeJitFunction
|
||||||
HookParam hp;
|
|
||||||
hp.address = invokeCompileMethodHelper;
|
if ( !EEJitManager::LoadJIT(ExecutionManager::m_pEEJitManager) )
|
||||||
hp.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
{
|
||||||
|
if ( !v10->m_jit )
|
||||||
|
{
|
||||||
|
CurrentIP = GetCurrentIP();
|
||||||
|
EEPolicy::HandleFatalError(0x80131506, CurrentIP, L"Failed to load JIT compiler", 0i64, 0i64, 0i64);
|
||||||
|
__debugbreak();
|
||||||
|
}
|
||||||
|
if ( !v10->m_alternateJit )
|
||||||
|
{
|
||||||
|
v46 = GetCurrentIP();
|
||||||
|
EEPolicy::HandleFatalError(0x80131506, v46, L"Failed to load alternative JIT compiler", 0i64, 0i64, 0i64);
|
||||||
|
LABEL_89:
|
||||||
|
RealCOMPlusThrow(kInvalidProgramException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
wchar_t aFailedToLoadJi[] = L"Failed to load JIT compiler";
|
||||||
|
auto paFailedToLoadJi = MemDbg::findBytes(aFailedToLoadJi, sizeof(aFailedToLoadJi), processStartAddress, processStopAddress);
|
||||||
|
if (!paFailedToLoadJi)
|
||||||
|
return false;
|
||||||
|
auto lea_aFailedToLoadJi = MemDbg::findleaaddr(paFailedToLoadJi, processStartAddress, processStopAddress);
|
||||||
|
if (!lea_aFailedToLoadJi)
|
||||||
|
return false;
|
||||||
|
ConsoleOutput("lea_aFailedToLoadJi %p", lea_aFailedToLoadJi - processStartAddress);
|
||||||
|
BYTE funcstart[] = {0x48, 0x89, 0x5c, 0x24, 0x10, 0x55, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57};
|
||||||
|
auto UnsafeJitFunction = reverseFindBytes(funcstart, sizeof(funcstart), lea_aFailedToLoadJi - 0x1000, lea_aFailedToLoadJi);
|
||||||
|
if (!UnsafeJitFunction)
|
||||||
|
return false;
|
||||||
|
ConsoleOutput("UnsafeJitFunction %p", UnsafeJitFunction - processStartAddress);
|
||||||
|
BYTE sig_call_invokeCompileMethodHelper[] = {
|
||||||
|
0x48, 0x8D, 0x44, 0x24, XX, // lea rax,[rbp+xx]
|
||||||
|
0x48, 0x89, 0x44, 0x24, 0x28, // mov [rsp+28],rax
|
||||||
|
0x48, 0x8d, 0x45, XX, // lea rax,[rbp-xx]
|
||||||
|
0x48, 0x89, 0x44, 0x24, 0x20, // mov [rsp+20],rax
|
||||||
|
0x4c, 0x8d, 0x8d, XX4, // lea r9,[rbp+xx]
|
||||||
|
0x4c, 0x8d, 0x85, XX4, // lea r8,[rbp+xx]
|
||||||
|
0x48, 0x8d, 0x95, XX4, // lea rdx,[rbp+xx]
|
||||||
|
0x49, 0x8b, 0xcc, // mov rcx,r12
|
||||||
|
0xe8, XX4};
|
||||||
|
auto call_invokeCompileMethodHelper = MemDbg::findBytes(sig_call_invokeCompileMethodHelper, sizeof(sig_call_invokeCompileMethodHelper), UnsafeJitFunction, UnsafeJitFunction + 0x1000);
|
||||||
|
if (!call_invokeCompileMethodHelper)
|
||||||
|
return call_invokeCompileMethodHelper;
|
||||||
|
BYTE sig_getMethodNameFromMetadata[] = {
|
||||||
|
0x41, 0xb8, 0xff, 0x0f, 0x00, 0x00,
|
||||||
|
0x66, 0x41, 0x23, 0xc8,
|
||||||
|
0x0f, 0xb7, 0x02,
|
||||||
|
0x66, 0x41, 0x23, 0xc0,
|
||||||
|
0x44, 0x0f, 0xb7, 0xc9,
|
||||||
|
0x41, 0x81, 0xc9, 0x00, 0x60, 0x00, 0x00,
|
||||||
|
0x41, 0xc1, 0xe1, 0x0c};
|
||||||
|
auto ptr_sig_getMethodNameFromMetadata = MemDbg::findBytes(sig_getMethodNameFromMetadata, sizeof(sig_getMethodNameFromMetadata), processStartAddress, processStopAddress);
|
||||||
|
if (!ptr_sig_getMethodNameFromMetadata)
|
||||||
|
return false;
|
||||||
|
BYTE start_getMethodNameFromMetadata[] = {0x48, 0x89, XX, XX};
|
||||||
|
getMethodNameFromMetadata = (decltype(getMethodNameFromMetadata))reverseFindBytes(start_getMethodNameFromMetadata, sizeof(start_getMethodNameFromMetadata), ptr_sig_getMethodNameFromMetadata - 0x100, ptr_sig_getMethodNameFromMetadata, 0, true);
|
||||||
|
if (!getMethodNameFromMetadata)
|
||||||
|
return false;
|
||||||
|
ConsoleOutput("getMethodNameFromMetadata %p", (uintptr_t)getMethodNameFromMetadata - processStartAddress);
|
||||||
|
HookParam hp_invokeCompileMethodHelper;
|
||||||
|
hp_invokeCompileMethodHelper.address = *(int *)(call_invokeCompileMethodHelper + sizeof(sig_call_invokeCompileMethodHelper) - 4) + call_invokeCompileMethodHelper + sizeof(sig_call_invokeCompileMethodHelper);
|
||||||
|
hp_invokeCompileMethodHelper.user_value = (uintptr_t) new passinfo{};
|
||||||
|
hp_invokeCompileMethodHelper.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||||
{
|
{
|
||||||
auto methodInfo = (CORINFO_METHOD_INFO *)stack->r8;
|
auto methodInfo = (CORINFO_METHOD_INFO *)stack->r8;
|
||||||
|
|
||||||
@ -59,27 +143,57 @@ bool Ryujinx::attach_function()
|
|||||||
const char *enclosingClassName;
|
const char *enclosingClassName;
|
||||||
auto methodname = getMethodNameFromMetadata((CEEInfo *)stack->rdx, methodInfo->ftn, &className, &namespaceName, &enclosingClassName);
|
auto methodname = getMethodNameFromMetadata((CEEInfo *)stack->rdx, methodInfo->ftn, &className, &namespaceName, &enclosingClassName);
|
||||||
if (!methodname)
|
if (!methodname)
|
||||||
return;
|
|
||||||
if (strcmp(methodname, "RegisterFunction") != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ConsoleOutput("%s %s %s %s", className, namespaceName, enclosingClassName, methodname);
|
|
||||||
HookParam hpinternal;
|
|
||||||
hpinternal.user_value = stack->stack[5]; // entryAddress->RegisterFunction
|
|
||||||
hpinternal.address = stack->retaddr;
|
|
||||||
hpinternal.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
|
||||||
{
|
{
|
||||||
|
((passinfo *)hp->user_value)->nativeEntry = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((passinfo *)hp->user_value)->nativeEntry = (void **)stack->stack[5];
|
||||||
|
((passinfo *)hp->user_value)->methodname = methodname;
|
||||||
|
((passinfo *)hp->user_value)->className = className;
|
||||||
|
((passinfo *)hp->user_value)->namespaceName = namespaceName;
|
||||||
|
// ((passinfo *)hp->user_value)->enclosingClassName = enclosingClassName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bool succ = NewHook(hp_invokeCompileMethodHelper, "invokeCompileMethodHelper");
|
||||||
|
BYTE sig_call_FlushInstructionCache[] = {
|
||||||
|
/*
|
||||||
|
.text:0000000140086454 call cs:__imp_GetCurrentProcess
|
||||||
|
.text:000000014008645A mov config, rax ; hProcess
|
||||||
|
.text:000000014008645D mov r8d, ebx ; dwSize
|
||||||
|
.text:0000000140086460 mov ILHeader, rsi ; lpBaseAddress
|
||||||
|
.text:0000000140086463 call cs:__imp_FlushInstructionCache
|
||||||
|
*/
|
||||||
|
0xFF, 0x15, XX4,
|
||||||
|
0x48, 0x8B, XX,
|
||||||
|
0x44, 0x8B, XX,
|
||||||
|
0x48, 0x8B, XX,
|
||||||
|
0xFF, 0x15, XX4};
|
||||||
|
auto ptr_sig_call_FlushInstructionCache = MemDbg::findBytes(sig_call_FlushInstructionCache, sizeof(sig_call_FlushInstructionCache), hp_invokeCompileMethodHelper.address, hp_invokeCompileMethodHelper.address + 0x1000);
|
||||||
|
if (!ptr_sig_call_FlushInstructionCache)
|
||||||
|
return false;
|
||||||
|
HookParam hp_call_FlushInstructionCache;
|
||||||
|
hp_call_FlushInstructionCache.address = ptr_sig_call_FlushInstructionCache + sizeof(sig_call_FlushInstructionCache) - 6;
|
||||||
|
hp_call_FlushInstructionCache.user_value = hp_invokeCompileMethodHelper.user_value;
|
||||||
|
hp_call_FlushInstructionCache.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||||
|
{
|
||||||
|
auto info = (passinfo *)hp->user_value;
|
||||||
|
if (!info->nativeEntry)
|
||||||
|
return;
|
||||||
|
if (info->methodname != "RegisterFunction")
|
||||||
|
return;
|
||||||
|
if (info->className != "Translator")
|
||||||
|
return;
|
||||||
|
// Ryujinx.HLE.HOS:ArmProcessContext`1:Initialize
|
||||||
|
// Ryujinx.Cpu.Jit:JitCpuContext:Execute
|
||||||
HookParam hp_cs_function;
|
HookParam hp_cs_function;
|
||||||
hp_cs_function.address = *(uintptr_t *)hp->user_value;
|
hp_cs_function.address = *(uintptr_t *)info->nativeEntry;
|
||||||
hp_cs_function.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
hp_cs_function.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||||
{
|
{
|
||||||
ConsoleOutput("%p %p %p %p %p %p", stack->rcx, stack->rdx, stack->r8, stack->r9, stack->r10, stack->r11);
|
ConsoleOutput("%s\n%p %p %p %p %p %p", hp->name, stack->rcx, stack->rdx, stack->r8, stack->r9, stack->r10, stack->r11);
|
||||||
};
|
};
|
||||||
NewHook(hp_cs_function, "RegisterFunction");
|
NewHook(hp_cs_function, (info->namespaceName + ":" + info->className + ":" + info->methodname).c_str());
|
||||||
|
|
||||||
hp->type = HOOK_EMPTY;
|
|
||||||
};
|
};
|
||||||
NewHook(hpinternal, "invokeCompileMethodHelper Return");
|
succ |= NewHook(hp_call_FlushInstructionCache, "FlushInstructionCache");
|
||||||
};
|
return succ;
|
||||||
return NewHook(hp, "invokeCompileMethodHelper");
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user