【发布时间】:2020-12-25 21:18:44
【问题描述】:
我曾经通过从使用CreateThread 创建的线程中调用FreeLibraryAndExitThread 来卸载注入的库。
需要从不同的线程卸载库导致这种方法不可能。现在我正在使用TerminateThread(因为它不会终止调用它的线程,而是通过的线程)和FreeLibrary。但是,正如 WinAPI 文档所建议的那样,这会产生“竞争条件”并使进程崩溃。有没有办法解决这个问题?
旧代码:
HMODULE g_hModule{ NULL };
BOOL WINAPI DllMain(HMODULE hModule, DWORD fwdReason, LPVOID lpReserved) {
g_hModule = hModule;
if (fwdReason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)main, 0, 0, 0);
}
return TRUE;
}
void Unload(int nExitCode) {
FreeLibraryAndExitThread(g_hModule, (DWORD)nExitCode);
}
新代码:
HMODULE g_hModule{ NULL };
HANDLE g_hThread{ NULL };
BOOL WINAPI DllMain(HMODULE hModule, DWORD fwdReason, LPVOID lpReserved) {
g_hModule = hModule;
if (fwdReason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
g_hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)main, 0, 0, 0);
}
return TRUE;
}
void Unload(int nExitCode) {
TerminateThread(g_hThread, (DWORD)nExitCode);
FreeLibrary(g_hModule);
}
提前感谢您的帮助!
【问题讨论】:
-
这能回答你的问题吗? Kill a running thread 无论如何,在这里搜索“[c++] 终止线程”,你会发现很多信息。在进一步探索这条道路之前,了解终止线程的含义。
-
简短回答:不,没有。 C++ 不能以这种方式工作。除了从原始线程函数返回之外,通过任何方式终止线程都是未定义的行为。
TerminateThread没有明确定义的 C++ 代码行为。它不适用于 C++ 代码。 -
新代码在所有情况下都是错误的并且毫无意义。
TerminateThread- 你终止了 self 线程。FreeLibrary永远不会被调用。没有意义创建线程只是为了终止它(甚至不正确退出)。旧代码看起来是正确的(假设main == Unload和错误的卸载签名) -
在旧代码中
Unload是从main(由CreateThread创建的线程)调用的,而在新代码中它是从一个单独的线程调用的。这就是为什么我认为FreeLibrary应该运行 -
ULONG WINAPI Unload(PVOID) { FreeLibraryAndExitThread((HMODULE)&__ImageBase, 0);和CreateThread(0, 0, Unload, 0, 0, 0);这就是代码需要的样子