必威体育Betway必威体育官网
当前位置:首页 > IT技术

星号密码查看器原理完全揭秘

时间:2019-10-12 19:43:28来源:IT技术作者:seo实验室小编阅读:88次「手机版」
 

星号密码查看器

星号密码一般分为窗口和网页两种,密码一般以“*”字符显示,也有些以其它字符比如圆点或#显示,在编程中可以设置任意字符为密码掩码。密码框一般为编辑框(Edit),也叫文本框(TextBox),也有些是自绘框,这里我们只看标准Edit,密码框具有一个ES_PASSword的样式,普通Edit没有。但是,并不是所有显示“*”号的都是密码框,有些看似是密码框,其实是伪密码框,或者说是“真”星号,就是说它根本就是一个普通的Edit,密码原本就是*字符,而不是掩码,这种框用句柄工具(ViewWizard)查看,看到的是*号,而看不到真正的密码,这种情况一般是设计者为了保留密码位数而临时设置的,单击它会直接清空密码,因为它里面存放的是*,如果不清空程序就会把*当成是真正的密码,从而发生错误,所以对于这种情况,是看不到密码的。

   如何查看原本的密码呢?我们可以用一个消息:EM_GETPASSWORDCHAR和EM_SETPASSWORDCHAR,一个是获取密码字符,一个是设置密码字符,获取到的是密码掩码的ASCII码,要显示密码,我们先将密码框设置为0字符,将它变成一个普通的文本框,然后真正的密码就显示出来了,然后再用常规的WM_GETTEXT消息,即可复制密码框文本,之后再还原,否则密码就会一直显示。顺便说一下WM_GETTEXT消息,这个消息是用来获取编辑框的内容,但是它也可以用来获取“窗口”内容,实际上编辑框也是窗口,但是在获取和设置文本时稍有不同。普通的窗口(非Edit控件)获取和设置文本一般用GetWindowText和SetWindowText,获取窗口文本长度用GetWindowTextLength,包括Button(按钮)、Static(静态控件)等都可以用这些函数,但Edit比较特殊,因为它的内容比较多,不像窗口标题一样,只有一行,所以Edit文本不能用上面说的函数,而必须借助WM_GETTEXT和WM_SETTEXT消息实现,获取长度用WM_GETTEXTLENGTH,后者可兼容前者,用后者的方法也可对前者进行修改,反过来不行。但是,GetWindowText并非间接调用WM_GETTEXT,设置也一样,你可以在窗口函数中hook掉WM_GETTEXT或WM_SETTEXT,别的程序便不能控制你的窗口内容了,但用Get/Set之类的仍然能改变或获取你的窗口标题。

   到现在你可能以为可以自己做一个星号密码查看器了,其实问题没那么简单,还有个搜索问题需要解决。要查看密码,就要先找到密码窗口,如何搜索窗口呢?星号查看器程序一般用WindowFromPoint来获取鼠标所在位置的窗口,获取鼠标位置可以用GetCursorPos,当然有人喜欢用钩子,钩子虽灵活但容易被拦截,这里我们用GetCursorPos+定时器。接下来,你会发现有些窗口无法获取,比如WinRAR的设置密码窗口,这是为什么呢?其实WinRAR并没有拦截我们的代码,而是WinRAR的界面有许多“框架”窗口,这些窗口是透明的,而且比其它控件都要大,所以挡住了其它控件,而WindowFromPoint的搜索顺序是按窗口Z轴进行的,也就是先搜索最上层的窗口或控件,所以虽然后面的控件能够看到,可是却获取不到。如何才能做到精准搜索呢?我们可以自己编一个函数,当发现一个子窗口,就递归搜索它的兄弟窗口,看有没有比它Size小的,有的话就把小的当作搜索目标,问题就解决了。然而,很少有软件解决了这个问题,我知道的能精确搜索的软件有微软的Spy++,还有我自己的ViewWizard,还有个WndSpy等。不过,测试发现Spy++还是有漏洞的,或者说不算太精确,有些窗口它仍然搜索不到,比如某些无效(disabled)的控件。如此,问题算基本上解决了,但还有一个问题,就是透明窗口问题,有些窗口具有WS_EX_TRANSparent样式,鼠标是点击不到的,用WindowFromPoint是搜索不到的,ChildWindowFromPointEx函数说是能够搜索透明窗口,实际测试仍然搜索不到,这个问题虽然不是很重要,但要解决还是很容易的,只需重新遍历一次目标窗口之上的顶层窗口即可。透明窗口目前只有ViewWizard工具能够搜索,尚无发现有其它软件支持透明窗口的搜索。除了搜索之外,还可以用其它方法,例如遍历,这种方法不存在上述的问题,但是遍历也有不同的方法,例如典型的Enumwindows/EnumChildWindows,这两个函数都无法获取隐藏窗口(这里的隐藏指进程在内核中hook了NtUserQueryWindow,而非窗口的Style属性),但GetWindow却能获取,不过这一点并不影响我们获取密码,可以不考虑这个。另外,星号查看器程序只适用于标准Edit控件,如果密码框非以上标准Windows控件,比如是自写控件,非窗口类,那用以上方法就无法获取密码了。

   好了,窗口密码查看器已经实现了,接下来看网页密码。能否获取网页密码和浏览器有关,不同的浏览器方法不同,这里以IE为例,谈一下如何查看IE网页中的星号密码。要获取网页对象,在工程中需要引用一个mshtml.tlb的库,然后就能操作一个网页元素了,把页面元素复制过来,判断是否包含密码(password)元素,有则是密码,没有则不代表一定没有密码,因为password类型可以改成别的,不过没关系,只要能看到星号,我们就能查看密码,只要遍历页面所有元素,就能找到密码值。然而,网页元素也要面对一个窗口对象所遇到的问题,前面说了,框架形式的窗口会阻碍我们搜索下层的窗口,同样的,框架页面元素也会屏蔽掉它里面的子元素,框架类(IFRAME)也是一个元素,它本身又包含另一个页面对象,所以搜索到框架,我们就必须递归寻找最内层的元素,这样才能找到最终的元素。实际上,用这种方法,不但能做一个网页密码查看器,还能做一个网页Spy++。

   最后说一下如何防范星号查看器程序。对设计者而言,最简单的方法是做一个假的密码框,也就是用一个普通的编辑框代替密码框,里面直接输入*字符,不放密码,只为显示密码长度用。还有种方法是Hook掉WM_GETTEXT,让其它进程无法获取自己的文本。按照上面的方法,我共制作了五个版本的星号查看器程序,还差最后一个没研究出来,就是暴力读内存强制获取密码,但不同的程序需要完全不同的方法,所以只研究了记事本程序(notepad),发现notepad程序的Edit控件文本地址一直位于Edit窗口字节值+0x4F0处(WinXP/SP3下文本偏移始终为0xAABE8),直接读取该地址处的值就是文本框的内容。

 

以下是5个版本的核心代码:

'http://zzmzzff.blog.163.com

'版本1 跟踪焦点获取密码

Public Function m_ReadPwd() As String

   Dim hWndSrc     As Long

   Dim hEdit       As Long

   Dim ThreadId    As Long

   Dim nLength     As Long

   Dim ProcessId   As Long

   Dim CurTID      As Long

  

   hWndSrc = GetForegroundWindow()

   If hWndSrc = 0 Then Exit Function

  

   CurTID = GetCurrentThreadId()

   ThreadId = GetWindowThreadProcessId(hWndSrc, ByVal 0)

   If CurTID = ThreadId Then m_ReadPwd = Chr(0): Exit Function

  

   attachThreadInput CurTID, ThreadId, True

   hEdit = GetFocus()

   If hEdit <> 0 Then

   Dim nChar       As Long

   Dim szText      As String

              If GetWindowLong(hEdit, GWL_STYLE) And ES_PASSWORD Then '是密码框

           nChar = Sendmessage(hEdit, EM_GETPASSWORDCHAR, 0, ByVal 0&)

           If nChar <> 0 Then

                   postmessage hEdit, EM_SETPASSWORDCHAR, 0, 0

                   Sleep 10

                   nLength = SendMessage(hEdit, WM_GETTEXTLENGTH, 0, ByVal 0&)

                   If nLength > 0 Then

                           szText = String(nLength + 1, Chr(0))

                           Call SendMessage(hEdit, WM_GETTEXT, nLength + 1, ByVal szText)

                           szText = Left(szText, InStr(szText, Chr(0)) - 1)

                   End If

                   PostMessage hEdit, EM_SETPASSWORDCHAR, nChar, 0

           End If

   End If

   End If

   AttachThreadInput CurTID, ThreadId, False

   m_ReadPwd = szText

End Function

'版本2 自动获取

'搜索密码

Public Function m_SearchPwd(optional ByVal bForceSearch As Boolean = True) As String

   Dim hWndSrc     As Long

   Dim ThreadId    As Long

   Dim nLength     As Long

   Dim CurTID      As Long

   Dim pt          As POINTAPI

      

   GetCursorPos pt

   hWndSrc = WindowFromPoint(pt.x, pt.y) '获取鼠标所在窗口

  

   '检查窗口,以获取深层/透明/无效窗口,有些控件Z序和尺寸不谐调,默认只能获取上层控件,例如WinRAR的密码窗口,此法可获取任意窗口

   If bForceSearch Then m_CheckWnd hWndSrc, pt.x, pt.y

   If hWndSrc = 0 Then Exit Function

  

   CurTID = GetCurrentThreadId()

   ThreadId = GetWindowThreadProcessId(hWndSrc, ByVal 0)

   If CurTID = ThreadId Then m_SearchPwd = Chr(0): Exit Function '如果是自己退出

  

   nLength = SendMessage(hWndSrc, WM_GETTEXTLENGTH, 0, ByVal 0&) '长度

   If nLength <= 0 Then Exit Function

  

   Dim nChar       As Long

   Dim szText      As String

   szText = String(nLength + 1, Chr(0))

   If GetWindowLong(hWndSrc, GWL_STYLE) And ES_PASSWORD Then

   nChar = SendMessage(hWndSrc, EM_GETPASSWORDCHAR, 0, ByVal 0&) '是否密码框

   If nChar <> 0 Then

           PostMessage hWndSrc, EM_SETPASSWORDCHAR, 0, 0

           Sleep 10

   End If

       End If

   '这次取所有窗口文本

   Call SendMessage(hWndSrc, WM_GETTEXT, nLength + 1, ByVal szText)

   If nChar <> 0 Then PostMessage hWndSrc, EM_SETPASSWORDCHAR, nChar, 0

   szText = Left(szText, InStr(szText, Chr(0)) - 1)

   m_SearchPwd = szText

End Function

'检查窗口

Sub m_CheckWnd(ByRef hWinCheck As Long, x As Long, y As Long, Optional bSearchhidden As Boolean, Optional bSearchThrough As Boolean)

   Dim hWin                As Long

   Dim hWinParent          As Long

   Dim hWinChild           As Long

   Dim lpRectChild         As RECT

   Dim lpRectWin           As RECT

  

   '是否搜索透明窗口,以获取最上层窗口 //这个可以省略,一般用不上,要达到完美的话添上

   If bSearchThrough Then

   CheckTransparentWin hWinCheck, x, y

   End If

  

   '检查子窗口,以便获取灰色窗口

   hWin = hWinCheck

   CheckSubWin hWin, x, y

  

   '获取最深兄弟窗口,如果是控件再进行更深层次搜索

   If IsHaveCaption(hWin) = False Then

   hWinParent = GetAncestor(hWin, GA_PARENT)

   'Debug.print "hWinParent=", hWinParent

   If hWinParent = GetDesktopWindow() Then

           hWinParent = hWin

   End If

   GetWindowRect hWin, lpRectWin

   hWinChild = GetWindow(hWinParent, GW_CHILD)

   Do while hWinChild <> 0

           If hWinChild <> hWin Then

                   '是否搜索隐藏窗口 //注意,此处不能用IsWindowVisible,父窗隐藏后将无法知道子窗的显示状态

                   If Not bSearchHidden Imp (GetWindowLong(hWinChild, GWL_STYLE) And WS_VISIBLE) <> 0 Then

                           GetWindowRect hWinChild, lpRectChild

                                  If PtInRect(lpRectChild, x, y) Then

                                   If PtInRect(lpRectWin, lpRectChild.Left, lpRectChild.Top) <> 0 And _

                                           PtInRect(lpRectWin, lpRectChild.Right, lpRectChild.Bottom) <> 0 Then

                                           hWin = hWinChild

                                           'Debug.Print "目标窗口=", hWin

                                           Exit Do

                                   End If

                           End If

                   End If

           End If

                   hWinChild = GetWindow(hWinChild, GW_HWNDNEXT)

   Loop

   End If

  

   If hWin <> hWinCheck Then

   hWinCheck = hWin

   m_CheckWnd hWinCheck, x, y '递归

   End If

End Sub

'检查子窗口

Private Sub CheckSubWin(hWin As Long, x As Long, y As Long, Optional bSearchHidden As Boolean)

   Dim hChild      As Long

   Dim lpRect      As RECT

   hChild = GetWindow(hWin, GW_CHILD)

   Do While hChild <> 0

   If Not bSearchHidden Imp (GetWindowLong(hChild, GWL_STYLE) And WS_VISIBLE) <> 0 Then

           GetWindowRect hChild, lpRect

           If PtInRect(lpRect, x, y) Then

                   hWin = hChild

                   Exit Do

           End If

   End If

   hChild = GetWindow(hChild, GW_HWNDNEXT)

   Loop

End Sub

'检查穿透窗口

Private Sub CheckTransparentWin(hWin As Long, x As Long, y As Long)

   Dim hTop        As Long

   Dim lpRect      As RECT

   hTop = GetAncestor(hWin, GA_ROOT)

   hTop = GetWindow(hTop, GW_HWNDPREV)

   Do While hTop <> 0

   If IsWindowVisible(hTop) <> 0 Then

           GetWindowRect hTop, lpRect

          If PtInRect(lpRect, x, y) Then

                   hWin = hTop

                   CheckTransparentWin hWin, x, y

           End If

   End If

   hTop = GetWindow(hTop, GW_HWNDPREV)

      Loop

End Sub

'有标题栏

Private Function IsHaveCaption(ByVal hWin As Long) As Boolean

   IsHaveCaption = ((GetWindowLong(hWin, GWL_STYLE) And WS_CAPTION) = WS_CAPTION)

End Function

'版本3  //一次性获取

'获取所有密码

Public Function m_EnumPwd(Optional ByVal bShowPwd As Boolean) As String

   Dim hWndSrc     As Long

   Dim nLength     As Long

   Dim szText      As String

   Dim szTilte     As String

   Dim szPwd       As String

  

   hWndSrc = FindWindow(vbNullString, vbNullString)

   Do While hWndSrc <> 0

   szPwd = ""

   m_GetText hWndSrc, szPwd, bShowPwd

   If Not bShowPwd Then

           If szPwd <> "" Then

                   nLength = GetWindowTextLength(hWndSrc)

                   If nLength > 0 Then

                           If nLength > 255 Then nLength = 255 '取窗口标题,只取前255个

                           szTilte = String(nLength + 1, Chr(0))

                           Call GetWindowText(hWndSrc, szTilte, nLength + 1)

                           szTilte = Left(szTilte, InStr(szTilte, Chr(0)) - 1)

                   End If

                   szText = szText & "窗口 " & szTilte & " 的密码:" & vbCrLf & szPwd & vbCrLf

           End If

   End If

   hWndSrc = GetWindow(hWndSrc, GW_HWNDNEXT)

   Loop

   m_EnumPwd = szText

End Function

Sub m_GetText(ByVal hWndSrc As Long, szPwd As String, Optional bShowPwd As Boolean)

   Dim nLength     As Long

   Dim nChar       As Long

   Dim szText      As String

  

   hWndSrc = GetWindow(hWndSrc, GW_CHILD)

   Do While hWndSrc <> 0

   If GetWindowLong(hWndSrc, GWL_STYLE) And ES_PASSWORD Then

           If SendMessageTimeout(hWndSrc, WM_NULL, 0, 0, SMTO_ABORTIFHUNG Or SMTO_BLOCK, 500, ByVal 0&) <> 0 Then

                   nChar = SendMessage(hWndSrc, EM_GETPASSWORDCHAR, 0, ByVal 0&)

                   If nChar <> 0 Then '是密码框

                           If Not bShowPwd Then

                                   nLength = SendMessage(hWndSrc, WM_GETTEXTLENGTH, 0, ByVal 0&) '长度

                                   szText = ""

                                   If nLength > 0 Then

                                           szText = String(nLength + 1, Chr(0))

                                           PostMessage hWndSrc, EM_SETPASSWORDCHAR, 0, 0

                                           Sleep 10

                                           Call SendMessage(hWndSrc, WM_GETTEXT, nLength + 1, ByVal szText)

                                           PostMessage hWndSrc, EM_SETPASSWORDCHAR, nChar, 0

                                           szText = Left(szText, InStr(szText, Chr(0)) - 1)

                                   End If

                                   szPwd = szPwd & "密码: " & szText & vbCrLf

                           Else

                                   PostMessage hWndSrc, EM_SETPASSWORDCHAR, 0, 0

                                   PostMessage hWndSrc, WM_SIZE, 0, 0

                           End If

                   End If

           End If

   End If

   m_GetText hWndSrc, szPwd, bShowPwd '递归

   hWndSrc = GetWindow(hWndSrc, GW_HWNDNEXT)

   Loop

End Sub

'版本4 //获取网页密码

'获取所有密码 mod_Main

Public Function m_EnumWebPwd() As String

   Dim hWndSrc     As Long

   Dim hWndIESer   As Long

   Dim nLength     As Long

   Dim szText      As String

   Dim szTilte     As String

   Dim ProcessId   As Long

  

   hWndSrc = FindWindow(vbNullString, vbNullString)

   Do While hWndSrc <> 0

   szPwd = ""

   EnumSubWnd hWndSrc

   If szPwd <> "" Then

           GetWindowThreadProcessId hWndSrc, ProcessId

           nLength = GetWindowTextLength(hWndSrc)

           If nLength > 0 Then

                   If nLength > 255 Then nLength = 255 '取窗口标题,只取前255个

                   szTilte = String(nLength + 1, Chr(0))

                   Call GetWindowText(hWndSrc, szTilte, nLength + 1)

                   szTilte = Left(szTilte, InStr(szTilte, Chr(0)) - 1)

               End If

           szText = szText & "句柄: " & hWndSrc & " 进程: " & ProcessId & " 网页标题: " & szTilte & vbCrLf & "密码: " & szPwd & vbCrLf

   End If

   hWndSrc = GetWindow(hWndSrc, GW_HWNDNEXT)

   Loop

      m_EnumWebPwd = szText

End Function

Private Function EnumSubWnd(ByVal hWin As Long) As Long

   EnumChildWindows hWin, AddressOf EnumWinCallback, ByVal 0

End Function

Public Function EnumWinCallback(ByVal MyhWnd As Long, lParam As Long) As Long

   If IsIEServerHwnd(MyhWnd) Then

   m_ReadWebPwd MyhWnd, szPwd

   End If

   EnumWinCallback = 1

End Function

'IEServer窗口

Private Function IsIEServerHwnd(ByVal hWin As Long) As Boolean

   IsIEServerHwnd = GetWinClass(hWin) = "Internet Explorer_Server"

End Function

'mod_Html

'获取密码

Public Function m_ReadWebPwd(ByVal hWin As Long, szText As String)

   'On ERROR Resume Next

   Dim Doc         As IHTMLDocument

  

   Set Doc = IEDOMFromhWnd(hWin)

  

      Call GetPwdByDocument(Doc, szText)

End Function

Sub GetPwdByDocument(ByVal Doc As IHTMLDocument, szText As String)

   On Error Resume Next

   If Doc Is Nothing Then Exit Sub

   Dim SubDoc      As IHTMLDocument

   Dim Ele         As IHTMLElement

   Dim EleFra      As IHTMLIFrameElement3

   Dim szPwd       As String

   For Each Ele In Doc.All

   If Ele.tagName = "IFRAME" Then '如果是框架,继续递归获取下一级页面

           Set EleFra = Ele

           Set SubDoc = EleFra.contentDocument

           GetPwdByDocument SubDoc, szText

   Else

           If Ele.getAttribute("type") = "password" Then

                   szPwd = CStr(Ele.getAttribute("value"))

                   If szPwd = "" Then szPwd = Ele.innertext

                   szText = szText & szPwd & vbCrLf

           End If

   End If

   Next

End Sub

'版本5 //自动获取网页密码

'搜索密码

Public Function m_SearchPwd() As String

   Dim hWndSrc     As Long

   Dim pt          As POINTAPI

   GetCursorPos pt

   hWndSrc = WindowFromPoint(pt.x, pt.y) '获取鼠标所在窗口

   If IsIEServerHwnd(hWndSrc) Then

   screentoclient hWndSrc, pt

   m_SearchPwd = m_GetWebPwd(hWndSrc, pt.x, pt.y)

   End If

End Function

'获取密码

Public Function m_GetWebPwd(ByVal hWin As Long, x As Long, y As Long) As String

   'On Error Resume Next

   Dim Doc         As IHTMLDocument

   Dim szText      As String

  

   Set Doc = IEDOMFromhWnd(hWin)

  

   Call GetPwdByPoint(Doc, x, y, szText)

   m_GetWebPwd = szText

End Function

Private Sub GetPwdByPoint(ByVal Doc As IHTMLDocument2, ByVal x As Long, ByVal y As Long, szText As String)

   On Error Resume Next

   If Doc Is Nothing Then Exit Sub

   Dim SubDoc      As IHTMLDocument

   Dim Ele         As IHTMLElement

   Dim EleIFrame   As IHTMLIFrameElement3

   Dim rt          As Object

       

   Set Ele = Doc.elementFromPoint(x, y)

   If Not (Ele Is Nothing) Then

   Debug.Print Ele.offsetleft, Ele.offsettop

   If Ele.tagName = "IFRAME" Then '如果是框架,继续递归获取下一级页面

           Set EleIFrame = Ele

           Set SubDoc = EleIFrame.contentDocument

           Set rt = Ele.getBoundingClientRect

           x = x - rt.Left

           y = y - rt.Top

           GetPwdByPoint SubDoc, x, y, szText

   Else

           'Debug.Print x, y, Ele.offsetLeft, Ele.offsetTop

           If Not IsNull(Ele.getAttribute("value")) Then

                   szText = Ele.getAttribute("value")

           Else

                   szText = Ele.innerText

           End If

   End If

   End If

End Sub

'***************** 核心代码结束 ************************

完整代码:http://pan.baidu.com/s/1hsFOAfa

相关阅读

如何开网店,星密码破解2016年开淘宝网店详细流程与步骤

如何开网店,怎么开淘宝网店?距离2016年还剩不到10天时间了,想要在新的一年完成互联网创业梦想吗,那么就赶紧加入到开网店的队伍中吧

“暴力”破解 Linux密码

1.首先我们需要一个“字典”,换而言之,就是密码库,可以用来破解Linux用户的密码 2.接下来,我用一个脚本来给大家简单的写一下 #!/usr/

财付通支付密码忘记了该怎么办

财付通是一个支付平台,是由腾讯推出的,它的核心业务就是帮助在互联网上进行金额交易的双方完成收款和支付,提供一个安全、快捷。方便

万能密码

1.第四届山东理工大学计算机网络与信息安全竞赛 Web——网站后台用户名:uname=1") Or 1 – -密码随便填2.SDUTSec WEB——万能

h3c路由器修改ssh登录密码

1.local-user 用户名(admin)2. password simple/cipher 密码(admin)         (其中cipher是密文,simple是明文) 3.qu  4.save

分享到:

栏目导航

推荐阅读

热门阅读