首页
社区
课程
招聘
[原创]*号密码获取工具(VC++ MFC版) (带源代码)
发表于: 2007-2-4 12:35 5277

[原创]*号密码获取工具(VC++ MFC版) (带源代码)

2007-2-4 12:35
5277
                               *号密码获取工具(VC++  MFC版) (带源代码)               By Jacky Chou

   没有什么技术含量,写出来,只是为了说明*号的获取过程,在VC中是如何通过消息机制来实现的。高手不要见笑!
   
   通常情况下,我们很多程序中经常会需要输入密码,如一些拨号软件,在输入密码框中经常是以*号的形式显示的,那我们如何把*变成密码

呢?
  
   我们可以自己新建一个MFC工程,添加一个EDIT控件,在其属性里面我们可以看到其中一个password属性,我们选中该选项的时候,那我们

不管在该EDIT中输入什么内容,都是以*号的形式显示的。知道这个原理,我想我们可以通过以下步骤把*号中的密码给截获下来。

   实现方法: 1,既然*号密码是因为给EDIT设置了PASSWORD属性,使其变成*号形式,那我们把其PASSWORD属性去除了不就可以显示原来的真实

密码了,实践证明是正确的,所以,第一步就是把EDIT中的PASSWORD属性给去除了!
             2,其实,经过第一步,密码就会在EDIT中还原出来,那为什么很多程序都是截获密码到自己的程序,而不是在原程序中将其显示

呢?其真正原因是,在经过第一步后,我们就可以把该EDIT中的字符密码给获取下来,然后将其还原成PASSWORD属性,所以我们通常看到的是

别人程序中的*号密码在另外一个程序中显示,其实都是先把PASSWORD属性去除的,获取真实的字符密码后,再将其还原成原来的属性。(个人

认为)。  当然,你可以只做第一步,就可以看到密码了。

   好,下面我们看在VC中如何以消息的机制来实现。
   
   查看MSDN,查看 EM_SETPASSWORDCHAR
  
   我们可以看到以下内容:

   This message sets or removes a password character displayed in a single-line edit control when the user types text. When a

password character is set, that character is displayed in place of each character the user types.

  EM_SETPASSWORDCHAR
  wParam = (WPARAM)(UINT) ch;
  lParam = 0;

Parameters
  ch
Specifies the character to be displayed in place of the character typed by the user. If this parameter is zero, the

characters typed by the user are displayed.    //如果ch 为0,那么字符就会显示出来。

lParam
Not used; set to 0.

Return Values
None.

Remarks
When the EM_SETPASSWORDCHAR message is received by an edit control, the edit control redraws all visible characters by using

the character specified by the ch parameter.

If the edit control is created with the ES_PASSWORD style, the default password character is set to an asterisk (*). This

style is removed if an EM_SETPASSWORDCHAR message is sent with the ch parameter set to zero.

  我们只要看注视下的内容就可以知道,如何EDIT控件是以ES_PASSWORD方式创建的,那么默认的字符将会以*号的设置。如果一个消息

EM_SETPASSWORDCHAR以ch参数为0发送给EDIT的话,那么EDIT控件的*号属性就会被去除了,也就是显示原来的字符了。

  知道了上面的原理,我想我们实现就迎刃而解了。

  下面看程序代码

  /*  *号密码获取工具关键代码部分 */

POINT  curponit;      //声明全局变量
HWND   curhwnd;
CWnd   *curwnd;

//初始化函数 OnInitDialog()下
SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|WS_EX_TOPMOST);  //设置顶层窗口
SetTimer(1,1,NULL);       //设置1MS的一个时钟

//OnTimer消息函数下
void CPassWordGetDlg::OnTimer(UINT nIDEvent)
{
        // TODO: Add your message handler code here and/or call default
        if (1 == nIDEvent)
        {
                GetCursorPos(&curpoint);               //获取鼠标坐标
                curwnd = WindowFromPoint(curpoint);   //转换成窗口指针
                curhwnd = curwnd->GetSafeHwnd();            //获取窗口句柄

                CString pointpos,password;
                pointpos.Format("X:%d,Y:%d",curpoint.x,curpoint.y);
                GetDlgItem(IDC_POINT)->SetWindowText(pointpos);     //显示鼠标坐标

                //获取EDIT属性
                LONG lstyle = ::GetWindowLong(curhwnd,GWL_STYLE);
                if (lstyle&ES_PASSWORD)
                {
                        //还记得我们从MSDN里看到的,那个ch参数要设置为0,lParam是没有使用,也设置为0
                        //通过发送该消息后,密码的*号属性就去除了,如果只到这里,密码就还原了。
                        LONG PassToChar = ::SendMessage(curhwnd,EM_GETPASSWORDCHAR,0,0);
                        ::PostMessage(curhwnd,EM_SETPASSWORDCHAR,0,0);
                       
                        char szChar[50];
                        memset(szChar,0,sizeof(szChar));
                       
                        //然后我们要获取EDIT中的密码到自己的程序。
                        ::SendMessage(curhwnd,WM_GETTEXT,50,(LPARAM)szChar);

                        //密码我们也已经拿到了,把*号属性把它还原把!
                        ::PostMessage(curhwnd,EM_SETPASSWORDCHAR,PassToChar,0);

                        //把获取的密码获取到自己的程序
                        password.Format("%s",szChar);
                        GetDlgItem(IDC_PASSWORD)->SetWindowText(password);
                }
               
        }
        CDialog::OnTimer(nIDEvent);
}

    程序在WinXP Sp2  VC++ 6.0 EnterPrise English Version 下编译通过,测试成功!

    总结:我们也发现了,我们用到了PostMessage和SendMessage,这2个函数有区别的,如果下面的函数
    LONG PassToChar = ::SendMessage(curhwnd,EM_GETPASSWORDCHAR,0,0);改成PostMessage话,我们会发现EDIT框不是恢复成*号,而是变

成一个方格。
    如果函数::SendMessage(curhwnd,WM_GETTEXT,50,(LPARAM)szChar);我们改成PostMessage,我们会发送,密码没有办法获取到我们的程序

中。
    那这2个函数到底有多大区别呢?我们看下MSDN的说法:
   SendMessage
   This function sends the specified message to a window or windows. SendMessage calls the window procedure for the specified

window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts

a message to a thread's message queue and returns immediately.
   
   我们发现postmessage函数是发送消息到消息队列立即返回的,而sendmessage是等待进程处理完消息后再返回的。
   我个人的理解是,如果在获取EDIT密码框属性的时候如果用postmessage的话,可能获取不到,所以无法恢复成*号,获取密码字符也是同样

的道理。

   源代码下载
   Download-Link:
http://www.live-share.com/files/151396/PassWordGet.rar.html

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 214
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持支持!!!
有代码都要学习一下!!!
2007-2-4 13:09
0
游客
登录 | 注册 方可回帖
返回
//