2016-09-29 524 views
1

我正在写一个DLL,它被注入到游戏中以玩弄一些逆向工程。有一段时间,我在修改程序时能够成功注入,弹出和重新注入。我正在使用FreeLibraryAndExitThread来卸载。FreeLibraryAndExitThread在卸载注入的DLL时崩溃程序

将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); 

哪里hDLLDllMain参数hinstDLL。我也试过GetModuleHandleEx,而不是使用hinstDLL

我的猜测可以是:

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

  • XInputGetState是创造某种参考我的DLL调用时,当我删除我的DLL,它试图访问不再存在的内存。

编辑:我做了一点挖,问题似乎是,添加调用XInputGetState导致我的DLL加载XINPUT1_4.dll。我试图使用FreeLibrary来卸载它,但那是行不通的。

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

最终修改:这是一个简单的修复,我不得不叫LoadLibrary(L"XINPUT1_4.dll")为导致问题的DLL。

+0

自己的参考不应该被卸载从内存中该DLL为它的引用计数不会下降到0 –

+0

试装'xinput1_4.dll'明确在你的DLL(调用LoadLibrary,GetProcAddress的),而不是静态链接到它。如果在DLL卸载时将其加载,则可能没有问题。 –

+0

游戏实际上载入XINPUT的旧版本,它加载1.3版。这有什么区别吗? – Nerual

回答

1

这里的解决方案:

的问题是,调用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,它如果游戏已经使用XINPUT达到自己的目的,那么它应该有自己的开放式参考`xinput1_4.dll`,从而加载和释放您保留在内存中为我的DLL被卸载)