我正在编写一个DLL,将其注入游戏中以进行一些反向工程。有一段时间我能够成功地注入、弹出和重新注入程序。我使用
在添加XInput到程序中以便捕获用户输入后,当我调用
以下是在退出时导致程序崩溃的代码:
FreeLibraryAndExitThread
来卸载。在添加XInput到程序中以便捕获用户输入后,当我调用
FreeLibraryAndExitThread
时,游戏会崩溃并显示访问冲突。从这篇文章中可以得知,我猜测使用XInput在我卸载时留下了一些“活”的内容,并导致了崩溃。说实话,我不知道如何解决这个问题。以下是在退出时导致程序崩溃的代码:
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
是来自DllMain
的参数hinstDLL
。我还尝试使用GetModuleHandleEx
而不是使用hinstDLL
。
我的猜测是:
使用
XInputGetState
会使我的程序加载第二个XInput
的DLL,或者XInputGetState
在调用时创建了对我的DLL的某种引用,并且当我删除我的DLL时,它尝试访问不再存在的内存。
编辑:我进行了一些挖掘,问题似乎是添加对XInputGetState
的调用会导致我的DLL加载XINPUT1_4.dll
。我尝试使用FreeLibrary
卸载它,但没有效果。
编辑:我进一步缩小了范围——问题是由游戏中的某个线程尝试返回到XINPUT1_4.dll的代码部分造成的,该部分已被卸载,从而导致崩溃。我不知道如何解决这个问题。
最终编辑:这是一个简单的解决方法,我需要调用LoadLibrary(L"XINPUT1_4.dll")
来加载导致问题的DLL。
xinput1_4.dll
的引用,因此加载和释放你自己的引用不应该从内存中卸载该DLL,因为它的引用计数不会降为0。 - Remy Lebeauxinput1_4.dll
(使用LoadLibrary,GetProcAddress),而不是静态链接它。如果在您的DLL卸载时保留它已加载,则可能不会出现问题。 - Harry JohnstonLoadLibrary("XINPUT1_4.dll");
,并且在卸载时它也能正常工作!非常感谢! :) - Nerual