有个网页,用showmodeldialog打开的,没有工具栏、菜单,对右键没反应。
请问怎么用VC编写一个外挂程序,修改网页中text文本框的值?
有重赏!!!
参见:
http://expert.csdn.net/Expert/topic/2221/2221243.xml?temp=.8733637
两贴并一贴给分。

解决方案 »

  1.   

    贴一篇csdn的帖子给你,是讲如何取得网页密码的,你可以参考,只不过一个是get一个是set的区别,做个系统钩子把
      

  2.   

    本文将讲述如何在win2000下如何编程实现得到应用程序中的密码框中的密码及网页密码框中的密码
    记得在win98的时候,只要向一个密码框发一个WM_GETTEXT的消息就可以很容易的得到了其中的密码,微软可能已经意识到了,这一个不安的因素,在win2000/xp中,像以前那样写一个应用程序,向别的程序的密码框简单的发送一个WM_GETTEXT的消息就得到密码了,原因是在进程间数据是相互隔离的,如果参数窗口句柄不属于该进程的调用线程,函数执行就会失败,为了解决这个问题,我们可以用钩子函数实现,钩子函数一般存于动态链接库中,win32会自动把动态链接库映射到它影响的各个进程,在这其间该动态链接库的其它函数也会连带映射到运行的进程之中。这样钩子函数也就会和它的寄主程序窗口融为一体。在这样的一个进程中,由于dll的插入映射使得函数参数窗口句柄hwnd就属于该进程了,而这是win32所允许的。所以写一个dll并将其注入到有密码的进程中,这样就可以dll看成进程的一步分了,再用WM_COPYDATA来进行进程的通信,来将密码显示发送到我们要显示的程序中。
    好了理论说完了,开始动手用vc做一个程序了。
    先建立一个基于对话框的程序GetPass,其它选项为默认值。
    再加入一个edit控件,其ID为IDC_EDIT1用来显示得到的密码信息。
    在CGetPassDlg::OnInitDialog()的最后中加入
    const CWnd * pWndInsertAfter;
     pWndInsertAfter = &wndTopMost;
     SetWindowPos(pWndInsertAfter,0,0,0,0,SWP_NOSIZE);//将窗口放于最上层 SetTimer(1,100,NULL);//每隔500毫秒来取得一次密码。 BOOL k=InitHook(this->m_hWnd);//挂接钩子
     if(k==FALSE)
      AfxMessageBox("false");
    重载OnTimer函数,加入如下代码
     HWND hwnd;
     CPoint MousePos;
     GetCursorPos(&MousePos); //取得当前鼠标的坐标 hwnd= ::WindowFromPoint(MousePos);//得到当前坐标的对应窗口的句柄
     GetPassText(hwnd, m_hWnd);//调用这个函数来取得密码 得用classwzard为消息WM_COPYDATA加入响函数OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)加入如下代码,来得到dll传来的密码:
     SetDlgItemText(IDC_EDIT1, (LPCTSTR)pCopyDataStruct->lpData);
    这时编译我们的程序时会有两个错误如下
    error C2065: 'InitHook' : undeclared identifier
    error C2065: 'GetPassText' : undeclared identifier
    这两个函数是我们要在dll中建立。所以我们再新建一个名为Password的project,选择MFC AppWizard(dll),并且Add to Current Workplace
    并且选择add to current workspace.其它的按照默认值。
    先在Password.cpp的最上面加入变量与宏定义#define MAX_TEXTLEN 1024
    #define UM_GETPASS WM_USER + 0x392
    HINSTANCE ghInstance = 0;
    #pragma data_seg("ALLDATA")
     HHOOK g_hHook = NULL;
     HINSTANCE g_hDllIns = NULL;
     HWND g_hHostWnd = NULL;
    #pragma data_seg()再改写一下Password.def其代码如下:
    LIBRARY      "Password"
    DESCRIPTION  'Password Windows Dynamic Link Library'
    EXPORTS
       InitHook   @1
     ReleaseHook   @2
     GetPassText   @3
    SECTIONS
     ALLDATA SHARED
    //我们手动加入的函数声明与变量
    利用classwzard为CPasswordApp加入CPasswordApp::InitInstance()
    其中的代码为:  g_hDllIns =AfxGetInstanceHandle();
     DisableThreadLibraryCalls(g_hDllIns);
    再在Password.cpp中的全局变量CPasswordApp theApp之后加入如下代码:LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
    {
     try {
      if (code >= 0){   LPMSG pMsg = (LPMSG)lParam;   HWND hShowPassWnd = (HWND)pMsg->lParam;   if (pMsg->message == UM_GETPASS && g_hHostWnd == hShowPassWnd){ //获取*号中的内容    HWND hPassWnd = (HWND)pMsg->wParam; //*号窗口的HWND    if (hPassWnd){
         TCHAR szPassText[MAX_TEXTLEN];
         ZeroMemory(szPassText, MAX_TEXTLEN);
         ::SendMessage(hPassWnd, WM_GETTEXT, MAX_TEXTLEN, (LPARAM)szPassText); //获取内容
         
         COPYDATASTRUCT cd;
         ZeroMemory(&cd, sizeof(cd));
         cd.dwData = (DWORD)hPassWnd;
         cd.cbData = strlen(szPassText) + 1;
         cd.lpData = szPassText;
         SendMessage(hShowPassWnd, WM_COPYDATA, (WPARAM)hPassWnd, (LPARAM)&cd);//发送给ShowPass窗口
        }
       }
      }
     }
     catch(...){
     }
      

  3.   

    return CallNextHookEx(g_hHook, code, wParam, lParam);
    }
     BOOL  InitHook(HWND hWnd)
    {
     try {
      if (!hWnd){
       return FALSE;
      }  g_hHostWnd = hWnd;
      g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hDllIns, 0);
      return g_hHook != NULL;
     }
     catch (...){
     
      return FALSE;
     }
    }
    HWND WINAPI GetParentFromHwnd(HWND hWnd)
    {
     HWND hParWnd;
     try {
      do {
       hParWnd = GetParent(hWnd);
       if (hParWnd){
        hWnd = hParWnd;
       }
      }while (hParWnd);
     }
     catch (...){
     } return hWnd;
    }void  GetPassText(HWND hWndPass, HWND hWndShowPass)
    {
     try {
      HWND hParWnd = GetParentFromHwnd(hWndPass);
      ::PostMessage(hParWnd, UM_GETPASS, (WPARAM)hWndPass, (LPARAM)hWndShowPass);
     }
     catch(...){
     }
    }
    //卸载
     BOOL  ReleaseHook()
    {
     BOOL bSuccess = FALSE;
     try {
      if(g_hHook != NULL)
      {
       bSuccess = UnhookWindowsHookEx(g_hHook) ? TRUE : FALSE;
       g_hHook = NULL;
       g_hHostWnd = NULL;
      }
     }
     catch (...){
     }
     return bSuccess;
    }
    再在Password.h中加入函数导出声明
    extern "C" _declspec(dllexport) void  GetPassText(HWND hWndPass, HWND hWndShowPass);
    extern "C" _declspec(dllexport) BOOL  InitHook(HWND hWnd);
    extern "C" _declspec(dllexport) BOOL  ReleaseHook();最后编译、链接,把生成的Password.dll,Password.lib拷贝到GetPass工程的目录下,在GetPass工程的GetPassDlg.cpp的最上面加入如下代码
    #pragma comment(lib,"Password.lib")
    //隐式链接
    extern "C" _declspec(dllexport) void  GetPassText(HWND hWndPass, HWND hWndShowPass);
    extern "C" _declspec(dllexport) BOOL  InitHook(HWND hWnd);
    extern "C" _declspec(dllexport) BOOL  ReleaseHook();
    最后运行程序,把鼠标指向应用程序的密码框就可以看到密码了。
    但是我们把鼠标指向网页上的密码框时我们无法得到其内容,因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.
    在msdn上可以找到在不同的进程中取得IE的Webbrowser控件的IHTMLDocument2接口的方法它的实现机理是向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<IHTMLDocument> 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<IDispatch> spDisp;
         CComQIPtr<IHTMLWindow2> spWin;
         spDoc->get_Script( &spDisp );
         spWin = spDisp;
         spWin->get_document( &pDoc2 );
        }
       }
      }
      ::FreeLibrary(hInst);
     } 
     else{//如果没有安装MSAA
      AfxMessageBox(_T("请您安装Microsoft Active Accessibility"));
     }
     return pDoc2;
    }
      

  4.   

    贴一篇codeguru的帖子给你,是讲如何取得网页密码的,你可以参考,只不过一个是get一个是set的区别
    www.codeguru.com/ieprogram/SPwdSpy.html
      

  5.   

    我是个初学者,知道vc的框架。我感觉这个方法可能不行:网页这东西可烦人,ie只是解释内存的内容。不象软件,实实在在,显示与程序一致。网页的text框中的内容在内存理的位置前后不一样。
    反正我也说不清楚。我先试试。另外,能不能向正在下载的网页里加一点我自己的html代码?这样的话,此问题就容易了。
      

  6.   

    用鼠标钩子没法设置网页text的值