我正在编写一个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")
。
答案 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被卸载时它仍保留在内存中)