在 Windows 2000/XP 時代,某些程序(如防病毒、監控軟件)需要防止被用戶通過任務管理器關閉或刪除可執行文件。本文從原理層面分析其典型實現:雙輔助線程互相監視,實現進程級「不死」效果。僅供安全研究與防禦理解,請勿用於惡意軟件開發。
主進程 (T-mouse) ├── 本地輔助線程 (watch) ──→ 監視註冊表啟動項 + 遠程線程存活 └── 遠程線程 (remote) ──→ 注入 Explorer/Taskmgr 進程,監視主進程
| 組件 | 駐留位置 | 核心職責 |
|---|---|---|
| 主線程 | 主進程 | 業務邏輯、啟動輔助線程、文件備份到系統目錄、修改文件屬性隱藏 |
| 本地輔助線程 | 主進程 | 輪詢註冊表 `Run` 鍵值缺失則重寫;檢查遠程線程退出碼,掛了則重新注入 |
| 遠程線程 | Explorer/Taskmgr | 等待主進程句柄信號,主進程結束則拉起備份可執行文件 |
GetSystemDirectory(syspath, MAX_PATH);
CopyFile(curname, tname, TRUE); // 複製到系統目錄
SetFileTime(hFile, &ft, NULL, &ft); // 修改時間戳
SetFileAttributes(kname, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
// 打開目標進程,需 CREATE_THREAD | VM_OPERATION | VM_WRITE 權限
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
// 在目標進程分配內存
LPVOID remoteCode = VirtualAllocEx(hProcess, NULL, codeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
LPVOID remoteParam = VirtualAllocEx(hProcess, NULL, paramSize, MEM_COMMIT, PAGE_READWRITE);
// 寫入線程代碼與參數
WriteProcessMemory(hProcess, remoteCode, localCode, codeSize, NULL);
WriteProcessMemory(hProcess, remoteParam, ¶m, paramSize, NULL);
// 創建遠程線程
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)remoteCode, remoteParam, 0, NULL);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, RUN_KEY, 0, KEY_QUERY_VALUE, &hKey);
RegQueryValueEx(hKey, _T("AppName"), ...); // 檢查
RegSetValueEx(hKey, _T("AppName"), ..., (BYTE*)sysPath, ...); // 重寫
該技術利用 Windows 進程/線程模型、跨進程內存操作、註冊表持久化形成「雙重保險」。理解其原理有助於安全產品設計更強的自我保護,也助於惡意代碼分析與清除。現代系統(Vista+)引入會話隔離、UAC、PPL(保護進程輕量級)等機制,大幅提高了用戶態對抗難度。