Star password Detector

Source: Internet
Author: User

Function: detects the window information of the specified window and the necessary information of the process. If the window contains a password domain, the password is obtained.

Analysis is divided into three parts: interface, window operation, and DLL

Interface: normal window transparent window
  • Control color:
The background of the dialog box is repainted using the specified background bitmap in the onerasebkgnd of the corresponding wm_erasebkgnd through patblt. The background color of the corresponding control must be consistent with the background color of the dialog box, and the message wm_ctlcolor must be returned. Wm_ctlcolor is the message hbrush cwndspydlg: onctlcolor (CDC * PDC, cwnd * pwnd, uint nctlcolor) sent to the parent window when the window control needs to be re-painted. In this function, you can use PDC-> setbkcolor PDC-> setbkmode PDC-> settextcolor and the returned image brush handle to adjust the setbkcolor on a simple interface to change the text display area (a rectangle) of the control ), is not the background color of the entire control. Setbkmode is used to adjust the bkcolor ing mode. The default value is opaque. This mode uses the current text background color (set by setbkcolor) when you draw text on the control interface, if setbkcolor is not used, the background color of the entire control is set by default. This background color is specified when a subwindow is created, rather than the image brush returned by onctlcolor.) Click it again and then draw the text. Another ing mode is transparent. This ing mode allows text to be painted without a background refresh, but with a background color that is not a text area. In this way, there is no border around the text. The text background color is transparent. Settextcolor specifies the text color. The brush value returned by onctlcolor is used for the non-text area of the system drawing control. The onctlcolor code is as follows:
Hbrush cwndspydlg: onctlcolor (CDC * PDC, cwnd * pwnd, uint nctlcolor) {hbrush HBr = cdialog: onctlcolor (PDC, pwnd, nctlcolor); // todo: change any attributes of the DC hereswitch (nctlcolor) {Case ctlcolor_edit: // if it is a password, the highlighted text is red if (pwnd-> getdlgctrlid () = idc_edit_password) PDC-> settextcolor (RGB (255, 0, 0); elsepdc-> settextcolor (tool_tip_color); PDC-> setbkmode (transparent); Return (hbrush) convert (); Case ctlcolor_static: // set the text background color transparent PDC-> setbkmode (transparent); PDC-> settextcolor (tool_tip_color ); // return the transparent paint brush to make the static control always use the background color specified by its parent window in non-text areas. // The transparent text background attribute is also set, therefore, the text background color is also the parent window background color return (hbrush) m_nullbrush.getsafehandle (); Case ctlcolor_listbox: // if the parent window of ListBox is the parent window of ComboBox if (pwnd-> getparent () -> getdlgctrlid () = Response ()-> getdlgctrlid () {crect rectcombo; crect rectlistbox; Response (& rectcombo); pwnd-> getwindowrect (& rectlistbox ); // And The ListBox is the IF (rectcombo. left = rectlistbox. left & rectcombo. bottom = rectlistbox. top) {// set the text background color and the non-text area background color. Use m_graybrush // and use the tool_tip_color font 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 desiredreturn HBr ;}

  • Transparent window:
The formation of a transparent window mainly depends on a window style: ws_ex_layered (layered window). The layered window can be set to translucent and partial transparent through setlayered?wattributes. In a fully transparent area, you cannot receive mouse messages. If ws_ex_transparent is specified in the window, no mouse messages are received in all areas of the window. Setlayeredwindowattributes function usage: bool setlayeredwindowattributes (

Hwnd, // The Window handle to be set requires the ws_ex_layered window style
Colorref crkey, // The Color Key value is valid when dwflags is lwa_colorkey. In this case, all the areas where the color value is crkey will be transparent.
Byte balpha, // transparency (0-255), valid when dwflags is lwa_alpha
DWORD dwflags // execute the operation, which can be lwa_colorkey or lwa_alpha. In this case, all the crkey colors become transparent and other
Regional transparency is balpha

);

Setlayeredwindowattributes exists in the SDK of the new version. If you need to use it in the earlier version of vc6.0. You need to find the function in user32.dll and then reference it through the function pointer. The method is as follows: the code in onintialdialog:
// Set the window style to the hierarchical window modifystyleex (0, 0x80000); // initialize the transparent window combo box cstring strtrans; For (INT I = 1; I <= transparency_level; I ++) {strtrans. format ("% d %", I * 100/transparency_level); m_combotransparent.insertstring (I-1, strtrans);} // The initialization selects 100% opacity m_combotransparent.setcursel (TRANSPARENCY_LEVEL-1 ); // call the message function update interface to enable effective onselchangecombotransparent () initialization ();

Callback function when transparency is changed

Void cwndspydlg: onselchangecombotransparent () {// todo: add your control notification handler code hereint Index = m_combotransparent.getcursel (); If (Index = cb_err) return; // call setlayeredwindowattributes to set transparency for the layered window // load user32.libhmodule hdll =: loadlibrary (_ T ("USER32"); typedef bool (winapi * pfun) (hwnd, colorref, byte, DWORD); // obtain the required function address: pfun = (pfun): getprocaddress (hdll, "setlayered1_wattri Butes "); // use the function if (! Pfun) {MessageBox ("setlayered?wattributes failed! ");: Freelibrary (hdll); return;} else if (! Pfun (this-> getsafehwnd (), 0, (byte) (index + 1) * 255/transparency_level, 2) MessageBox ("setlayeredwindowattributes failed! ");: Freelibrary (hdll); return ;}
  • Prompt window

When you move the mouse over a control, a prompt window is displayed in the lower right corner: This is completed through the ctooltipctrl control. Use the following steps:

CToolTipCtrl m_tooltipctrl
Void cwndspydlg: settooltips () {// create m_tooltipctrl.create (this, tts_alwaystip); // set the attribute values (tool_tip_color); values (tool_tip_text_color); values (1, 2000 ); upper (200); // Add the prompt window 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 "));//...... // Add the crect rectlook prompt to the static control; (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 (optional)-> getwindowrect (& rectstaytop); screentoclient (& rectstaytop); publish (this, _ T ("Let window top most or not"), & rectstaytop, idc_staytop );}
Window operation: when you drag a magnifier to the target window, you need to obtain the window handle of the current mouse position. Win32 API has a function hwnd windowfrompoint (point) through which the window where the current mouse is located can be obtained. But sometimes there may be multiple windows at the place where the mouse is located. In this case, windowfrompoint returns the window at the top of Z-order. This may not be what we want. We want to get the minimum window at the current mouse position, otherwise, you will not be able to get the password box in the following window, but will always get the group box above. Therefore, we need to override a smallestwindowfrompoint. It enumerates all visible brothers of Windows returned by windowfrompoint, finds the smallest one, and returns its handle:
Hwnd smallestwindowfrompoint (cpoint point) {hwnd, hwndparent, hwndserach; hwnd =: windowfrompoint (point); rect; int areasamler; int area; If (hwnd! = NULL) {// obtain the area of the current returned window: getwindowrect (hwnd, & rect); areasamller = (rect. right-rect.left) * (rect. bottom-rect.top); hwndparent =: getparent (hwnd); If (hwndparent! = NULL) {hwndserach = hwnd; do {// traverse the window hwndserach =: getwindow (hwndserach, gw_hwndnext); // judge whether the sibling window is valid if (hwndserach &&:: getparent (hwndserach) = hwndparent &: iswindowvisible (hwndserach) {: getwindowrect (hwndserach, & rect); Area = (rect. right-rect.left) * (rect. bottom-rect.top); // if the new window is smaller, update the hwnd record current minimum area if (: ptinrect (& rect, point) & Area <areasamller) {areasamler = area; hwnd = hwndserach; }}} wh Ile (hwndserach! = NULL) ;}} return hwnd ;}
After obtaining the window handle, you can use functions such as getclassname getwindowlong to obtain window information, highlight the window, and update the window display:
Void hignlightwindow (hwnd) {# define linewidth 3if (hwnd = NULL |! Iswindow (hwnd) return; crect rect;: getwindowrect (hwnd, & rect); If (isrectempty (& rect) return; // convert screen coordinates to window coordinates offsetrect (& rect,-rect. left,-rect. top); // draw a rectangle 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 );}
If you obtain the information of the module where the window is located: 1. getwindowthreadprocessid is used to obtain the ID of the process in which the window is created. 2. call createtollhelp32snapshot to create a process snapshot 3. in this snapshot, process process32first process32next is used to enumerate the processes to obtain the structures of processentry32. 4. find the processentry32 struct whose value of th32processid is equal to the previous process ID. the szexefile Member of the struct is the execution module name. The obtained module path is similar to the preceding method: 1. create a module snapshot using the process ID 2. use the module32first module32next enumeration module to obtain the moduleentry32 struct 3. find the executable file name of the structure member szexepath (full module path) and the structure with the same name as the previous module. 4. Remove the structure szexepath from the module name to obtain the module path.
// The current process iddword dwprocessid; getwindowthreadprocessid (hwnd, & dwprocessid); cstring strprocessid; strprocessid. format (_ T ("% d"), dwprocessid); m_editprocessid.setwindowtext (strprocessid); // obtain the module name cstring strexename; handle hsnapprocess = partition (th32cs_snapprocess, dwprocessid); processentry32 PE; bool Bok; If (hsnapprocess! = Invalid_handle_value) {for (Bok = process32first (hsnapprocess, & PE); Bok = process32next (hsnapprocess, & PE )) {// find the process entry to which the window belongs if (PE. th32processid = dwprocessid) {strexename = PE. szexefile; break ;}}closehandle (hsnapprocess); Response (strexename); // obtain the module path cstring strexepath; cstring STR; handle hsnapmodule = callback (th32cs_snapmodule, dwprocessid); moduleentry32; If (hsnapmodule! = Invalid_handle_value) {for (Bok = module32first (hsnapmodule, & Me); Bok = module32next (hsnapmodule, & Me )) {// find the structure STR = me with the same module name as the previous one. 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 );
Hook and dynamic Connection Library: this is the core part of the program. How can we get the password when we know that the target window is a password box. If the detection window and the target window are in the same process or on the Win16 platform, you can get them through a simple wm_gettext message. However, in Win32 and later versions, messages between processes are independent and cannot be completed in this way. In this case, we set hooks to inject our hook function code into the thread in the target window. In this way, the wm_gettext message can be sent in the hook function, so that the password is obtained. That is to say, the hook is used to forcibly inject the DLL of the hook function to make the DLL part of the target process and obtain the password. There are two more questions: 1. How to set the hook, that is, what form of the hook function is used. 2. How to return the obtained password to the detection window. First, you can set a window hook to check the specific message sent in the probe window. This specific message is specially used for password detection, after the window processing function finds that the window thread receives the message, it starts to send the wm_gettext message in the target window to obtain the password. Note: the specific message here is not defined simply by # define MSG wm_user + 1. Such messages are also mutually independent messages registered through registerwindowmessage between processes that can be transmitted between processes, the second problem is that there are many methods for data transmission between processes. wm_copydata is the simplest method. By filling in copydatastruct and sending messages to the probe window, in the detection window, you only need to obtain the data in the message parameters in the Response Function oncopydata. Because the hook used here is a remote hook, therefore, it must be placed in the dynamic connection library to inject the hook function code into the target thread or process. Input the instance handle of the current DLL in setwindowshookex so that the target thread can load the DLL and find the hook function code to be executed. Probe window code
// Set the hook query password setspyhook (m_hwnd, hcurwnd, m_uspymsg); querypasswordedit (); unsetspyhook ();
Both setspyhook and querypasswordedit are in the dynamic Connection Library.
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;}

Window Process hook function:

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);}
To sum up, the test process is as follows:
Load the password Test message m_uspymsg for the dynamic connection library that contains the Window Process hook to register the inter-process communication
Move the mouse to get the mouse position window handle detected the mouse position window is a password window
Hook during the installation window for the thread in which the window is located
After m_uspymsg is sent to the target window, it is waiting for the Window Process of the thread where the target window is located. The hook function starts to get the password and send the wm_copydata message when it detects m_uspymsg.
Get the password data that hook sends to the probe window in oncopydata capture page: source code: http://download.csdn.net/detail/wudaijun/4971595

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.