使用远程线程来注入DLL
DLL注入技术要求我们目标进程中的一个线程调用LoadLibrary来载入我们想要的DLL
(1)用OpenProcess函数打开目标进程
(2)用VirtualAllocEx函数在远程进程的地址空间中分派一块内存
(3)用WriteProcessMemory函数把DLL的路径名复制到第一步分配的内存中
(4)用GetProcAddress函数来得到LoadLibraryW函数(在Kernel32.dll中)的实际地址
(5)用CreateRemoteThread函数在远程进程中创建一个线程,让新线程调用LoadLibraryW函数并在参数中传入第1步分配的内存地址。这时,DLL已经被注入到远程进程的地址空间中,DLL的DllMain函数会收到DLL_PROCESS_ATTACH通知并且可以执行我们想要执行的代码。当DllMain返回的时候,远程线程会从LoadLibraryW调用返回到BaseThreadStart函数。BaseThreadStart函数然后调用ExitThread,使远程线程终止。
补充:
(1)OpenProcess函数的作用是打开一个已存在的进程对象,并返回进程的句柄
(2)VirtualAllocEx函数的作用是在指定进程的虚拟空间申请内存,执行成功返回分配内存的首地址,不成功返回NULL
(3)WriteProcessMemory函数的作用是在某一进程的内存区域写入数据
(4)GetProcAddress函数的作用是获取DLL导出函数的地址,使用返回的函数指针调用DLL函数
(5)CreateRemoteThread函数的作用是创建一个在其它进程地址空间中运行的线程
示例代码:
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) { HANDLE hProcess = NULL, hThread = NULL; PWSTR pszLibFileRemote = NULL; // Get a handle for the target process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | // Required by Alpha PROCESS_CREATE_THREAD | // For CreateRemoteThread PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx PROCESS_VM_WRITE, // For WriteProcessMemory FALSE, dwProcessId); if (hProcess == NULL) return false; // Calculate the number of bytes needed for the DLL's pathname int cch = 1 + lstrlenW(pszLibFile); int cb = cch * sizeof(wchar_t); // Allocate space in the remote process for the pathname pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE); if (pszLibFileRemote == NULL) return false; // Copy the DLL's pathname to the remote process' address space if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)) return false; // Get the real address of LoadLibraryW in Kernel32.dll PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); if (pfnThreadRtn == NULL) return false; // Create a remote thread that calls LoadLibraryW(DLLPathname) hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL); if (hThread == NULL) return false; // Wait for the remote thread to terminate WaitForSingleObject(hThread, INFINITE); // Free the remote memory that contained the DLL's pathname if (pszLibFileRemote != NULL) VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE); if (hThread != NULL) CloseHandle(hThread); if (hProcess != NULL) CloseHandle(hProcess); return true; }
源自《Windows核心编程(第5版)》