FreeLibraryAndExitThread 在卸载注入的 DLL 时导致程序崩溃

2024-01-05

我正在编写一个 DLL,它被注入到游戏中,以便进行一些逆向工程。有一段时间,当我对程序进行更改时,我能够成功地注入、弹出和重新注入。我在用着FreeLibraryAndExitThread卸载。

将 XInput 添加到程序中以便我可以捕获用户输入后,当我调用时,游戏因访问冲突而崩溃FreeLibraryAndExitThread。从这个帖子 https://stackoverflow.com/questions/19934000/how-to-correctly-dispose-of-injected-dll-thread/19935609#19935609,我猜使用 XInput 会留下一些东西'live'当我去卸载时,在程序中,这就是导致崩溃的原因。老实说,我不知道如何解决这个问题。

这是退出时导致程序崩溃的代码:

    XINPUT_STATE state;
    ZeroMemory(&state, sizeof(XINPUT_STATE));

    //The problematic line of code
    bool gamepad = XInputGetState(0, &state) == ERROR_SUCCESS; 

    WORD buttonsHeld = state.Gamepad.wButtons;
    WORD buttonsPressed = (~previousButtonState) & state.Gamepad.wButtons;
    WORD buttonsReleased = previousButtonState & (~state.Gamepad.wButtons);

当我删除对XInputGetState,一切工作正常,我能够卸载 DLL 而不会崩溃。

这就是我如何调用程序卸载并退出

    FreeLibraryAndExitThread(hDLL, 0);

Where hDLL是论点hinstDLL from DllMain。我也尝试过GetModuleHandleEx而不是使用hinstDLL.

我的猜测是:

  • Using XInputGetState让我的程序加载第二个 DLLXInput, or

  • XInputGetState在调用时创建对我的 DLL 的某种引用,当我删除 DLL 时,它会尝试访问不再存在的内存。

编辑:我做了一些挖掘,问题似乎是添加调用XInputGetState导致我的 DLL 加载XINPUT1_4.dll。我尝试使用FreeLibrary卸载它,但这不起作用。

编辑:我进一步缩小了范围 - 事实证明,访问冲突是由游戏中的某些线程试图返回 XINPUT1_4.dll 代码的一部分引起的,该代码已被卸载,从而导致崩溃。我不知道如何解决这个问题。

最终编辑:这是一个简单的修复,我不得不打电话LoadLibrary(L"XINPUT1_4.dll")对于导致问题的 DLL。


这是解决方案:

问题是调用XInputGetState导致我的 DLL 自动加载XINPUT1_4.dll,当我调用 FreeLibraryAndExitThread 时,我的 DLL 卸载会强制 XInput DLL 也卸载。程序内的代码(可能来自 XInput 1.4 中的线程)尝试执行不再存在的代码,从而导致访问冲突。

所以解决方案就是简单地调用LoadLibrary(L'XINPUT1_4.dll')在我初始化 DLL 的线程后,当我的 DLL 被卸载时,XInput DLL 保留在内存中,因为LoadLibrary增加引用计数。

(当 DLL 的引用计数达到 0 时,它将卸载。首次加载时它被初始化为 1,LoadLibrary 将其递增 1,调用 FreeLibraryAndExitThread 将其递减 1。因此,当所有操作完成后,它的引用计数就在上面0 并且当我的 DLL 被卸载时它仍然保留在内存中)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeLibraryAndExitThread 在卸载注入的 DLL 时导致程序崩溃 的相关文章

随机推荐