[英]FreeLibraryAndExitThread crashes program when unloading injected DLL
I am writing a DLL that gets injected into a game in order to play around with some reverse engineering.我正在编写一个注入游戏的 DLL,以便进行一些逆向工程。 For a while I was able to successfully inject, eject and reinject as I made changes to the program.有一段时间,当我对程序进行更改时,我能够成功地注入、弹出和重新注入。 I'm using FreeLibraryAndExitThread
to unload.我正在使用FreeLibraryAndExitThread
卸载。
After adding XInput to the program so I could catch user input, the game crashes with an access violation when I call FreeLibraryAndExitThread
.在将 XInput 添加到程序中以便我可以捕获用户输入后,当我调用FreeLibraryAndExitThread
时,游戏因访问冲突而崩溃。 Going from this post , I'm guessing that using XInput is leaving something 'live' in the program when I go to unload, and that's what's causing the crash.从这篇文章开始,我猜测使用 XInput 会在我卸载时在程序中留下一些“活动”的东西,这就是导致崩溃的原因。 I'm honestly at a loss as to how to fix this.老实说,我不知道如何解决这个问题。
Here's the code that's crashing the program on exit:这是在退出时使程序崩溃的代码:
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);
When I remove the call to XInputGetState
, everything works just fine and I'm able to unload the DLL without crashing.当我删除对XInputGetState
的调用时,一切正常,我能够卸载 DLL 而不会崩溃。
And here's how I'm calling for the program to unload and exit这就是我如何调用程序卸载和退出
FreeLibraryAndExitThread(hDLL, 0);
Where hDLL
is the argument hinstDLL
from DllMain
.凡hDLL
是参数hinstDLL
从DllMain
。 I've also tried GetModuleHandleEx
instead of using hinstDLL
.我也试过GetModuleHandleEx
而不是使用hinstDLL
。
My guess is either:我的猜测是:
Using XInputGetState
makes my program load a second DLL for XInput
, or使用XInputGetState
使我的程序为XInput
加载第二个DLL,或者
XInputGetState
is creating some sort of reference to my DLL when called and when I remove my DLL, it's trying to access memory that's no longer there. XInputGetState
在调用时创建了对我的 DLL 的某种引用,当我删除我的 DLL 时,它试图访问不再存在的内存。
EDIT: I did a bit of digging and the problem seems to be that adding the call to XInputGetState
causes my DLL to load XINPUT1_4.dll
.编辑:我做了一些挖掘,问题似乎是添加对XInputGetState
的调用会导致我的 DLL 加载XINPUT1_4.dll
。 I tried using FreeLibrary
to unload it but that isn't working.我尝试使用FreeLibrary
卸载它,但这不起作用。
EDIT: I narrowed it down some more - it turns out that the access violation is being caused by some thread within the game trying to return to part of XINPUT1_4.dll's code, which is unloaded, making it crash.编辑:我进一步缩小了范围 - 结果表明访问冲突是由游戏中的某个线程试图返回 XINPUT1_4.dll 代码的一部分引起的,该代码已卸载,导致崩溃。 And I have no clue how to fix that.我不知道如何解决这个问题。
Final Edit: It was a simple fix, I had to call LoadLibrary(L"XINPUT1_4.dll")
for the DLL that was causing the issue.最终编辑:这是一个简单的修复,我不得不为导致问题的 DLL 调用LoadLibrary(L"XINPUT1_4.dll")
。
Here's the solution:这是解决方案:
The problem was that invoking XInputGetState
caused my DLL to automatically load XINPUT1_4.dll
, and when I called FreeLibraryAndExitThread, my DLL unloading forced the XInput DLL to unload as well.问题是调用XInputGetState
导致我的 DLL 自动加载XINPUT1_4.dll
,并且当我调用 FreeLibraryAndExitThread 时,我的 DLL 卸载也强制 XInput DLL 卸载。 Code within the program (probably from a thread in XInput 1.4) attempted to execute code that was no longer there, causing an access violation.程序中的代码(可能来自 XInput 1.4 中的线程)试图执行不再存在的代码,从而导致访问冲突。
So the solution was simply to call LoadLibrary(L'XINPUT1_4.dll')
after I initialize my DLL's thread so that when my DLL is unloaded, the XInput DLL stays in memory because the LoadLibrary
increases the reference count.所以解决方案只是在我初始化我的 DLL 的线程后调用LoadLibrary(L'XINPUT1_4.dll')
,这样当我的 DLL 被卸载时,XInput DLL 保留在内存中,因为LoadLibrary
增加了引用计数。
(When a DLL's reference count reaches 0, it unloads. It is initialized as 1 when you first load it, LoadLibrary increments it by 1, and calling FreeLibraryAndExitThread decrements it by 1. So when all is said and done, its reference count is above 0 and it remains in memory as my DLL is unloaded) (当 DLL 的引用计数达到 0 时,它会卸载。第一次加载时它被初始化为 1,LoadLibrary 将它加 1,调用 FreeLibraryAndExitThread 将它减 1。所以当一切都说完了,它的引用计数高于0 并且它在我的 DLL 被卸载时保留在内存中)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.