Unity的Mono代码相关信息
Unity的C#使用Mono引擎, 利用Mono模块的一些功能可以获取C#的一些信息
cheatengine其中包含一个带源码的插件, 可以获取相关信息
C#的函数编译成x86指令的函数, x86函数的地址获取方法
- cheatengine 使用对函数编译 mono_compile_method, 很可能会导致程序卡死, 异常等, 这个方法有限制的
BOOL CMonoInfo::GetMethodInfo(AsmMethod &Fun, BOOL bCompile)
{
int nRetVal;
PVOID code;
PVOID dbg_jitinfo;
MonoDebugMethodJitInfo *info;
BOOL bRetVal;
dbg_jitinfo = mo._mono_debug_find_method(Fun.method, m_domain);
if(!dbg_jitinfo)
{
dbg_jitinfo = mo._mono_debug_lookup_method(Fun.method);
}
if(dbg_jitinfo)
{
code = *(PVOID *)dbg_jitinfo;
Fun.code_start = code;
Fun.code_size = *(int *)((byte *)dbg_jitinfo + sizeof(code));
if(Fun.code_start == 0)
{
info = (MonoDebugMethodJitInfo *)dbg_jitinfo;
Fun.code_start = (PVOID)info->wrapper_addr;
}
return TRUE;
}
bRetVal = GetMethodInfoTable(Fun);
if(bRetVal)
return TRUE;
if(bCompile == FALSE)
return FALSE;
if(Fun.clas == NULL)
return FALSE;
nRetVal = mo._mono_class_is_generic(Fun.clas);
if(nRetVal != 0)
return FALSE;
__try
{
code = mo._mono_compile_method(Fun.method); // 部分版本导致异常, 或者卡死
Fun.code_start = code;
NLog::DbgOutput("_mono_compile_method get dat: %016X", code);
dbg_jitinfo = mo._mono_debug_find_method(Fun.method, m_domain);
if(dbg_jitinfo)
{
code = *(PVOID *)dbg_jitinfo;
Fun.code_start = code;
Fun.code_size = *(int *)((byte *)dbg_jitinfo + sizeof(code));
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
NLog::DbgOutput("_mono_compile_method except!");
return -1;
}
return TRUE;
}
- mono_debug_find_method, 这个方法部分版本获取不到
- 从domain获取到 MonoJitInfoTable, 然后遍历这个表, 可以获取完整信息, 但是这个方法, 不同版本的地址有些不一样, 需要适配
MonoJitInfoTable * CMonoInfo::Get_MonoJitInfoTable(void *domain)
{
MonoJitInfoTable *pTalbe;
__try
{
if(m_dwVersion >= 0x050B0000)
{
if(ISX64)
pTalbe = *(MonoJitInfoTable **)((byte *)domain + 0x148); //20190415-x64-050B0000
else
pTalbe = *(MonoJitInfoTable **)((byte *)domain + 0x148);
}
else
{
pTalbe = *(MonoJitInfoTable **)((byte *)domain + 0x148);
}
if(pTalbe->domain != domain)
return NULL;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
NLog::DbgOutput("Get_MonoJitInfoTable except!");
return NULL;
}
return pTalbe;
}
BOOL CMonoInfo::LoadJitTable()
{
MonoJitInfoTable *pTalbe;
MonoJitInfo *pItem;
int i, k;
if(m_bMtdInfoInit)
return TRUE;
m_bMtdInfoInit = TRUE;
pTalbe = Get_MonoJitInfoTable(m_domain);
if(pTalbe == NULL)
return FALSE;
m_MtdInfoMap.clear();
for(i=0; i<pTalbe->num_chunks; ++i)
{
for(k=0; k<pTalbe->chunks[i]->num_elements; ++k)
{
pItem = pTalbe->chunks[i]->data[k];
m_MtdInfoMap[pItem->d.method] = pItem;
}
}
return TRUE;
}
BOOL CMonoInfo::GetMethodInfoTable(AsmMethod &Fun)
{
MonoJitInfo **ppFind;
MonoJitInfo *pInfo;
LoadJitTable();
ppFind = StdEx::FindInMap(m_MtdInfoMap, Fun.method);
if(ppFind == NULL)
return FALSE;
pInfo = *ppFind;
Fun.code_start = pInfo->code_start;
Fun.code_size = pInfo->code_size;
return TRUE;
}

浙公网安备 33010602011771号