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

FreeLibraryAndExitThread crashes program when unloading injected DLL

本文关键字:FreeLibraryAndExitThread 程序 崩溃 卸载 注入 DLL      更新时间:2023-10-16

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

在将XInput添加到程序中以便我可以捕获用户输入后,当我调用FreeLibraryAndExitThread时,游戏因访问冲突而崩溃。从这篇文章来看,我猜使用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);

其中hDLLDllMain的参数hinstDLL。我也尝试过GetModuleHandleEx而不是使用hinstDLL

我的猜测是:

  • 使用XInputGetState使我的程序为XInput加载第二个DLL,或者

  • 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被卸载)

相关文章:
  • 没有找到相关文章