Unity游戏调用C++内部DLL函数崩溃问题求助
问题描述
在Unity游戏中尝试调用C内部DLL的User__get_VisitorsCount函数获取当前访客数,直接调用会导致游戏崩溃,但通过Hook拦截该函数时却能正常获取返回值。本人熟悉基础C,但对逆向工程和栈操作了解有限。已尝试多种调用约定,也测试过栈上多个地址作为MethodInfo*参数,问题仍未解决。
附上代码与栈信息
Hook代码(可正常工作)
// 基于MinHook实现的示例Hook代码 typedef int(*User__get_VisitorsCount_t)(void* instance, MethodInfo* method); User__get_VisitorsCount_t original_GetVisitorsCount; int Hook_GetVisitorsCount(void* instance, MethodInfo* method) { int result = original_GetVisitorsCount(instance, method); // 此处可正常打印正确的访客数 printf("Visitors Count: %d\n", result); return result; } // Hook初始化流程 MH_Initialize(); MH_CreateHook((void*)0xXXXXXXX, &Hook_GetVisitorsCount, (void**)&original_GetVisitorsCount); MH_EnableHook((void*)0xXXXXXXX);
直接调用代码(执行崩溃)
// 尝试的直接调用方式 typedef int(*User__get_VisitorsCount_t)(void* instance, MethodInfo* method); User__get_VisitorsCount_t GetVisitorsCount = (User__get_VisitorsCount_t)0xXXXXXXX; // 尝试过传入nullptr、栈上随机地址作为method参数,均触发崩溃 int count = GetVisitorsCount(nullptr, nullptr); // 或尝试传入从其他渠道获取的实例指针与栈地址 // int count = GetVisitorsCount(instancePtr, methodPtr);
Hook捕获的函数栈信息
栈帧 #0: User__get_VisitorsCount 参数1: 0x12345678 (有效instance指针) 参数2: 0x87654321 (有效MethodInfo*指针)
可能的原因与解决方案
1. 调用约定不匹配
这类IL2CPP自动生成的__get_XXX getter函数,调用约定有明确平台特性:
- x86平台:默认是
__thiscall,this指针通过ecx寄存器传递,其余参数压栈。需确保typedef显式指定约定:typedef int(__thiscall* User__get_VisitorsCount_t)(void* instance, MethodInfo* method); - x64平台:统一使用fastcall,this指针放入rcx寄存器,第二个参数放入rdx,无需显式指定约定,但要保证typedef参数顺序正确。
2. MethodInfo*参数无效
Hook时的MethodInfo*是Unity运行时传入的合法指针,包含函数元数据与调用信息,部分IL2CPP生成的函数会校验该指针有效性:
- 解决方案一:在Hook中保存合法的
MethodInfo*,直接调用时复用:MethodInfo* validMethodInfo = nullptr; int Hook_GetVisitorsCount(void* instance, MethodInfo* method) { validMethodInfo = method; // 保存合法指针 return original_GetVisitorsCount(instance, method); } // 后续直接调用时使用该指针 int count = GetVisitorsCount(instancePtr, validMethodInfo); - 解决方案二:通过IL2CPP API从元数据中获取:使用
il2cpp_class_get_method_from_name,根据类名和函数名查询对应MethodInfo(需链接IL2CPP导出函数)。
3. Instance指针无效
确保传入的instance是合法的User类实例:
- 可在Hook中保存游戏正常调用时传入的
instance指针,直接调用时复用; - 若
User是单例类,可通过查找游戏内存中的单例实例地址获取合法指针。
4. 栈平衡问题
若调用约定匹配仍崩溃,可尝试用汇编手动控制栈与寄存器操作:
示例x86汇编调用(thiscall约定):
push methodPtr ; 压入第二个参数 mov ecx, instancePtr ; 将this指针放入ecx call 0xXXXXXXX ; 调用目标函数 add esp, 4 ; 若为stdcall则无需此行,被调用者会自动清理栈
内容的提问来源于stack exchange,提问作者watersippin
相关产品推荐
相关产品推荐

