通过CreateRemoteThread注入DLL

注入流程

  1. 获取要注入的目标进程的句柄(OpenProcess)
  2. 在目标进程中开辟内存空间,用于写入DLL的路径(VirtualAllocEx)
  3. 在开辟的空间中写入DLL的路径(WriteProcessMemory)
  4. 获取kernel32.dll的句柄(GetModuleHandle)
  5. 获取kernel32.dll中LoadLibrary的地址(GetProcAddress)
  6. 在目标进程中创建远程线程(CreateRemoteThread)

需要注意的地方

  1. 在Win11中因为自己的DLL命名为了MyHack.dll导致Windows Defender拦截了一切对该dll的访问(踩坑!!)
  2. 因为注入的应用不一定有输出的地方,所以需要使用OutputDebugStringA("hack.dll has Injection!!!");这种形式来输出,通过DebugView来查看
  3. 执行注入的exe和注入的dll一定要相同的位数
  4. 32位的执行exe和注入dll无法注入进64位的目标进程,CreateRemoteThread会报错5
    image.png

注入代码

#include <Windows.h>
#include <tchar.h>


BOOL InjectDLL(DWORD dwPID, LPCTSTR szDllPath) {
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);


	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) {
		_tprintf(L"OpenProcess(%d) failed [%d]\n", dwPID, GetLastError());
		return FALSE;
	}

	LPVOID pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

	if (!(WriteProcessMemory(hProcess, pRemoteBuf, szDllPath, dwBufSize, NULL))) {
		_tprintf(L"WriteProcessMemory fail [%d]\n", GetLastError());
		return FALSE;
	}

	HMODULE hMod = GetModuleHandle(L"kernel32.dll");
	if (hMod == NULL) {
		_tprintf(L"get kernel32.dll fail [%d]", GetLastError());
		return FALSE;
	}
	LPTHREAD_START_ROUTINE pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
	if (pThreadProc == NULL) {
		_tprintf(L"GetProcAddress fail [%d]", GetLastError());
		return FALSE;
	}

	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
	if (hThread == NULL) {
		_tprintf(L"CreateRemoteThread fail [%d]", GetLastError());
		return FALSE;
	}
	DWORD retCode = WaitForSingleObject(hThread, INFINITE);
	if (retCode == WAIT_FAILED) {
		_tprintf(L"Wait Thread fail [%d]", GetLastError());
		return FALSE;
	}

	CloseHandle(hThread);
	CloseHandle(hProcess);
	return TRUE;
}


int _tmain(int argc, TCHAR* argv[]) {
	if (argc != 3) {
		_tprintf(L"Usage : %s pid dllpath\n", argv[0]);
		return 1;
	}

	if (InjectDLL((DWORD)_tstol(argv[1]), argv[2])) {
		_tprintf(L"success");
	}
	else {
		_tprintf(L"fail");
	}
	return 0;
}