功能:探测指定窗口的窗口信息和所在进程的必要信息,如果该窗口包含密码域,则获取该密码。
分析分为界面,窗口操作,DLL三个部分
HBRUSH CWndSpyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here switch (nCtlColor) { case CTLCOLOR_EDIT: //如果是密码显示框 突出文字为红色 if(pWnd->GetDlgCtrlID() == IDC_EDIT_PASSWORD) pDC->SetTextColor(RGB(255,0,0)); else pDC->SetTextColor(TOOL_TIP_COLOR); pDC->SetBkMode(TRANSPARENT); return (HBRUSH)m_grayBrush.GetSafeHandle(); case CTLCOLOR_STATIC: //设置文字背景色透明 pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(TOOL_TIP_COLOR); //返回透明画刷 使得静态控件非文字区域始终使用其父窗口指定的背景颜色 //由于也设定了TRANSPARENT文字背景属性,因此文字背景色也是父窗口背景色 return (HBRUSH)m_nullBrush.GetSafeHandle(); case CTLCOLOR_LISTBOX: //如果ListBox的父窗口为ComboBox的父窗口 if (pWnd->GetParent()->GetDlgCtrlID() == m_comboTransparent.GetParent()->GetDlgCtrlID()) { CRect rectCombo; CRect rectListBox; m_comboTransparent.GetWindowRect(&rectCombo); pWnd->GetWindowRect(&rectListBox); //并且该ListBox为指定的m_comboTransparent组合框弹出的 if(rectCombo.left == rectListBox.left && rectCombo.bottom == rectListBox.top) { //设定文字背景色和非文字区域背景色均用m_grayBrush //并使用TOOL_TIP_COLOR 颜色字体 pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(TOOL_TIP_COLOR); return (HBRUSH)m_grayBrush.GetSafeHandle(); } } break; default: break; } // TODO: Return a different brush if the default is not desired return hbr; }
//设置窗口样式为分层窗口 ModifyStyleEx(0, 0x80000); //初始化透明窗口组合框 CString strTrans; for (int i=1; i<=TRANSPARENCY_LEVEL; i++) { strTrans.Format("%d%%", i*100/TRANSPARENCY_LEVEL); m_comboTransparent.InsertString(i-1, strTrans); } //初始化选择为100% 不透明 m_comboTransparent.SetCurSel(TRANSPARENCY_LEVEL-1); //调用消息函数 更新界面 使初始化有效 OnSelchangeComboTransparent();选择透明度改变时 回调函数
void CWndSpyDlg::OnSelchangeComboTransparent() { // TODO: Add your control notification handler code here int index = m_comboTransparent.GetCurSel(); if (index == CB_ERR) return; //调用SetLayeredWindowAttributes为分层窗口设置透明度 //加载User32.lib HMODULE hDll = ::LoadLibrary(_T("user32")); typedef BOOL (WINAPI *PFUN)(HWND, COLORREF, BYTE, DWORD); //得到所需函数地址 PFUN pFun = (PFUN)::GetProcAddress(hDll, "SetLayeredWindowAttributes"); //使用函数 if (!pFun) { MessageBox("SetLayeredWindowAttributes Failed!"); ::FreeLibrary(hDll); return; } else if(!pFun(this->GetSafeHwnd(), 0, (BYTE)(index+1)*255/TRANSPARENCY_LEVEL, 2)) MessageBox("SetLayeredWindowAttributes Failed!"); ::FreeLibrary(hDll); return; }
CToolTipCtrl m_tooltipctrl
void CWndSpyDlg::SetToolTips() { //创建 m_tooltipctrl.Create(this, TTS_ALWAYSTIP); //设置属性 m_tooltipctrl.SetTipBkColor(TOOL_TIP_COLOR); m_tooltipctrl.SetTipTextColor(TOOL_TIP_TEXT_COLOR); m_tooltipctrl.SetDelayTime(1, 2000); m_tooltipctrl.SetMaxTipWidth(200); //添加提示窗口 m_tooltipctrl.AddTool(GetDlgItem(IDC_COMBO_TRANSPARENT), _T("The transparency of dialog")); m_tooltipctrl.AddTool(GetDlgItem(IDC_EDIT_CONTROL), _T("The ID of control which you detecting. In decimal")); m_tooltipctrl.AddTool(GetDlgItem(IDC_CHECK_MORE), _T("Whether show more information of the detected window")); //...... //给静态控件添加提示 CRect rectLook; ((CStatic*)GetDlgItem(IDC_LOOK))->GetWindowRect(&rectLook); ScreenToClient(&rectLook); m_tooltipctrl.AddTool(this,_T("Detect icon, Drag the icon to window you wana detect."), &rectLook, IDC_LOOK); CRect rectStayTop; ((CStatic*)GetDlgItem(IDC_STAYTOP))->GetWindowRect(&rectStayTop); ScreenToClient(&rectStayTop); m_tooltipctrl.AddTool(this, _T("Let window top most or not"), &rectStayTop, IDC_STAYTOP); }
HWND SmallestWindowFromPoint(CPoint point) { HWND hWnd, hWndParent, hWndSerach; hWnd = ::WindowFromPoint(point); RECT rect; int areaSamller; int area; if (hWnd != NULL) { //得到当前返回的窗口的面积 ::GetWindowRect(hWnd, &rect); areaSamller = (rect.right-rect.left)*(rect.bottom-rect.top); hWndParent = ::GetParent(hWnd); if (hWndParent != NULL) { hWndSerach = hWnd; do { //遍历窗口 hWndSerach = ::GetWindow(hWndSerach, GW_HWNDNEXT); //判断是否是有效的兄弟窗口 if (hWndSerach && ::GetParent(hWndSerach)==hWndParent && ::IsWindowVisible(hWndSerach)) { ::GetWindowRect(hWndSerach, &rect); area = (rect.right-rect.left)*(rect.bottom-rect.top); //如果新得到的窗口更小 那么更新hWnd 记录当前最小面积 if (::PtInRect(&rect, point) && area < areaSamller) { areaSamller = area; hWnd = hWndSerach; } } } while (hWndSerach != NULL); } } return hWnd; }
void HignLightWindow(HWND hWnd) { #define LINEWIDTH 3 if (hWnd == NULL || !IsWindow(hWnd)) return; CRect rect; ::GetWindowRect(hWnd, &rect); if(IsRectEmpty(&rect)) return; //将屏幕坐标转换为窗口坐标 OffsetRect(&rect, -rect.left, -rect.top); //绘制矩形 HDC hdc = ::GetWindowDC(hWnd); PatBlt(hdc, rect.left, rect.top, rect.right-rect.top, LINEWIDTH, DSTINVERT); PatBlt(hdc, rect.left, rect.bottom-LINEWIDTH, rect.right-rect.top, LINEWIDTH, DSTINVERT); PatBlt(hdc, rect.left, rect.top, LINEWIDTH, rect.bottom-rect.top, DSTINVERT); PatBlt(hdc, rect.right-LINEWIDTH, rect.top,LINEWIDTH, rect.bottom-rect.top, DSTINVERT); ::ReleaseDC(hWnd, hdc); }
//当前进程ID DWORD dwProcessID; GetWindowThreadProcessId(hWnd, &dwProcessID); CString strProcessID; strProcessID.Format(_T("%d"), dwProcessID); m_editProcessID.SetWindowText(strProcessID); //得到模块名称 CString strExeName; HANDLE hSnapProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, dwProcessID); PROCESSENTRY32 pe; BOOL bOk; if (hSnapProcess != INVALID_HANDLE_VALUE) { for(bOk = Process32First(hSnapProcess, &pe); bOk; bOk = Process32Next(hSnapProcess, &pe)) { //找到窗口所属的进程条目 if (pe.th32ProcessID == dwProcessID) { strExeName = pe.szExeFile; break; } } } CloseHandle(hSnapProcess); m_editModuleName.SetWindowText(strExeName); //得到模块路径 CString strExePath; CString str; HANDLE hSnapModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID); MODULEENTRY32 me; if (hSnapModule != INVALID_HANDLE_VALUE) { for (bOk = Module32First(hSnapModule, &me); bOk; bOk=Module32Next(hSnapModule, &me)) { //找到模块名和前面得到的模块名一致的结构体 str = me.szExePath; int namePos = str.ReverseFind('\\'); str = str.Mid(namePos+1); if (str.CompareNoCase(strExeName) == 0) { str = me.szExePath; strExePath = str.Left(namePos); break; } } } CloseHandle(hSnapModule); m_editModulePath.SetWindowText(strExePath);
//设定钩子 查询密码 SetSpyHook(m_hWnd, hCurWnd, m_uSpyMsg); QueryPasswordEdit(); UnSetSpyHook();
BOOL SetSpyHook(HWND hWndCaller, HWND hWndTarget, UINT msg) { if (!hWndTarget || !hWndCaller) return FALSE; if (g_bReEnter) { PopMsg(_T("Re Enter Hook")); } g_hook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc, g_hInstDLL, GetWindowThreadProcessId(hWndTarget, NULL)); if(!g_hook) return FALSE; g_hWndCaller = hWndCaller; g_hWndTarget = hWndTarget; g_bReEnter = TRUE; g_msg = msg; return TRUE; }
BOOL QueryPasswordEdit() { if (!g_hook || !g_hWndCaller || !g_hWndTarget || !g_msg) { return FALSE; } SendMessage(g_hWndTarget, g_msg, 0, 0); return TRUE; }
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam; if (pCwp->message == g_msg) { TCHAR szData[MAX_PATH] = {0}; SendMessage(g_hWndTarget, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szData); COPYDATASTRUCT cds; cds.dwData = (DWORD)g_hWndTarget; cds.lpData = szData; cds.cbData = (lstrlen(szData)+1)*sizeof(TCHAR); SendMessage(g_hWndCaller, WM_COPYDATA, (WPARAM)g_hWndTarget, (LPARAM)&cds); } return CallNextHookEx(g_hook, nCode, wParam, lParam); }