`

[原]简易Windows密码查看器

阅读更多

[标题]:简易Windows密码查看器
[时间]:2009-10-09
[摘要]:通过全局钩子获取当前鼠标处的窗口控件句柄,然后直接调用GetWindowText()获取密码文本。
[关键字]:密码、查看、星号、全局钩子、Hook、WM_COPYDATA、DLL、XP样式
[环境]:Visual Studio 2008、Visual C++ 6.0
[作者]:天堂露珠 (wintys@gmail.com) http://www.blogjava.net/wintys

[正文]:

    此密码查看器原理:通过全局钩子获取当前鼠标处的窗口控件句柄,然后直接调用GetWindowText()获取密码文本。工程在VC++6.0和VS2008中编译通过。

1、查看密码的DLL工程

    因为查看密码功能要用到全局鼠标Hook,所以要把功能放到一个DLL中。

PasswordViewerMouseHookDLL.h:

#pragma once

#ifdef PSWMOUSEHOOKDLL_API_EXPORTS
#define PSWMOUSEHOOKDLL_API __declspec(dllexport)
#else
#define PSWMOUSEHOOKDLL_API __declspec(dllimport)
#endif

/*
Winty:2009-09-29
调用SetHook()设置Hook,但无需卸载Hook,DLLMain中有清理。
*/
//My Declaration================================
#define MAXCOUNT 200 //密码最大长度
#define DWDATA_PSW_NOTIFY 1 //COPYDATASTRUCT的dwData自定义值

//密码信息结构体,用于发送
typedef struct tagPswNotify
{
    char psw[MAXCOUNT];//password/text
    POINT pt;//鼠标位置
    HWND hWnd;//控件句柄
} PSWNOTIFY , *PPSWNOTIFY;

/*extern表示这里只是变量声明,变量定义在cpp文件中*/
extern PSWMOUSEHOOKDLL_API BOOL g_bReadySend;//WM_COPYDATA互斥的标志,因为WM_COPYDATA不能重叠
extern PSWMOUSEHOOKDLL_API HWND g_hWnd; //接收消息的窗体句柄
extern PSWMOUSEHOOKDLL_API HHOOK g_hhk; //钩子句柄
extern PSWMOUSEHOOKDLL_API BOOL g_bView;//是否需要查看密码

//鼠标钩子过程
PSWMOUSEHOOKDLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam );
//设置钩子(可在窗口的OnInitDialog()中调用)
PSWMOUSEHOOKDLL_API void SetHook(HWND hWnd);

PasswordViewerMouseHookDLL.cpp:

#include "stdafx.h"

#define PSWMOUSEHOOKDLL_API_EXPORTS
#include "PasswordViewerMouseHookDLL.h"

#include <stdio.h>

//进程间共享数据,还要在链接器选项里添加:"/SECTION:.MyShare,RWS"
//或: #pragma   comment(linker,"/SECTION:.MyShare,RWS") 
//查看结果:dumpbin /headers *.DLL
#pragma data_seg(".MyShare")
HHOOK g_hhk = NULL;/*Hook句柄*/
HWND  g_hWnd = NULL;/*接收消息的窗口句柄*/
BOOL  g_bReadySend = TRUE;/*用于同步COPYDATA消息*/
#pragma data_seg()
#pragma   comment(linker,"/SECTION:.MyShare,RWS")

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            break;
        case DLL_PROCESS_DETACH:
            if(g_hhk != NULL)
            {
                UnhookWindowsHookEx(g_hhk);
                g_hhk = NULL;
                g_hWnd = NULL;
            }
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;

    }
    return TRUE;
}

LRESULT CALLBACK MouseProc(
                           int nCode,      // hook code
                           WPARAM wParam,  // message identifier
                           LPARAM lParam   // mouse coordinates
)
{
    if(nCode == HC_ACTION)
    {
        PMOUSEHOOKSTRUCT pMouseHookStruct
            = reinterpret_cast<PMOUSEHOOKSTRUCT>(lParam);
        LONG x = pMouseHookStruct->pt.x;
        LONG y = pMouseHookStruct->pt.y;
        HWND hWnd = pMouseHookStruct->hwnd;

        HWND hWndFromPoint = ::WindowFromPoint(pMouseHookStruct->pt);

        if(hWndFromPoint != g_hWnd  &&  g_bReadySend)//不能获取显示密码的文本框的内容
        {
            g_bReadySend = FALSE;
            char psw[MAXCOUNT];
            ::GetWindowText(hWndFromPoint , psw , MAXCOUNT);
            PSWNOTIFY pswNotify;
            strcpy(pswNotify.psw , psw);
            pswNotify.pt.x = x;
            pswNotify.pt.y = y;
            pswNotify.hWnd = hWndFromPoint;

            COPYDATASTRUCT cd;
            cd.lpData = &pswNotify;
            cd.cbData = sizeof(PSWNOTIFY);
            cd.dwData = DWDATA_PSW_NOTIFY;
            ::SendMessage(g_hWnd, WM_COPYDATA, NULL , (LPARAM)(LPVOID)&cd);
        }
    }

    return CallNextHookEx(g_hhk , nCode , wParam ,lParam);
}

void SetHook(HWND hWnd)
{
    g_hWnd = hWnd;
    g_hhk = SetWindowsHookEx(WH_MOUSE ,
                             MouseProc ,
                             GetModuleHandle("PasswordViewerMouseHookDLL") ,
                             NULL);
}

 

    DLL要想将密码消息发送到主窗口显示,要用WM_COPYDATA消息(或其它进程间通信方式),否则会发送失败。如果用WM_SETTEXT,因为全局Hook发送的消息所带的字符串指针lParam可能不能被主窗口访问,从而造成访问异常。

    g_bReadySend的设置是因为WM_COPYDATA消息不能连续发送,必须等前一条消息取走之后才能发送下一条消息。

2、显示密码的工程PasswordViewer

    创建一个对话框工程PasswordViewer。

使用DLL步骤:

  • 把PasswordViewerMouseHookDLL工程生成的PasswordViewerMouseHookDLL.dll、PasswordViewerMouseHookDLL.lib,以及PasswordViewerMouseHookDLL.h复制到PasswordViewer工程。
    [参考资料]:
    [附件]:
  • 在PasswordViewerDlg.cpp 中加入#include "PasswordViewerMouseHookDLL.h"和#pragma comment(lib , "PasswordViewerMouseHookDLL.lib")

    如果要设置最后生成XP样式的窗口,得在PasswordViewerDlg.cpp 中加入

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")

 

 

    PasswordViewerDlg.cpp主要代码为响应WM_COPYDATA消息,把消息内容显示到窗口上:

BOOL CPasswordViewerDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    if(pCopyDataStruct->dwData == DWDATA_PSW_NOTIFY && !g_bReadySend)
    {
        PPSWNOTIFY pPswNotify = (PPSWNOTIFY)pCopyDataStruct->lpData;

        CString strMousePosition;
        strMousePosition.Format("(%3d,%3d)" , pPswNotify->pt.x ,pPswNotify->pt.y);
        m_strMousePosition = strMousePosition;
        CString strPsw;
        strPsw.Format("%s" , pPswNotify->psw);
        m_strPsw = strPsw;
        CString strHWnd;
        strHWnd.Format("%p" , pPswNotify->hWnd);
        m_strHWnd = strHWnd;
        UpdateData(FALSE);

        g_bReadySend = TRUE;

        return TRUE;
    }
    else
    {
        CString str(_T("未发现窗口"));
        m_strPsw = str;

        UpdateData(FALSE);

        return CDialog::OnCopyData(pWnd, pCopyDataStruct);
    }   
}

 

    别忘了要在CPasswordViewerDlg::OnInitDialog()中调用DLL的SetHook(m_hWnd),初始化全局钩子。

3、运行

    运行结果如图:

cpp_PasswordViewer

【cpp_PasswordViewer.jpg】

[附件]:

PasswordViewer.exe、PasswordViewerMouseHookDLL.dll、工程源代码

原创作品,转载请注明出处。
作者:Winty (wintys@gmail.com)
博客:http://www.blogjava.net/wintys
分享到:
评论

相关推荐

    WinRAR V3.90 beta 1 简体中文版.exe

    在 WinRAR 查看器中的“以 Windows 文本方式查看”快捷键从 Ctrl W 变为 Ctrl I. 9. 新的命令行开关 -r- 可以完全禁用递归. 因此“rar a -r- arc 目录名称”命令将仅添加空目录名称文件夹并且忽略它的内容. 缺省...

    远程会议+远程协助 Mikogo

    4.连接建立后,与会者可以通过Mikogo的查看器实时查看发起人的屏幕。 关于Mikogo Mikogo是一个整合创新的桌面共享新科技,提供用户更简易使用的免费网络会议解决方案,让用户拥有更高品质的实时在线协作。Mikogo...

    cmd操作命令和linux命令大全收集

    94. Clipbrd--------剪贴板查看器 95. conf-----------启动netmeeting 96. certmgr.msc----证书管理实用程序 操作详解 net use ipipc$ " " /user:" " 建立IPC空链接 net use ipipc$ "密码" /user:"用户名" 建立...

    迷你版SQL2000服务器

    Windows OS(vista/win7/win8/xp/2000/2003) 不支持Windows 9x 软件功能: 1、MSSQL2000数据库服务开启、关闭控制; 2、基本数据库操作(改密码、数据库新建、删除、分离、附加、备份、恢复); 3、日志和连接...

    实用小工具超级工具箱

    2007/11/16 09:15 280,576 WINDOWS蓝屏代码查询器.EXE 2006/02/03 09:08 398,336 中天专用万能翻译器.exe 2007/11/08 15:54 1,314,438 光盘刻录.exe 2007/07/09 15:46 2,184,488 光盘测试工具.exe 2004/12/22 09:09 ...

    SupChat:一个使用ionic和Firebase的简单聊天应用程序

    "SupChat"是一款基于Ionic框架和Firebase实时数据库构建的简易聊天应用程序。这个项目展示了如何将这两项技术结合,创建一个跨平台的移动应用,让用户能够实现实时的文本消息交流。 1. **Ionic框架**:Ionic是开源...

    JAVA上百实例源码以及开源项目源代码

    Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码,文件操作,压缩包查看 Java zip压缩包查看程序,应用弹出文件选择框,选择ZIP格式的压缩文件,可以像Winrar软件一样查看压缩文件内部的文件及文件夹,源码...

    grub4dos-V0.4.6a-2017-02-04更新

    同时屏蔽驱动器号 0x80(避免通过 BIOS 读 u 盘,有可能死机)。 这一更改也避免了 Issue 162 读 64 位逻辑扇区的问题。 FDD 模式的 u 盘被识别为硬盘,问题多多。已经发现的问题是执行 find,不返回 (hd0);...

Global site tag (gtag.js) - Google Analytics