有些软件可以把口令和密码的“*”显示出来,是如何实现的?(50分)

  • 主题发起人 主题发起人 dak
  • 开始时间 开始时间
显示为*,实际值是有的。如edit1.text,想办法获得。
 
密码框和普通的编辑框没有本质区别,只是在创建时加入了风格:ES_PASSWORD;
密码框中的内容在内存里并没有加密,只是在绘制编辑框时画上了星号.
所以只要获得密码宽的窗口句柄,想他发送消息: WM_GETTEXT就能得到.
 
呵呵,这是俺前两年发表的一篇文章,你看看吧,呵呵,老陈菜了。
:P

让"*"无所遁形-------简谈"*"形密码截获的程序原理
看到这类程序第一眼,我首先想到的是利用HOOK来实现,这也是一种比较正常的想法,
但在深思之后,发现其实根本用不着烦琐的HOOK,很简单的通过API调用就可以实现此功能。
虽然表面上我们看到的是类似符号"*"的密码暗文,但在系统内部,其内容还是以明文形式
存在,我们所要做的,也就是获取系统内明文的内容。
熟悉Windows编程的人都知道,Windows系统中,每一个控制单元都有自己的名称属性,
无论是窗口还是按纽,或者文本框都是如此。作为窗口,其名称属性(WindowText)显示为
窗口标题,而文本框则显示在其显示区域之中,显示密码暗文的一般都是文本框,虽然显
示的是无法识别原文的字符,但其根本的属性并未改变,我们仍然可以通过标准WinApi来
获得其真实属性。
我们可以通过两个API函数GetWindowTextLength和GetWindowText的配合使用来实现此
功能。
其中,GetWindowTextLength(HWND hWnd)用以获得WindowText的长度。而
GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount )则可获得其属性。
其中的参数HWND为目标句柄,lpString为字符串变量地址,nMaxCount :获得的字符长度
(在此项目中即为getwindowTextLength函数返回值)
下面我们就以比较易于理解的Object Pascal语言谈谈在Delphi中此功能的实现。
假设Form上有一个Maskedit1,内有"*"形的密文,过程如下:
procedure GetPSW;
Var TxtLen:Integer;
WinTxt:PChar;
begin
TxtLen:=GetWindowTextLength(MaskEdit1.handle)+1;
GetMem(WinTxt,Txtlen);
//获得MaskEdit中的密文长度并为用来存储明文的字符串WinText分配内存
GetWindowText(MaskEdit1.handle,WinTxt,TxtLen);
showmessage(String(WinTxt));
//获得Mawkedit1中的密文原码并加以显示
FreeMem(WinTxt,0);
//释放占用的内存。
end;

这样我们就从理论上验证了获得密码的可行性。然而,从实用角度考虑,往往密码
都是在其他运行程序的窗口中出现,如何获得其他窗口中的"*"的密码原文呢?这就需要
GetCursorpos等函数的配合使用。
在Delphi中,函数getcursorpos()可返回当前的鼠标光标坐标,而windowfrompoint()
则可返回当前指定位置的窗口的句柄。如此一来,我们的问题便迎刃而解。
如上假设,例程可更改如下:
procedure GetPSW;
Var TxtLen:Integer;
WinTxt:PChar;
Wnd:hWnd;
P:TPoint;
begin
getcursorpos(p);//返回当前光标位置
wnd:=windowfrompoint(p);//返回当前光标所在位置的窗口句柄
TxtLen:=GetWindowTextLength(wnd)+1;
GetMem(WinTxt,Txtlen);
//获得MaskEdit中的密文长度并为用来存储明文的字符串WinText分配内存
GetWindowText(wnd,WinTxt,TxtLen);
showmessage(String(WinTxt));
//获得Mawkedit1中的密文原码并加以显示
FreeMem(WinTxt,0);
//释放占用的内存。
end;

这样,我们就可以显示出其他窗口的"*"形密码原文了,配以合适的激活方式,则一
个所谓密码破译软件便可大功告成。
同时,通过对下载例程的分析,发现下载例程使用的并非API函数方法,而是利用
SendMessage来实现这一功能,下面是笔者将其改写过后的片段:
TxtLen:=sendmessage(wnd,wm_gettextlength,0,0)+1;
setlength(Wintxt,TxtLen);
sendmessage(wnd,wm_gettext,len,LongInt(@WinTxt[1]));
可以看到,通过Sendmessage向目标句柄发送wm_gettextlength以及wm_gettext消息
可以达到同样的目的。
好了,无论采用哪一种方法,我们现在都已经实现了目标,本文也就结束了。
 
to nuke:我按你所说的编了,但不行。只有按你后面小半段所说,也即按xwolf所说,发消息就可以了。前面讲的那么多,是行不通的。本想让你们俩平分50分,不过
你让我走了点弯路,就少给你一些吧。
 
多人接受答案了。
 
to xwlof:非常抱歉,应该给你的35分,由于操作失误给错分了!再次抱歉!
 
sorry 我来还给xwlof吧。
 
后退
顶部