|
|||||
<このサンプルの概要> 以前自分で入力したパスワードを忘れてしまい困った事が無いでしょうか? パスワードの設定画面を見てもパスワードがアスタリスク(***)に変換されて表示されるため 確認出来ません。そんな時に役立つのが「パスワードを見るツール」ですが、 ブラウザ以外のウィンドウで表示されているパスワードは意外に簡単に表示する事が出来ます。 このサンプルはその「パスワードを見るサンプル」です。 パスワード表示ツール(SeePasswd)はこのサンプルを元にブラウザ(IE)のパスワードを表示出来る ようにしたツールです。パスワードが見れた後はパスワードをデータベースに登録して管理 したくなると思うので、パスワード管理ツールと連携する機能があります。 具体的にはPasswordChar(*)が設定されたTextBoxから実際のパスワードを取得し表示します。 このサンプルのポイントとなるキーワードは以下の通りです。 (1)PostMessage (2)SendMessage (3)EM_GETPASSWORDCHAR (4)EM_SETPASSWORDCHAR このサンプルには含まれていませんが、IEのパスワードを調べる方法の概略は以下の通りです。 (1)ブラウザ(IE)のクラス名[Internet Explorer_Server]を探す。 (2)[WM_HTML_GETOBJECT]メッセージを[Internet Explorer_Server]に送る。 (3)[IID_IHTMLDocument]オブジェクトを取得する。 (4)[IID_IHTMLDocument]オブジェクトの[getElementsByTagName]で全てのタグを取得する。 (5)[INPUT]タグの[TYPE]が[password]のものからパスワードを取得する。 ただし(4)、(5)の処理を全てのフレームに対し実行する必要があります。 IEのパスワードを表示するツールの中にはフレーム未対応のものがあり、 そのツールでは表示出来無いパスワードがありました。 ※転載等色々禁止させてください。 ※個人利用の参考としてのみご覧ください。 ※決して悪用はしないでください。 ★標準モジュール(Module1.vb) Module Module1 ' APIの定義 Private Const WM_GETTEXT = &HD Private Const EM_GETPASSWORDCHAR = &HD2 Private Const EM_SETPASSWORDCHAR = &HCC Private Delegate Function D_EnumWindowsProc *** As Integer Private Delegate Function D_EnumChildWindowsProc *** As Integer Private Declare Function EnumWindows Lib "user32.dll" _ (ByVal lpEnumFunc As D_EnumWindowsProc, ByVal lParam As Integer) As Integer Private Declare Function EnumChildWindows Lib "user32.dll" _ (ByVal hwndParent As Integer, ByVal lpEnumFunc As D_EnumChildWindowsProc, _ ByVal lParam As Integer) As Integer Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _ ByVal lParam As Byte()) As Integer Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" _ (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _ ByVal lParam As Byte()) As Integer ' パスワードを取得するコレクション Private colPasswd As New Collection ' 表示中の全てのパスワードを取得 Public Function GetAllPasswd() As Collection Try ' パスワードを取得するコレクション初期化 colPasswd.Clear() ' トップレベルウィンドウの全てハンドル取得して、そこに属するパスワードを全て取得 Dim intRet As Integer = EnumWindows(AddressOf EnumWindowsProc, 0) Catch ex As Exception End Try ' リターン Return colPasswd End Function ' トップレベルウィンドウの全てハンドル取得して、そこに属するパスワードを全て取得 Public Function EnumWindowsProc( _ ByVal hWnd As Integer, ByVal lParam As Integer) As Integer Try ' 指定された親ウィンドウに属するパスワードを全て取得 Dim intRet As Integer = EnumChildWindows(hWnd, AddressOf EnumChildWindowsProc, 0) Catch ex As Exception End Try ' リターン Return 1 End Function ' 指定された親ウィンドウに属するパスワードを全て取得 Private Function EnumChildWindowsProc( _ ByVal hWnd As Integer, ByVal lParam As Integer) As Integer Try Dim bytPasswd As Byte() = New Byte(255) {} Dim strPasswd As String = "" Dim intRet As Integer ' パスワード文字が設定されているかチェック Dim pch As Integer = SendMessage(hWnd, EM_GETPASSWORDCHAR, 0, Nothing) If pch <> 0 Then ' パスワード文字を無効 For i As Integer = 0 To 10 PostMessage(hWnd, EM_SETPASSWORDCHAR, 0, Nothing) Application.DoEvents() If SendMessage(hWnd, EM_GETPASSWORDCHAR, 0, Nothing) = 0 Then Exit For System.Threading.Thread.Sleep(100) Next ' パスワード文字列取得 intRet = SendMessage(hWnd, WM_GETTEXT, 255, bytPasswd) strPasswd = StripNulls(bytPasswd) ' パスワード文字を有効 For i As Integer = 0 To 10 PostMessage(hWnd, EM_SETPASSWORDCHAR, pch, Nothing) Application.DoEvents() If SendMessage(hWnd, EM_GETPASSWORDCHAR, 0, Nothing) = pch Then Exit For System.Threading.Thread.Sleep(100) Next ' パスワードを取得するコレクションにパスワードを追加 If strPasswd <> "" Then colPasswd.Add(strPasswd) End If End If Catch ex As Exception End Try ' リターン Return 1 End Function ' 文字列からNULL文字以降をカット Private Function StripNulls(ByVal bytOrg As Byte()) As String Dim strOrg As String = "" Try strOrg = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(bytOrg) Dim pt As Integer = strOrg.IndexOf(Chr(0)) If pt >= 0 Then strOrg = strOrg.Substring(0, pt) End If Catch ex As Exception End Try Return strOrg End Function End Module ★フォームモジュール(Form1.vb) Public Class Form1 Private Sub Button1_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click ' 表示中の全てのパスワードを取得 Dim colPasswd As Collection colPasswd = GetAllPasswd() ' パスワード有無チェック If colPasswd.Count <= 0 Then MessageBox.Show("パスワードはありませんでした。") Return End If ' パスワード毎のコレクションループ For i As Integer = 1 To colPasswd.Count ' パスワードの表示 MessageBox.Show(colPasswd.Item(i)) Next i End Sub End Class |