如何正确退出注入进程的DLL内部的窗口过程?
问题排查点
- 第一个核心错误:你在ExitProcess钩子中直接调用
WndProc是完全错误的。PostQuitMessage的作用是给当前执行该函数的线程的消息队列投递WM_QUIT消息,你在钩子线程调用WndProc,相当于在钩子线程执行PostQuitMessage,根本不会投递到你跑窗口逻辑的次级线程的消息队列,次级线程的GetMessage永远拿不到退出信号,线程无法退出,自然会导致进程残留。 - 第二个逻辑错误:你的
WndProc中WM_COPYDATA的分支没有加break,执行完WM_COPYDATA的逻辑后会直接掉落到下方的WM_DESTROY/WM_QUIT分支,提前触发退出逻辑,属于未定义行为。 - 第三个遗漏点:你没有等待次级线程完全退出就直接调用原
ExitProcess,即使线程收到退出信号,也可能因为还没完成资源清理就被强制终止,引发残留问题。 - 额外冗余问题:消息-only窗口不需要调用
ShowWindow和UpdateWindow,这两行属于无效代码可以删掉。
修复方案
- 先修正
WndProc的分支逻辑,补全break,补充标准窗口销毁流程:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_COPYDATA: { //.... break; // 补充这行避免分支掉落 } case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: OutputDebugString(L"WM_DESTROY"); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
- 修改ExitProcess钩子逻辑,改为给窗口投递消息,等待次级线程退出后再执行原退出流程:
void ExitProcess_Hook(UINT uExitCode) { OutputDebugString(L"ExitProcess_Hook!"); // 消息会自动路由到创建窗口的次级线程处理 PostMessageW(dummy_hwnd, WM_CLOSE, 0, 0); // 等待次级线程完全退出 if(thread.valid()) { thread.wait(); } // 清理注册的窗口类资源 UnregisterClass(dummy_class_name, 0); return ExitProcess(uExitCode); }
内容的提问来源于stack exchange,提问作者user14761342
相关产品推荐
相关产品推荐

