遠程線程注入


原理:

  打開目標進程以后,將要注入的動態庫的路徑寫入這個地址空間,然后調用開啟遠程線程的函數,來執行LoadLibraryA或者LoadLibraryW(其實不存在LoadLibrary這個函數,他只是一個宏,如果是UNICODE環境的話會調用LoadLibraryW,否則就是LoadLibraryA)來執行這個動態庫,動態庫一旦被加載起來,DllMain中的DLL_PROCESS_ATTACH則會被執行,我們將要執行的代碼寫在DLL_PROCESS_ATTACH分支即可。之所以把LoadLibraryA(W)作為線程函數,是因為它剛好只有1個參數,在不考慮參數類型的情況下,可以認為它的原型與線程函數一樣,示例如下:

HMODULE WINAPI LoadLibraryW(
    _In_ LPCWSTR lpLibFileName
    );

DWORD WINAPI ThreadProc(
    _In_ LPVOID lpParameter
    );

  注意:由於從Windows Vista 開始,微軟為了增強系統的安全性,對系統服務和登錄用戶進行了會話(Session)隔離,系統服務屬於會話0,登錄的第一個用戶屬於會話1,之前系統服務和第一個登錄用戶都屬於會話0。此方法並不能突破SESSION 0隔離。原因是在 CreateRemoteThread 函數中對此進行了檢查,如果不在同一會話中,調用 CsrClientCallServer 為新進程進行登記的操作就會失敗,這就直接導致了線程創建的失敗。

步驟:

  1. 打開目標進程
  2. 在目標進程中申請空間
  3. 將要注入的Dll路徑寫入剛申請的空間中
  4. 獲取LoadLibrary函數地址
  5. 在目標進程中創建線程,線程回調函數就是LoadLibrary函數,回調函數參數就是要注入的Dll路徑
  6. 等待線程結束
  7. 清理環境

代碼如下:

BOOL CBiaoBai1Dlg::CreateRemoteThreadInjectDll(DWORD dwProcessId, char* pszDllFileName)
{
	// 1.打開目標進程
	HANDLE hProcess = OpenProcess(
		PROCESS_ALL_ACCESS,		// 打開權限
		FALSE,					// 是否繼承
		dwProcessId);			// 進程PID
	if (NULL == hProcess)
	{
		MessageBox("打開目標進程失敗!");
		return FALSE;
	}

	// 2.在目標進程中申請空間
	LPVOID lpPathAddr = VirtualAllocEx(
		hProcess,					// 目標進程句柄
		0,							// 指定申請地址
		strlen(pszDllFileName) + 1,	// 申請空間大小
		MEM_RESERVE | MEM_COMMIT,	// 內存的狀態
		PAGE_READWRITE);			// 內存屬性
	if (NULL == lpPathAddr)
	{
		MessageBox("在目標進程中申請空間失敗!");
		CloseHandle(hProcess);
		return FALSE;
	}

	// 3.在目標進程中寫入Dll路徑
	SIZE_T dwWriteSize = 0;
	if (FALSE == WriteProcessMemory(
		hProcess,					// 目標進程句柄
		lpPathAddr,					// 目標進程地址
		pszDllFileName,					// 寫入的緩沖區
		strlen(pszDllFileName) + 1,	// 緩沖區大小
		&dwWriteSize))				// 實際寫入大小
	{
		MessageBox("目標進程中寫入Dll路徑失敗!");
		CloseHandle(hProcess);
		return FALSE;
	}

	//獲取LoadLibraryA的函數地址
	//FARPROC可以自適應32位與64位
	FARPROC pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		MessageBox("獲取LoadLibrary函數地址失敗!");
		CloseHandle(hProcess);
		return FALSE;
	}

	// 4.在目標進程中創建線程
	HANDLE hThread = CreateRemoteThread(
		hProcess,					// 目標進程句柄
		NULL,						// 安全屬性
		NULL,						// 棧大小
		(PTHREAD_START_ROUTINE)pFuncProcAddr,	// 回調函數
		lpPathAddr,					// 回調函數參數
		NULL,						// 標志
		NULL						// 線程ID
	);
	if (NULL == hThread)
	{
		MessageBox("目標進程中創建線程失敗!");
		CloseHandle(hProcess);
		return FALSE;
	}

	// 5.等待線程結束
	WaitForSingleObject(hThread, -1);

	DWORD code;
	GetExitCodeThread(hThread, &code);
	code = GetLastError();

	// 6.清理環境
	VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
	CloseHandle(hThread);
	CloseHandle(hProcess);
	return TRUE;
}

  

 

   

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM