如何获取网页密码框中的密码

原文:点击打开链接


原创文档 本文适合中级读者 已阅读29448次 ] 
  •                  
  •                  
  •                  
  •       

  • 如何获取网页密码框中的密码

    作者:Sjx

    下载源代码


    前言

    本人是在家中上网,经常有一些BBS的密码懒得记了,就用IE的自动密码保存功能,这样一来是方便了,但却有一个麻烦,一旦机子不行了,想要重装操作系统了,这些密码却也取不出了,还得重新申请,好麻烦!因此我就写了一个工具,可以取得网页密码框的密码.
    因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.有两种方法可以取得WebBrowser控件的接口,接下来我们会逐一介绍,并提供示例源代码供大家参考。

     
    示例程序运行效果图

    第一种方法:使用脚本语言和IE右键菜单

      我们可以使用注册表来控制IE右键菜单.当你装了FlashGet(网际快车)时,你会发现IE右键菜单多了两项:"使用网际快车下载"和"使用网际快车下载全部链接",而这时你打开注册表,在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下有这两个主键.这两个主键下都有两个值,一个是默认的串值,指定了选择了这个菜单命令要打开的URL,IE在一个隐藏的窗口打开它,并这个隐藏窗口的external.menuArguments值设为当前窗口对象,执行完URL对话网页包含的脚本程序该窗口自动关闭.另一个名称是contexts是DWORD值,指定了在什么情况下需要显示这个菜单项.具体的值见下.

    (0x1 << CONTEXT_MENU_DEFAULT) (等于 0x1) //缺省时显示
    (0x1 << CONTEXT_MENU_IMAGE) (等于 0x2) //右键点击图像时显示该项
    (0x1 << CONTEXT_MENU_CONTROL) (等于 0x4) //右键点击表单元素时显示该项
    (0x1 << CONTEXT_MENU_TABLE) (等于 0x8) //右键点击表格时显示该项
    (0x1 << CONTEXT_MENU_TEXTSELECT) (等于 0x10) //右键点击高亮选择的文本时显示该项
    (0x1 << CONTEXT_MENU_ANCHOR) (等于 0x20) //右键点击链接时显示该项
    (0x1 << CONTEXT_MENU_UNKNOWN) (等于 0x40)//右键点击网页中除上以外的地方显示该项
    
    现在我们写一段 VBScript 脚本程序以获取密码框的值.
    Sub GetPassword()
      set srcEvent = external.menuArguments.event
      Set doc=external.menuArguments.document
      set ele=doc.elementFromPoint( srcEvent.clientX, srcEvent.clientY )
      if ele.type ="password" then
    		if ele.value="" then
    			Alert("密码为空")
    		else
    			Alert("密码为:"+ele.value)
    		end if
      end if
    end sub
    
    call GetPassword()
    
      然后在注册表HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下新建一下主键,键名为"取得密码",缺省值设为该htm文件的路径,在该主键下另增一个DWORD值,值为4,表示只在右击表单元素时显示该项.关闭注册表,重新启动IE窗口,点击一下密码框,就会出现该项,点击该项,弹出一个对话框,告诉你的密码 。

    第二种方法:使用VC来实现

      由于VC知识库是一个关于C++以及Visual C++的网站,与脚本语言没什么关系。所以我们要用另一种稍微复杂一点的方法来实现相同的事情,那就是用C++来做。在不同的进程中取得IE的Webbrowser控件的IHTMLDocument2接口,请参阅MSDN上的一篇文章,标题是:HOWTO: Get IHTMLDocument2 from a HWND(根据HWND取得IHTMLDocument2接口)(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q249232).它的实现机理是向Webbrowser控件(窗口类名是"Internet Explorer_Server")发一个WM_HTML_GETOBJECT,然后把返回值传给Microsoft Active Accessibility (MSAA) 函数ObjectFromLresult,这样你会取得一个已经编排(Marshaling)过的COM接口.如下函数所示:

    IHTMLDocument2* GetDocInterface(HWND hWnd) 
    {
    	// 我们需要显示地装载OLEACC.DLL,这样我们才知道有没有安装MSAA
    	HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
    	IHTMLDocument2* pDoc2=NULL;
    	if ( hInst != NULL ){
    		if ( hWnd != NULL ){
    			CComPtr spDoc=NULL;
    			LRESULT lRes;
    			/*由于WM_HTML_GETOBJECT非Windows标准消息,所以需要RegisterWindowMessage*/
    			UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
    			::SendMessageTimeout( hWnd, 
    							nMsg, 
    							0L, 
    							0L, 
    							SMTO_ABORTIFHUNG, 
    							1000, 
    							(DWORD*)&lRes );
    
    			/*取得ObjectFromLresult函数的地址*/
    			LPFNOBJECTFROMLRESULT pfObjectFromLresult = \
    					(LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, 
    								_T("ObjectFromLresult") );
    			if ( pfObjectFromLresult != NULL ){
    				HRESULT hr;
    				hr=pfObjectFromLresult(lRes,
    						IID_IHTMLDocument,
    						0,
    						(void**)&spDoc);
    				if ( SUCCEEDED(hr) ){
    					CComPtr spDisp;
    					CComQIPtr spWin;
    					spDoc->get_Script( &spDisp );
    					spWin = spDisp;
    					spWin->get_document( &pDoc2 );
    				}
    			}
    		}
    		::FreeLibrary(hInst);
    	} 
    	else{//如果没有安装MSAA
    		AfxMessageBox(_T("请您安装Microsoft Active Accessibility"));
    	}
    	return pDoc2;
    } 
    
      这样,我们就取得了IHTMLDocument2*接口了,要取得密码框的密码还得一番周折,首先得构造一个基于对话框的MFC程序,增加一个按钮,在主对话框类增加一个成员变量m_bCapture,在构造函数中初始化为FALSE. 然后处理该按钮的Click事件:
    void CXXXXDlg::OnGetHtmlClick()
    {
    	SetCapture();//跟踪鼠标
    	m_bCapture=TRUE;
    }
    
    接着应该处理WM_LBUTTONUP消息:
    void CXXXXDlg::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    	if(m_bCapture){
    		m_bCapture=FALSE;
    		ReleaseCapture();//释放鼠标
    
    		static TCHAR	buf[100];
    
    		POINT pt;
    		GetCursorPos(&pt);
    		HWND hwnd=::WindowFromPoint(pt);
    		if(hwnd!=NULL){
    			::GetClassName( hwnd, (LPTSTR)&buf, 100 );
    			if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 ){
    				POINT iept=pt;
    				::ScreenToClient(hwnd,&iept);
    				GetPassword(GetDocInterface(hwnd),iept);
    			}
    		}
    	}
    
    	CDialog::OnLButtonUp(nFlags, point);
    }
    
    GetPassword函数是这样实现的,基本可以模仿VBScript的调用,但要复杂一些:
    void GetPassword(IHTMLDocument2* pDoc2,POINT pt)
    {
    	if(pDoc2==NULL)return;
    	CComPtr pElement;
    	HRESULT hr=pDoc2->elementFromPoint(pt.x,pt.y,&pElement);//取得鼠标所在的元素
    	if(SUCCEEDED(hr)){
    		CComPtr pPwdElement;
    		hr=pElement->QueryInterface(IID_IHTMLInputTextElement,
    			(void**)&pPwdElement);//是否有表单输入元素
    		if(SUCCEEDED(hr)){
    			CComBSTR type;
    			hr=pPwdElement->get_type(&type);
    			if(SUCCEEDED(hr)){
    				if(type==_T("password")){//是密码框吗?
    					CComBSTR pwd;
    					hr=pPwdElement->get_value(&pwd);
    					if(SUCCEEDED(hr)){
    						if(pwd.Length()!=0){//有密码则显示
    							CComBSTR msg=_T("密码是:");
    							msg+=pwd;
    							CString str(msg);
    							AfxMessageBox(str);
    						}
    						else{
    							AfxMessageBox(_T("密码为空!"));
    						}
    					}
    				}
    			}
    		}
    	}
    	pDoc2->Release();
    }
    
    使用这种方法要注意:
    1. 如果程序在Windows95,98和NT 4.0 Service With Pack 4 or 5下运行必须要把Microsoft Active Accessibility (MSAA)运行时组件(RDK)与程序一起发布(Windows2000及Windows NT 4.0 Service With Pack 6中已经有了,所以不用);
    2. 这种方法只适用用于Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 4.01 SP2, 5;
    3. 使用这种方法前要调用CoInitialize(NULL);然后应该相应地调用CoUninitialize();
    4. Microsoft Active Accessibility (MSAA)可从 http://www.microsoft.com/enable/msaa/download.htm 下载 ;

    附: 我们也可以使用Active Accessibility(MSAA)获取IHTMLDocument2*接口,见下程序: 

    /*
    函数名:GetDocInterfaceByMSAA 
    参数:hwnd,WebBrowser控件的窗口句柄 
    功能:取得hwnd对应的Webbrowser控件的IHTMLDocument2*接口.
    */

    IHTMLDocument2* GetDocInterfaceByMSAA(HWND hwnd)
    {
    	HRESULT hr;
    	HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
    
    	IHTMLDocument2* pDoc2=NULL;
    	if ( hInst != NULL ){
    		if ( hwnd != NULL ){
    			//取得AccessibleObjectFromWindow函数
    			LPFNACCESSIBLEOBJECTFROMWINDOW pfAccessibleObjectFromWindow =
    				(LPFNACCESSIBLEOBJECTFROMWINDOW)::GetProcAddress(hInst,
    					_T("AccessibleObjectFromWindow"));
    			if(pfAccessibleObjectFromWindow != NULL){
    				CComPtr spAccess;
    				hr=pfAccessibleObjectFromWindow(hwnd,0,
    					//取得Webbrowser控件的IAccessible接口
    					IID_IAccessible,(void**) &spAccess);
    				if ( SUCCEEDED(hr) ){
    					CComPtr spServiceProv;
    					hr=spAccess->QueryInterface(IID_IServiceProvider,
    									(void**)&spServiceProv);
    					if(hr==S_OK){
    						CComPtr spWin;
    						hr=spServiceProv->QueryService(IID_IHTMLWindow2,
    								IID_IHTMLWindow2,
    								(void**)&spWin);
    						/*
    						注意:并不是每次都能取得IHTMLWindow2接口,如果调用失败,
    						可以尝试取得IHTMLElement接口:
    						CComPtr spElement;
    						hr=spServiceProv->QueryService(IID_IHTMLElement,
    						        IID_IHTMLElement,
    							(void**)&spElement);
    						*/
    						if(hr==S_OK)
    							spWin->get_document(&pDoc2);
    					}
    				}
    			}
    		}
    		::FreeLibrary(hInst);
    	}
    	else{
    		AfxMessageBox(_T("请您安装Microsoft Active Accessibility"));
    	}
    	return pDoc2;
    }

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值