Feelme的文章

  • 在DllMain中测试调用LoadLibrary和CreateThread函数可正常使用

    背景某天,在网上无意中看到一篇博文,标题是说在DLL的入口点函数DllMain中不能调用 LoadLibrary 加载DLL,因为会造成死锁。看到这里我楞了一下,因为我之前写过很多DLL程序,在入口点函数DllMain中也加载过其它的DLL,从没有出现过什么问题。然后,我便仔细阅读了这篇博文,大概理解了它的意思。它应该想表达的是在DLL的DllMain函数中谨慎使用 LoadLibrary,以防发生死锁情况。
    虽然都懂了它的意思,我还是决定自己再亲自动手写一下代码看看。现在,我就把实现的过程和测试心得整理成文档,分享给大家。
    实现过程首先,我直接创建一个名为 Dll_LoadLibrary_CreateThread_Test 的DLL项目工程,在 DllMain 的 DLL_PROCESS_ATTACH 时候直接调用 CreateThread 函数创建一个多线程,同时,也调用 LoadLibrary 加载另一个 DLL 文件。
    BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { // 创建多线程 ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL); // 加载DLL HMODULE hDll = ::LoadLibrary("testdll.dll"); if (NULL == hDll) { ::MessageBox(NULL, "load testdll.dll error.", "error", MB_OK); } break; } … …(省略) } return TRUE;}
    其中,ThreadProc 多线程函数,执行的操作就是每个 5000 毫秒就弹窗提示一次。
    UINT ThreadProc(LPVOID lpVoid){ while (TRUE) { Sleep(5000); ::MessageBox(NULL, "this si from createthread.", "createthread", MB_OK); } return 0;}
    在 testdll.dll 这个DLL的入口点函数DllMain中,直接弹窗提示。
    BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { // 弹窗 ::MessageBox(NULL, "this is from testdll.dll DllMain function.", "testdll.dll", MB_OK); break; } … …(省略) } return TRUE;}
    然后,我们直接加载 Dll_LoadLibrary_CreateThread_Test.dll 文件,成功弹出下图所示的两个提示框,说明 CreateThread 函数成功创建多线程,LoadLibrary 成功加载DLL。


    总结经过上面的例子测试,说明在 DllMain 函数中,是可以使用 CreateThread 以及 LoadLibrary 函数的。只要我们避免相互在 DllMain 中相互调用,出现死锁,如下面这种相互调用的情况:

    DllB 在 DllMain 里调用 LoadLibrary 加载 DllA
    DllA 在 DllMain 里调用 LoadLibrary 加载 DllB

    这样,就会无限循环加载下去,形成死锁。
    所以,之所以说 在DllMain里不能调用LoadLibrary函数,其实,并不是说只要是在 DllMain 中,都不能调用 LoadLibrary 函数,而是说,如果这两个 Dll 如果在 DllMain 中相互调用的情况下,是会出错的,所以,为了避免这种相互调用死锁的情况发生,就不提倡在 DllMain 中调用 LoadLibrary!实际上,只要避免这种相互调用的情况,LoadLibrary 还是可以使用的!
    参考参考自《Windows黑客编程技术详解》一书
    1  留言 2018-11-07 11:31:42

发送私信

去奋斗,去追求,去发现,但不要放弃

11
文章数
11
评论数
eject