📄 spwdspy.html
字号:
<pre><font face="Times New Roman"><font color="#800000"> &&| </font></font><font color="#800000" face="Times New Roman">::lstrcmp(szClassName, _T("</font><font color="#800000" face="Times New Roman">ThunderTextBox")) != 0</font><font face="Times New Roman"><font color="#800000"> ) return FALSE;
</font><font color="#008000"><span class="codeComment">//Here, is it OK?</span></font><font color="#800000">
DWORD dw = ::GetWindowLong(hWnd,GWL_STYLE);
dw &= ES_PASSWORD;
if(dw == ES_PASSWORD)
return TRUE;
return FALSE;
}</font>
</font></pre>
<p><font face="Times New Roman">Above is the implementation of <b><font color="#000080">SuperPasswordSpy++</font></b>. But, in a tool sample called Eureka (residing in <a href="http://www.codeguru.com/samples/Eureka.shtml"> http://www.codeguru.com/samples/Eureka.shtml</a>, unfortunately this tool is for Win9X/Me), the author judges a password edit if its class name is "TEDIT," "IRIS.PASSWORD," or "EDIT." I played with Delphi and Borland C++ six years ago, and I know it is Borland's name convention TxxxClass. But I have no Delphi at hand, so if anyone can help check this, please comment below.
As to the "ThunderTextBox", it is created by Visual Basic. Thanks in advance. And I will add multiple name matching if necessary.
Well, of course, it is impossible to cover all cases for the class name can be
changed by developers arbitrarily (for example, who knows what is the password
edit name in Visual Studio 2003?). If it is such case, please modify the source
of my <b><font color="#000080">SuperPasswordSpy++</font></b> yourself. </font></p>
<p><font face="Times New Roman"><b>2. When Multiple Frame Sets Exist Inside an Html Document...</b></font></p>
<p><font face="Times New Roman">The current (Dec. 2002) version of <b><font color="#000080">SuperPasswordSpy++</font></b> assumes there is only one frame inside an HTML document if it contains a password field. It is fine with most passworded homepages (for example, MSN Hotmail). But, to make it perfect, I will add multiple frame set support in next version of <b><font color="#000080">SuperPasswordSpy++</font></b>. Please check this in my site later.</font></p>
<h3><font face="Times New Roman">More Words about *****</font></h3>
<p><font face="Times New Roman"><b>1. Windows Logon Password: (Win2K ONLY)</b></font></p>
<p><font face="Times New Roman">It sounds a little crazy, but please look at the following figure:</font></p>
<p><font face="Times New Roman">
<img src="SPwdSpyInterface3.jpg" width="500" height="341"></font></p>
<p><font face="Times New Roman"><em>Figure 5: SuperPasswordSpy++'s Peeking "Change Your Password" on WinLogon Screen of Win2K Server</em></font></p>
<p><font face="Times New Roman">I have only the Japanese Win2K server at hand, so there is some Japanese here, but I think you can see it is from "Ctrl+Alt-Del," then press the "Change Password" button. <b><font color="#000080">PasswordSpy++</font></b> has been launched <b>under SYSTEM context on Winlogon Desktop</b> of this Win2K, and it works. I mean, it can read the password from the "Change Password" Dialog. Oh, by the way, you will never know the current password because it is never shown.</font></p>
<p><font face="Times New Roman">To conduct this experiment, you have to use some tool to launch a program on Winlogon Desktop of Windows. You can go
<a href="http://www.codeguru.com/misc/RunUser.html">
http://www.codeguru.com/misc/RunUser.html</a> to get my "GUI RunAs" program. You have to choose Winlogon desktop, make the user name edit box blank to use SYSTEM identity, and remember you must have Administrator rights to do so. Follow the article's instructions and you may need to log off the current session once (only once) to enable some privileges if you do not already have them. Some reader sent me e-mail saying there is
already a "Runas" command line tool in Windows OS already. I know, <b>but with this
MS-brand RunAs command-line tool, you can NOT choose the Desktop to launch the program
while my tool works.</b> If you have problems with the tool (for example, the launched program's GUI is blocked), please launch the tool itself as SYSTEM first, and then launch the program you use.</font></p>
<p><font face="Times New Roman">The last word: To get the screen shot, press "Print Screen" when you are on the Winlogon desktop, go to the default desktop, and paste it into MSPaint. You can also use the RunAs tool to launch MSPaint onto the Winlogon
screen too, and do your job there without switching back and forth. And, you may find this RunAs GUI tool is a good way to launch a task manager as SYSTEM and kill some stubborn process (including NT Service).
</font></p>
<p><font face="Times New Roman"><b>2. Anti Peeking Edit and Crack Anti-Peeking Edit ( -* - = +)</b></font></p>
<p><font face="Times New Roman">I notice someone asked how to do anti peeking. Well, it does not cost too much to implement anti-peeking. Following is a code example using MFC. First, derive an edit class from CEdit. My first idea is to override its PreTranslate, this way:</font></p>
<pre><font face="Times New Roman"><font color="#800000">BOOL CAntiPeekEdit::PreTranslateMessage(MSG* pMsg)
</font><font color="#008000"><span class="codeComment">//This does NOT work!</span></font><font color="#800000">
{
if(pMsg->message == WM_GETTEXT)
{
<span class="codeComment"> </span></font><span class="codeComment"><font color="#008000">//Only Report Text When Passing a Fixed Length Buffer;</font></span><font color="#800000">
if(pMsg->wParam == 1024) <span class="codeComment">//The Number Only You Know</span>
{
}
else
{
::lstrcpy((LPTSTR)(pMsg->lParam), _T("Nothing"));
return TRUE;
}
}
return CEdit::PreTranslateMessage(pMsg);
}</font>
</font></pre>
<p><font face="Times New Roman">Unfortunately, the inside if clause will never be called. Why? MFC team guys know. Well, I have to turn to the virtual function WindowsProc; this time it works:</font></p>
<pre><font face="Times New Roman"><font color="#800000">LRESULT CAntiPeekEdit::WindowProc( UINT message,
WPARAM wParam,
LPARAM lParam)
</font><font color="#008000"><span class="codeComment">//This works!</span></font><font color="#800000">
{
if(message == WM_GETTEXT)
{
if(wParam == 1024) </font><font color="#008000"><span class="codeComment">//The Number Only You Know</span></font><font color="#800000">
{
return CEdit::WindowProc(message, wParam, lParam);
}
else
{
::lstrcpy((LPTSTR)(lParam), _T("Nothing"));
<span class="codeComment"> </span></font><span class="codeComment"><font color="#008000">//Insert Dummy Text Here To the Peeker</font></span><font color="#800000">
return 7;
}
}
return CEdit::WindowProc(message, wParam, lParam);
}</font>
</font></pre>
<p><font face="Times New Roman">In your own program, when you want to get the password text, you must do the following:</font></p>
<pre><font face="Times New Roman"><font color="#800000">TCHAR sz[1024];
::SendMessage(hPasswordEdit, WM_GETTEXT, 1024, (LPARAM)sz);</font>
</font></pre>
<p><font face="Times New Roman">If other routines call to retrieve the password, WM_GETTEXTLENGTH will tell them the correct length, but when the correct length buffer is to our AntiPeekEdit, we know it is called from some other un-secure source, so we can just send back the junk. Well, you can also abandon WM_GETTEXT completely and use a WM_USER + 123 message to get the text out.</font></p>
<p><font face="Times New Roman">Let's go back to how to counterstrike this kind of AntiPeekEdit. Well, we know the reason we use hook DLL and query password from inside the remote process is the Win2K password-style edit will not accept WM_GETTEXT from outside the process boundary. And, the above strategy replaces the standard Edit class Windows Procedure with a user-defined one. So, how about replacing this user-defined procedure back to the standard Edit class Windows Procedure when our lovely <b><font color="#000080">SuperPasswordSpy++</font></b> peeks it:</font></p>
<pre><font face="Times New Roman"><font color="#800000">HWND hParent = ::GetParent(g_hTarget);
</font><font color="#008000"><span class="codeComment">//g_hTarget is the password edit handle we are interested</span></font><font color="#800000">
HWND hwndEdit = CreateWindow(
_T("EDIT"), </font><font color="#008000"><span class="codeComment">// predefined class</span></font><font color="#800000">
NULL, <span class="codeComment">// no window title</span>
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
0, 0, 0, 0, </font><font color="#008000"> <span class="codeComment">// set size in WM_SIZE message</span></font><font color="#800000">
hParent, </font><font color="#008000"><span class="codeComment">// parent window</span></font><font color="#800000">
(HMENU)123,
</font><font color="#008000"><span class="codeComment">// edit control ID -- Note: Must be Unique Among Sibling Windows</span></font><font color="#800000">
(HINSTANCE) GetWindowLong(g_hTarget, GWL_HINSTANCE),
NULL); // pointer not needed
</font><font color="#008000"><span class="codeComment">//Get the standard Windows Procedure of Edit class</span></font><font color="#800000">
LONG_PTR lpNewEdit = GetWindowLongPtr(hwndEdit, GWLP_WNDPROC);
LONG_PTR lp = ::SetWindowLongPtr(g_hTarget, GWLP_WNDPROC,
(LONG_PTR)lpNewEdit);
</font><b><font color="#008000"><span class="codeComment">//Password Fetch Here --- I only use this call in
//SuperPasswordSpy++</span></font><font color="#800000">
SendMessage(g_hTarget, WM_GETTEXT, sizeof(szBuffer) /
sizeof(TCHAR), (LPARAM)szBuffer);</font></b><font color="#800000">
</font><font color="#008000"><span class="codeComment">//Reset the original Windows Procedure</span></font><font color="#800000">
::SetWindowLongPtr(g_hTarget, GWLP_WNDPROC, (LONG_PTR)lp);</font>
</font></pre>
<p><font face="Times New Roman">Please note the Control ID parameter when creating the fake edit; it must be unique among its siblings. Well, I use 123 as a placeholder here. You can write addition code to enumerate the sibling windows and get a unique ID, and remember to destroy the fake edit in the end.</font></p>
<p><font face="Times New Roman">But, it is really an overkill in most cases, so I did not include the above code in <b><font color="#000080">SuperPasswordSpy++</font></b> to keep performance and stability high. But, once you really meet such a anti-peek password edit, uncomment the additional code in the <b><font color="#000080">SuperPasswordSpy++ </font></b>source code, and keep an eye on keeping the fake edit control ID unique.</font></p>
<p><font face="Times New Roman">If someone is mad asking if we have way to anti- anti- anti-peeking, well, maybe you can add a global variable flag, before you fetch password set this flag, and after reading, reset it.... Then why not use some algorithm to encode the text in WM_GETTEXT handler? <b>faint..</b>.</font></p>
<p><font face="Times New Roman"><b>3. More Peeking Spy Tools...</b></font></p>
<p><font face="Times New Roman"> If you need to peek into MSN Messenger/Windows Messenger inside information and chat contents, please refer to my previous article MessengerSpy++ (residing in <a href="http://www.codeguru.com/misc/MessagerSpy.html">http://www.codeguru.com/misc/MessagerSpy.html</a>). The following figure shows we can get the 100% fresh RTF text and these Emotional Icons from MSN Messenger (the right-side window). Note: it is for Win2k/XP and support MSN Messenger 4.6, 4.7, and 5.0. And what's more, it can send text/icons to MSN Messenger and let Messenger send it to the other person.</font></p>
<p><font face="Times New Roman">
<img src="SPwdSpyInterface4.jpg" width="500" height="334"></font></p>
<p><font face="Times New Roman"><em>Figure 5: Mate Tool MessengerSpy++'s Peeking a MSN Messenger Chat on WinXP</em></font></p>
<p><font face="Times New Roman"><b>3. WinXP "Change User Password" Control Panel Applet</b></font></p>
<p><font face="Times New Roman">Unfortunately, even it is inside "Internet Explorer_Server" (res://D:\WINDOWS\system32\nusrmgr.cpl/nusrmgr.hta), the password input field is inside an ActiveX with CLSID:A5064426-D541-11D4-9523-00B0D022CA64 in my English WinXP Professional. So, it is completely impossible to read the password from the ActiveX black box.</font></p>
<h3><font face="Times New Roman">Acknowledgements</font></h3>
<p><font face="Times New Roman">Thanks to the following article/code contributor on CodeGuru: Mr. Giancarlo Iovino for his HyperLink Control (I fixed a few lines of code so it can go under Unicode now), and Mr. Brian Friesen for his thesis-level article and tool <a href="http://www.codeguru.com/samples/pwdspy.html">PasswordSpy</a>.</font></p>
<h3><font face="Times New Roman">Downloads</font></h3>
<!-- demo and source files -->
<p><font face="Times New Roman"><a href="SPwdSpyDemo_Src.zip">Download Demo Project Source</a> (all the source code + exe) - 142 Kb<br>
<a href="SPwdSpyDemo_Exe.zip">Download Demo Exe File Only</a> (Exe + DLL Only, MFC library static linked) - 373 Kb</font></p>
<p>丂</p>
<h3><font face="Times New Roman">Version History</font></h3>
<table cellSpacing="2" cellPadding="2" border="2">
<tr vAlign="top" bgColor="#ffff99">
<td><font face="Times New Roman"><b>Version</b></font></td>
<td><font face="Times New Roman"><b>Release Date</b></font></td>
<td><font face="Times New Roman"><b>Features</b></font></td>
</tr>
<tr vAlign="top">
<td><font face="Times New Roman">1.1</font></td>
<td><font face="Times New Roman">2003.m.d</font></td>
<td><font face="Times New Roman">Support For IE Multiple Frame Set Password Peeking</font></td>
</tr>
<tr vAlign="top">
<td><font face="Times New Roman">1.0</font></td>
<td><font face="Times New Roman">Dec 7, 2002</font></td>
<td><font face="Times New Roman">First Version</font></td>
</tr>
</table>
<H3><font face="Times New Roman">History</font></H3>
<font face="Times New Roman">Date Posted: December 27, 2002<BR>
<!-- Only use the following if the article is updated -->
<!-- Date Last Updated: [today's date in the format month day, year] ---><BR>
</font>
<!--#include virtual= "footer.shtml" -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -