远程线程注入

原理:

  打开目标进程以后,将要注入的动态库的路径写入这个地址空间,然后调用开启远程线程的函数,来执行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;
}

  

   

  

直面挫折,顽强生长
原文地址:https://www.cnblogs.com/ndyxb/p/12751827.html