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

时间:2016-09-29 21:50:18

标签: c++ windows dll reverse-engineering dll-injection

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

将XInput添加到程序后,我可以捕获用户输入,当我调用FreeLibraryAndExitThread时,游戏会因访问冲突而崩溃。从this post开始,我猜测当我去卸载时,使用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);

hDLL来自hinstDLL的参数DllMain。我还尝试了GetModuleHandleEx而不是hinstDLL

我猜是:

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

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

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

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

最终编辑:这是一个简单的修复,我不得不为导致该问题的DLL调用LoadLibrary(L"XINPUT1_4.dll")

1 个答案:

答案 0 :(得分:2)

以下是解决方案:

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

因此解决方案只是在我初始化DLL的线程后调用LoadLibrary(L'XINPUT1_4.dll'),以便在卸载我的DLL时,XInput DLL保留在内存中,因为LoadLibrary增加了引用计数

(当DLL的引用计数达到0时,它会卸载。当你第一次加载时,它被初始化为1,LoadLibrary将它递增1,并且调用FreeLibraryAndExitThread将它减1。所以当所有的都被说出来时完成后,它的引用计数大于0,并且当我的DLL被卸载时它仍保留在内存中)