DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系
? ? ? ? 前幾篇文章一直沒有在源碼級證明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH時會進入臨界區(qū)。這個論證非常重要,因為它是使其他線程不能進入臨界區(qū)從而導致死鎖的關鍵。我構造了在DLL被映射到進程地址空間的場景,請看死鎖時加載DLL的線程的堆棧(轉載請指明出于breaksoftware的csdn博客)
? ? ? ? 如果仔細看過《DllMain中不當操作導致死鎖問題的分析--導致DllMain中死鎖的關鍵隱藏因子2》,應該得知第14步就是進入臨界區(qū)的點。
? ? ? ? 我們可以看到LdrLoadDll內部調用了LdrLockLoaderLock。LdrLockLoaderLock內部進入臨界區(qū),我們用IDA查看LdrLoadDll函數(shù)
int __stdcall LdrLoadDll(int a1, int a2, int a3, int a4)
{……LdrLockLoaderLock(1, 0, &v10);……v6 = LdrpLoadDll(v9, a1, a2, v17, a4, 1);……if ( v8 >= 0 ){ms_exc.disabled = -1;sub_7C936587(ebp0, v7);v6 = 0;goto LABEL_6;}}int __usercall sub_7C936587<eax>(int a1<ebp>, int a2<esi>)
{LdrpTopLevelDllBeingLoaded = a2;return LdrUnlockLoaderLock(1, *(_DWORD *)(a1 - 572));
}
? ? ? ? 我們看到在LdrpLoadDll是在臨界區(qū)中執(zhí)行的。其實在LdrpLoadDll中也會進入該臨界區(qū),但是我們不必關注了。因為只要一次沒出臨界區(qū)就可以滿足死鎖的條件了。
? ? ? ? 我們再看下卸載DLL時發(fā)生的進入臨界區(qū)場景,請看堆棧
? ? ? ? 我們將關注FreeLibrary和LdrpCallInitRoutine之間的代碼邏輯。我們用IDA查看LdrUnLoadDll
int __stdcall LdrUnloadDll(int a1)
{……v73 = 0;v70 = *(_DWORD *)(*MK_FP(__FS__, 24) + 48);v71 = 0;ms_exc.disabled = 0;if ( !LdrpInLdrInit )RtlEnterCriticalSection(&LdrpLoaderLock);++LdrpActiveUnloadCount;if ( !LdrpShutdownInProgress ){if ( LdrpCheckForLoadedDllHandle(a1, (int)&v78) ){if ( *(_WORD *)(v78 + 56) != -1 ){……if ( (unsigned __int8)LdrpActiveUnloadCount <= 1u ){……v15 = (int *)LdrpUnloadHead;v77 = (int *)LdrpUnloadHead;while ( v15 != &LdrpUnloadHead ){……LdrpCallInitRoutine((int (__stdcall *)(_DWORD, _DWORD, _DWORD))v20, *(_DWORD *)(v78 + 24), 0, 0);……v15 = (int *)LdrpUnloadHead;v77 = (int *)LdrpUnloadHead;ms_exc.disabled = 0;v3 = 0;}……}}}else{v71 = 0xC0000135u;}}ms_exc.disabled = -1;sub_7C937424();
……return v71;
}int __cdecl sub_7C937424()
{int result; // eax@3--LdrpActiveUnloadCount;if ( !LdrpInLdrInit )result = RtlLeaveCriticalSection(&LdrpLoaderLock);return result;
}
? ? ? ? 我們看到LdrUnloadDll幾乎所有操作都是在臨界區(qū)執(zhí)行的。
? ? ? ? 以上兩段從源碼級證明了加載和卸載DLL導致的DllMain的調用(以及不調用)都是在臨界區(qū)中完成的。
總結
以上是生活随笔為你收集整理的DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DllMain中不当操作导致死锁问题的分
- 下一篇: DllMain中不当操作导致死锁问题的分