注入全流程速覽
| 階段 | 關鍵 API | 作用 |
| 1. 獲取目標進程 | CreateToolhelp32Snapshot → Process32First/Next → OpenProcess | 按進程名查找 PID,獲取具備 VM_OPERATION/VM_WRITE 權限的句柄 |
| 2. 分配遠程內存 | VirtualAllocEx | 在目標進程申請 PAGE_READWRITE 內存,大小 = DLL 路徑長度 + 1 |
| 3. 寫入 DLL 路徑 | WriteProcessMemory | 將完整 DLL 路徑拷貝至遠程內存 |
| 4. 創建遠程線程 | CreateRemoteThread | 以 LoadLibraryA 為線程入口,參數指向遠程內存,觸發 DLL 加載 |
| 5. 等待並清理 | WaitForSingleObject → CloseHandle | 等待加載完成,關閉線程與進程句柄 |
卸載全流程
| 步驟 | 關鍵 API | 說明 |
| 1 | CreateRemoteThread(GetModuleHandleA, DLL名) | 在目標進程獲取已加載 DLL 的模塊句柄 |
| 2 | GetExitCodeThread | 線程退出碼即為 HMODULE |
| 3 | CreateRemoteThread(FreeLibrary, HMODULE) | 調用 FreeLibrary 卸載 DLL |
| 4 | WaitForSingleObject + CloseHandle | 等待卸載完成,清理句柄 |
完整參考代碼
// 關鍵片段
DWORD dwPid = GetProcessHandle(argv[1]); // 遍歷快照匹配進程名
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, dwPid);
LPVOID pRemote = VirtualAllocEx(hProcess, NULL, strlen(dllPath)+1, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemote, dllPath, strlen(dllPath)+1, &written);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)LoadLibraryA, pRemote, 0, &tid);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
// 卸載
HANDLE hTh = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)GetModuleHandleA, pRemote, 0, &tid);
WaitForSingleObject(hTh, INFINITE);
GetExitCodeThread(hTh, &hMod);
CloseHandle(hTh);
hTh = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)FreeLibrary, (LPVOID)hMod, 0, &tid);
WaitForSingleObject(hTh, INFINITE);
CloseHandle(hTh);
CloseHandle(hProcess);
實戰注意點
- 目標進程位數(x86/x64)必須與注入器一致,否則 LoadLibraryA 地址錯誤;
- 需關閉目標進程的 DEP/ASLR 或使用對應繞過技術;
- 殺毒軟件/EDR 會攔截 CreateRemoteThread,實戰需考慮免殺;
- DLL 入口點
DllMain 中不得執行複雜邏輯,避免鎖死加載器鎖。