Windows10的DllMain中CreateThread并WaitforSingleObject造成死锁
2022/2/5 7:12:28
本文主要是介绍Windows10的DllMain中CreateThread并WaitforSingleObject造成死锁,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文分两种情况讨论,即在CreateThread之后是否调用WaitForSingleObject. 先看:static DWORD WINAPI ThreadCreateInDllMain(LPVOID) { printf("ThreadCreateInDllMain start"); return 0; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { printf("DllMain start.\n"); HMODULE hMod = NULL; HANDLE hThread = NULL; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: printf("DLL_PROCESS_ATTACH\n"); hThread = CreateThread(NULL, 0, ThreadCreateInDllMain, NULL, 0, NULL); WaitForSingleObject(hThread, INFINITE); break; case DLL_THREAD_ATTACH: printf("DLL_THREAD_ATTACH\n"); break; case DLL_THREAD_DETACH: printf("DLL_THREAD_DETACH\n"); break; case DLL_PROCESS_DETACH: printf("DLL_PROCESS_DETACH\n"); break; } return TRUE; }我们看看这个NtWaitforSingleObject在等待什么(其实我们自己写的代码我们肯定知道是在等待一个线程对象):
查看句柄对应的详细信息:
等待3号线程:
我们看3号线程在干啥,3号线程也在等待(3号线程的等待是关键):
它在等待一个事件:
IDA看它等的是什么,它在等待LdrpWorkCompleteEvent事件:
设置这个Event的线程不是在等待,就是已经退出了。所以我们要找哪里能SetEvent(LdrpWorkCompleteEvent),找到是在LdrpProcessWork中:
我没有具体去追踪调用ZwSetEvent(LdrpWorkCompleteEvent)的调用关系,但是,总之,我们知道DllMain中的线程会负责ZwSetEvent(LdrpWorkCompleteEvent),但是它在等待线程完成,而线程又在等待DllMain的ZwSetEvent(LdrpWorkCompleteEvent),所以会死锁。 如果代码是这样,就不会死锁:
static DWORD WINAPI ThreadCreateInDllMain(LPVOID) { printf("ThreadCreateInDllMain start"); return 0; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { printf("DllMain start.\n"); HMODULE hMod = NULL; HANDLE hThread = NULL; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: printf("DLL_PROCESS_ATTACH\n"); hThread = CreateThread(NULL, 0, ThreadCreateInDllMain, NULL, 0, NULL); break; case DLL_THREAD_ATTACH: printf("DLL_THREAD_ATTACH\n"); break; case DLL_THREAD_DETACH: printf("DLL_THREAD_DETACH\n"); break; case DLL_PROCESS_DETACH: printf("DLL_PROCESS_DETACH\n"); break; } return TRUE; }我单步跟踪了LdrpDrainWorkQueue,即线程的NtWaitForsingleobject的调用者,如果DllMain中没有WaitForSingleObject的流程,LdrpDrainWorkQueue从这里就break掉了:
如果DllMain中有WaitForsingleobject,那么这里直接跳转:
跳转到这里等待:
其实LdrpDrainWorkQueue中会走到NtWaitforSingleObject进行等待的根本原因就在于上边判断了是否有WorkInProcess:
所以我们可以推断LdrpWorkInProgress表示是否还有DllMain在处理。创建线程的时候,如果还有DllMain没有执行完,那么会等待这个DllMain执行完才创建线程。而此时Thread在等待DllMain完,而DllMain又在等待Thread则必然死锁。
这篇关于Windows10的DllMain中CreateThread并WaitforSingleObject造成死锁的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升