You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:34:49