mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2025-01-15 00:43:59 +08:00
.
This commit is contained in:
parent
330070f0f2
commit
6470f82f91
@ -3,18 +3,18 @@
|
||||
namespace
|
||||
{
|
||||
/*
|
||||
const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd,
|
||||
const char** className,
|
||||
const char** namespaceName,
|
||||
const char** enclosingClassNames,
|
||||
size_t maxEnclosingClassNames)
|
||||
UnsafeJitFunction->
|
||||
invokeCompileMethodHelper->
|
||||
jitMgr->m_jit->compileMethod
|
||||
|
||||
FlushInstructionCache
|
||||
*/
|
||||
/*
|
||||
CorJitResult CILJit::compileMethod(ICorJitInfo* compHnd,
|
||||
CORINFO_METHOD_INFO* methodInfo,
|
||||
unsigned flags,
|
||||
uint8_t** entryAddress,
|
||||
uint32_t* nativeSizeOfCode)
|
||||
unsigned __int8 *__fastcall UnsafeJitFunction(
|
||||
PrepareCodeConfig *config,
|
||||
COR_ILMETHOD_DECODER *ILHeader,
|
||||
CORJIT_FLAGS *pJitFlags,
|
||||
unsigned int *a4)
|
||||
*/
|
||||
/*
|
||||
CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
|
||||
@ -24,6 +24,21 @@ namespace
|
||||
BYTE **nativeEntry,
|
||||
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 CORINFO_METHOD_HANDLE;
|
||||
struct CORINFO_METHOD_INFO
|
||||
@ -42,15 +57,84 @@ namespace
|
||||
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()
|
||||
{
|
||||
WarningOutput("not support ryuujinx, please use yuzu/sudachi instead.");
|
||||
return true;
|
||||
auto invokeCompileMethodHelper = processStartAddress + 0x84CC0;
|
||||
getMethodNameFromMetadata = (decltype(getMethodNameFromMetadata))(processStartAddress + 0x7AED0);
|
||||
HookParam hp;
|
||||
hp.address = invokeCompileMethodHelper;
|
||||
hp.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||
/*
|
||||
UnsafeJitFunction
|
||||
|
||||
if ( !EEJitManager::LoadJIT(ExecutionManager::m_pEEJitManager) )
|
||||
{
|
||||
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;
|
||||
|
||||
@ -59,27 +143,57 @@ bool Ryujinx::attach_function()
|
||||
const char *enclosingClassName;
|
||||
auto methodname = getMethodNameFromMetadata((CEEInfo *)stack->rdx, methodInfo->ftn, &className, &namespaceName, &enclosingClassName);
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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");
|
||||
|
||||
hp->type = HOOK_EMPTY;
|
||||
NewHook(hp_cs_function, (info->namespaceName + ":" + info->className + ":" + info->methodname).c_str());
|
||||
};
|
||||
NewHook(hpinternal, "invokeCompileMethodHelper Return");
|
||||
};
|
||||
return NewHook(hp, "invokeCompileMethodHelper");
|
||||
succ |= NewHook(hp_call_FlushInstructionCache, "FlushInstructionCache");
|
||||
return succ;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user