以下提供兩個函數,分別用於向其它進程注入和卸載指定DLL模組。支援Unicode編碼。
//-----------------------------------------------------------------------------------------------------------<br />// 函數: InjectDll<br />// 功能: 向目標進程中注入一個指定 Dll 模組檔案.<br />// 參數: [in] const TCHAR* ptszDllFile - Dll 檔案名稱及路徑<br />// [in] DWORD dwProcessId - 目標進程 ID<br />// 返回: bool - 注入成功返回 true, 注入失敗則返回 false.<br />// 說明: 採用遠程線程注入技術實現<br />//-----------------------------------------------------------------------------------------------------------<br />bool InjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)<br />{<br />// 參數無效<br />if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))<br />{<br />return false;<br />}<br />// 指定 Dll 檔案不存在<br />if (-1 == _taccess(ptszDllFile, 0))<br />{<br />return false;<br />}<br />HANDLE hProcess = NULL;<br />HANDLE hThread = NULL;<br />DWORD dwSize = 0;<br />TCHAR* ptszRemoteBuf = NULL;<br />LPTHREAD_START_ROUTINE lpThreadFun = NULL;<br />// 擷取目標進程控制代碼<br />hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);<br />if (NULL == hProcess)<br />{<br />return false;<br />}<br />// 在目標進程中分配記憶體空間<br />dwSize = (DWORD)::_tcslen(ptszDllFile) + 1;<br />ptszRemoteBuf = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);<br />if (NULL == ptszRemoteBuf)<br />{<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 在目標進程的記憶體空間中寫入所需參數(模組名)<br />if (FALSE == ::WriteProcessMemory(hProcess, ptszRemoteBuf, (LPVOID)ptszDllFile, dwSize * sizeof(TCHAR), NULL))<br />{<br />::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 從 Kernel32.dll 中擷取 LoadLibrary 函數地址<br />#ifdef _UNICODE<br />lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");<br />#else<br />lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");<br />#endif<br />if (NULL == lpThreadFun)<br />{<br />::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 建立遠程線程調用 LoadLibrary<br />hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, ptszRemoteBuf, 0, NULL);<br />if (NULL == hThread)<br />{<br />::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 等待遠程線程結束<br />::WaitForSingleObject(hThread, INFINITE);<br />// 清理<br />::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);<br />::CloseHandle(hThread);<br />::CloseHandle(hProcess);<br />return true;<br />}<br />//-----------------------------------------------------------------------------------------------------------<br />// 函數: UnInjectDll<br />// 功能: 從目標進程中卸載一個指定 Dll 模組檔案.<br />// 參數: [in] const TCHAR* ptszDllFile - Dll 檔案名稱及路徑<br />// [in] DWORD dwProcessId - 目標進程 ID<br />// 返回: bool - 卸載成功返回 true, 卸載失敗則返回 false.<br />// 說明: 採用遠程線程注入技術實現<br />//-----------------------------------------------------------------------------------------------------------<br />bool UnInjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)<br />{<br />// 參數無效<br />if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))<br />{<br />return false;<br />}<br />HANDLE hModuleSnap = INVALID_HANDLE_VALUE;<br />HANDLE hProcess = NULL;<br />HANDLE hThread = NULL;<br />// 擷取模組快照<br />hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);<br />if (INVALID_HANDLE_VALUE == hModuleSnap)<br />{<br />return false;<br />}<br />MODULEENTRY32 me32;<br />memset(&me32, 0, sizeof(MODULEENTRY32));<br />me32.dwSize = sizeof(MODULEENTRY32);<br />// 開始遍曆<br />if(FALSE == ::Module32First(hModuleSnap, &me32))<br />{<br />::CloseHandle(hModuleSnap);<br />return false;<br />}<br />// 遍曆尋找指定模組<br />bool isFound = false;<br />do<br />{<br />isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));<br />if (isFound) // 找到指定模組<br />{<br />break;<br />}<br />} while (TRUE == ::Module32Next(hModuleSnap, &me32));<br />::CloseHandle(hModuleSnap);<br />if (false == isFound)<br />{<br />return false;<br />}<br />// 擷取目標進程控制代碼<br />hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwProcessId);<br />if (NULL == hProcess)<br />{<br />return false;<br />}<br />// 從 Kernel32.dll 中擷取 FreeLibrary 函數地址<br />LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");<br />if (NULL == lpThreadFun)<br />{<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 建立遠程線程調用 FreeLibrary<br />hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr /* 模組地址 */, 0, NULL);<br />if (NULL == hThread)<br />{<br />::CloseHandle(hProcess);<br />return false;<br />}<br />// 等待遠程線程結束<br />::WaitForSingleObject(hThread, INFINITE);<br />// 清理<br />::CloseHandle(hThread);<br />::CloseHandle(hProcess);<br />return true;<br />}