Unity的Mono代码相关信息

Unity的C#使用Mono引擎, 利用Mono模块的一些功能可以获取C#的一些信息
cheatengine其中包含一个带源码的插件, 可以获取相关信息
C#的函数编译成x86指令的函数, x86函数的地址获取方法

  1. 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;
}
  1. mono_debug_find_method, 这个方法部分版本获取不到
  2. 从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;
}
posted @ 2022-06-30 21:56  Yofoo  阅读(219)  评论(0)    收藏  举报