日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系

發布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? 前幾篇文章一直沒有在源碼級證明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH時會進入臨界區。這個論證非常重要,因為它是使其他線程不能進入臨界區從而導致死鎖的關鍵。我構造了在DLL被映射到進程地址空間的場景,請看死鎖時加載DLL的線程的堆棧(轉載請指明出于breaksoftware的csdn博客)

? ? ? ? 如果仔細看過《DllMain中不當操作導致死鎖問題的分析--導致DllMain中死鎖的關鍵隱藏因子2》,應該得知第14步就是進入臨界區的點。

? ? ? ? 我們可以看到LdrLoadDll內部調用了LdrLockLoaderLock。LdrLockLoaderLock內部進入臨界區,我們用IDA查看LdrLoadDll函數

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是在臨界區中執行的。其實在LdrpLoadDll中也會進入該臨界區,但是我們不必關注了。因為只要一次沒出臨界區就可以滿足死鎖的條件了。

? ? ? ? 我們再看下卸載DLL時發生的進入臨界區場景,請看堆棧


? ? ? ? 我們將關注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幾乎所有操作都是在臨界區執行的。

? ? ? ? 以上兩段從源碼級證明了加載和卸載DLL導致的DllMain的調用(以及不調用)都是在臨界區中完成的。

總結

以上是生活随笔為你收集整理的DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。