天天看點

注入系列:遠端線程注入

注入思路

1.使用程序PID打開程序,獲得句柄

2.使用程序句柄申請記憶體空間

3.把dll路徑寫入記憶體

4.建立遠端線程,調用LoadLibrary

5.釋放收尾工作或者解除安裝dll

代碼實作:

BOOL CInjectDlg::ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pszDllFileName)
{
	HANDLE  hProcess = NULL;
	SIZE_T  dwSize = 0;
	LPVOID  pDllAddr = NULL;     //DLL位址
	FARPROC pFunProcAddr = NULL; //函數位址
	HANDLE  hRemoteThread = NULL;//遠端線程
	DWORD   dwStatus = 0;

	//打開目标程序 擷取句柄
	//使用程序PID打開程序,獲得句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (hProcess == NULL)
	{
		m_TipMsg += L"打開程序失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"打開程序成功\r\n";
	}

	//在注入的程序中申請記憶體
	dwSize = strlen(pszDllFileName) + 1;
	//配置設定空間,存儲dll
	//使用程序句柄申請記憶體空間
	pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (pDllAddr == NULL)
	{
		m_TipMsg += L"申請記憶體失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"申請記憶體成功\r\n";
	}

	//向申請的記憶體中寫入資料
	//把dll路徑寫入記憶體
	BOOL bIsSucess = WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL);
	if (bIsSucess == FALSE)
	{
		m_TipMsg += L"寫入記憶體失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"寫入記憶體成功\r\n";
	}

	//獲得
	//加載ntdll.dll
	
	HMODULE hNtdll = LoadLibraryA("ntdll.dll");
	if (hNtdll == NULL)
	{
		m_TipMsg += L"加載ntdll失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"加載ntdll成功\r\n";
	}

	//擷取LoadLibraryA函數位址
	建立遠端線程,調用LoadLibrary
	pFunProcAddr = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
	if (pFunProcAddr == NULL)
	{
		m_TipMsg += L"加載LoadLibraryA函數位址失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"加載LoadLibraryA函數位址成功\r\n";
	}

	//擷取ZwCreateThread函數位址  ZwCreateThread在64位和32位下的函數聲明不一樣
#ifdef _WIN64
	typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,
		HANDLE ProcessHandle,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		ULONG CreateThreadFlags,
		SIZE_T ZeroBits,
		SIZE_T StackSize,
		SIZE_T MaximumStackSize,
		LPVOID pUnkown);
#else
	typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,   //線程句柄
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,	
		HANDLE ProcessHandle,	//程序句柄
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		BOOL CreateSuspended,
		DWORD dwStackSize,
		DWORD dw1,
		DWORD dw2,
		LPVOID pUnkown);
#endif
	typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
	if (ZwCreateThreadEx == NULL)
	{
		m_TipMsg += L"加載ZwCreateThreadEx函數位址失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"加載ZwCreateThreadEx函數位址成功\r\n";
	}
	//使用ZwCreateThreadEx函數建立遠端線程 實作DLL注入
	dwStatus = ZwCreateThreadEx(
		&hRemoteThread, 
		THREAD_ALL_ACCESS, 
		NULL,
		hProcess, 
		(LPTHREAD_START_ROUTINE)pFunProcAddr, 
		pDllAddr,
		0, 0, 0, 0, NULL);
	if (hRemoteThread == NULL)
	{
		m_TipMsg += L"遠端線程注入失敗\r\n";
		return FALSE;
	}
	else
	{
		m_TipMsg += L"遠端線程注入成功\r\n";
	}

	//關閉句柄
	CloseHandle(hProcess);
	FreeLibrary(hNtdll);
	return TRUE;

}