Windows 下動態庫的 DllMain 與 c++ 相關坑

首先推薦一系列深度剖析的文章:
https://blog.csdn.net/breaksoftware/article/details/8167641

有時候需要在 DllMain 中寫一些代碼,比如下面這樣,其中 TestAttach 等函數裏面有需要的一些代碼,裏面的代碼片在採用 DllMain 調用之前完全運行正常。

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		TestAttach();
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		TestDetach();
		break;
	}
	return TRUE;
}
使用 std::mutex 造成死鎖

例如:

void TestMutex()
{
	std::mutex _m;
	_m.lock();
	_m.unlock();
}
void TestDetach()
{
	TestMutex();
}

使用 RemoteDll.exe (一款 DLL注入的簡單工具,注意32和64位版本差異,也可以自己 LoadLibrary 然後卸載測試),將編譯的 Dll 注入到 RemoteDll.exe (或其他程序)。發現目標程序 RemoteDll 關閉的時候,實際是執行到TestDetach 的時候出問題了
在這裏插入圖片描述
上圖可看到注入成功了,然後點擊關閉
在這裏插入圖片描述
使用系統相關同步機制可以實現自己的鎖,簡單舉例如下:

class CTestLock
{
public:
	CTestLock()
	{
		m_hdMutex = CreateMutexA(NULL, FALSE, "123");
	}
	~CTestLock()
	{
		if (NULL != m_hdMutex)
		{
			CloseHandle(m_hdMutex);
			m_hdMutex = NULL;
		}
	}

	void Lock()
	{
		if (NULL != m_hdMutex)
		{
			OutputDebugStringA("Lock Lock Lock");
			WaitForSingleObject(m_hdMutex, INFINITY);
		}
	}

	void UnLock()
	{
		if (NULL != m_hdMutex)
		{
			ReleaseMutex(m_hdMutex);
			OutputDebugStringA("UnLock Lock Lock");
		}
	}

	HANDLE m_hdMutex;
};

void TestMutex()
{
	CTestLock _lock;
	_lock.Lock();
	_lock.UnLock();
}
使用 std::thread 造成死鎖

例如:

void TestThreadFunc()
{
}

void TestThread()
{
	auto _thread = std::thread(std::bind(TestThreadFunc));
	_thread.join();
}
void TestAttach()
{
	TestThread();	// LoadLibrary 時候調過來時候死鎖
}

在這裏插入圖片描述

使用系統提供的接口比如 beignthread相關函數 和 CreateThread(該函數好像有安全性相關問題,另外的事情)。則沒有這樣的問題,例如:

void TestThreadFunc()
{
	// 做點自己的事情,用類的函數一樣
}

void TestThread()
{
	auto _thread = std::thread(std::bind(TestThreadFunc));
	_thread.join();
}
unsigned __stdcall _ThreadFunc(void* para)
{
	TestThread();
	return 0;
}

void TestAttach()
{
	_beginthreadex(NULL, 0, _ThreadFunc, NULL, 0, NULL);
}

該問題和操縱系統版本有關係,非必現。我用的VS2013,在一臺WIN7出現。相關參考:
https://stackoverflow.com/questions/22402791/visual-studio-2013-stdmutex-and-the-dreaded-windows-loader-lock
https://stackoverflow.com/questions/14711263/c11-stdmutex-in-visual-studio-2012-deadlock-when-locked-from-dllmain
https://stackoverflow.com/questions/27800412/unhandled-exception-when-using-stdmutex-instead-of-boostmutex

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章