当前位置: 首页 > article >正文

DLL注入之消息钩子

1、函数准备

  通过查阅资料可知,实现消息钩子的核心函数是SetWindowsHookEx() ,通过查阅官方文档,可知:

HHOOK SetWindowsHookExA(

  [in] int       idHook,  //要安装的挂钩过程的类型

[in] HOOKPROC  lpfn,  //指向挂钩过程的指针

[in] HINSTANCE hmod,  //包含 lpfn 参数指向的挂钩过程的 DLL 的句柄

  [in] DWORD     dwThreadId //要与挂钩过程关联的线程的标识符

);

具体如下:

idHook有许多取值,可以看到2是我需要的:

剩下3个参数的解释:

根据上图红框内的提示可知,还有一个核心的函数:

LRESULT CALLBACK KeyboardProc(

  _In_ int    code,     //决定hook如何处理消息,可取0、3

  _In_ WPARAM wParam,    //击键对应系统中的虚拟代码,如Tab键对应0x09

  _In_ LPARAM lParam     //击键消息的标志位们

);

IParam:

我们想要在击键松开的时候拦截消息,所以IParam对应的值为0x80000000。

根据官方文档,安装钩子需要两个必要的部分:一个安装钩子的程序和一个全局钩子处理DLL。

2、编写DLL

DLL部分实现hook到消息之后,如何对消息进行处理。

DLL可以定义两类函数,导出函数和内部函数。导出函数可以被其他模块调用,也可以在定义它们的DLL中调用,而内部函数只能在定义它们的DLL中调用。

通过官方的example,可以看到对键盘进行拦截,核心就是实现KeyboardProc()函数:

在VS2022中新建一个DLL项目名为HookKeyBoard,在属性中c/c++->预编译中选择不使用编译头。在DLLMAIN.cpp中写入如下代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include<stdio.h>
#include<windows.h>#define HOOK_PROCESS_NAME "notepad.exe"HINSTANCE hInstance = NULL;
HHOOK hHook = NULL;
HWND hWnd = NULL;BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID IpvReserved)//DLL入口
{switch (dwReason){case DLL_PROCESS_ATTACH:hInstance = hinstDLL;break;case DLL_PROCESS_DETACH:break;}return TRUE;
}extern "C" __declspec(dllexport) LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{char szPath[MAX_PATH] = { 0, };CHAR* p = NULL;if (!(lParam & 0x80000000))//释放按键时{GetModuleFileNameA(NULL, szPath, MAX_PATH );//获取当前可执行程序或DLL的路径p = strrchr(szPath, '\\');//比较进程名称是否为记事本if (!_stricmp(p + 1, "notepad.exe")){return 1;}}//不是记事本则传递给下一个hookreturn CallNextHookEx(hHook, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) void HookStart()
{hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
}extern "C" __declspec(dllexport) void HookStop()
{if (hHook){UnhookWindowsHookEx(hHook);hHook = NULL;}
}

Hookstart和Hookstop不是必须的,这里只是做了封装,直接给应用程序提供调用接口。

生成解决方案后,可在如下位置找到.dll文件:

3、编写安装程序

安装应用程序必须具有 DLL 模块的句柄,然后才能安装挂钩。要检索 DLL 模块的句柄,需使用 DLL 的名称调用 LoadLibrary函数。获取句柄后,可以调用 GetProcAddress 函数来检索指向挂钩过程的指针。最后,使用 SetWindowsHookEx 将挂钩过程地址安装在相应的挂钩链中。SetWindowsHookEx 传递模块句柄、指向挂钩过程入口点的指针和线程标识符的 0,指示挂钩过程应与调用线程位于同一桌面中的所有线程相关联。

官方示例如下:

  

   新建一个控制台项目,我编写的程序如下:

//#include<stdio.h>
//#include<conio.h>
//#include<windows.h>
//
//HHOOK hHook = NULL;
//HINSTANCE hInstance = NULL;
//
//int main()
//{
//    HMODULE hDll = NULL;
//    char ch = 0;
//
//    //加载dll
//    hDll = LoadLibraryA("HookKeyBoard.dll");
//    if (hDll == NULL) exit(0);
//    //获取导出函数的地址
//
//    FARPROC KeyboardProc = (FARPROC)GetProcAddress(hDll, "KeyboardProc");
//
//    //开始hook
//    hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, hInstance, 0);
//
//    //输入Q退出hook
//    printf("输入q退出hook!\n");
//    while (1)
//    {
//        char h = _getch();
//        _putch(h);
//        if (h == 'q')
//            break;
//    }
//    //结束hook
//    if (hHook)
//    {
//        UnhookWindowsHookEx(hHook);
//        hHook = NULL;
//    }
//    //卸载dll
//    FreeLibrary(hDll);
//    return 0;
//}
#include<stdio.h>
#include<conio.h>
#include<windows.h>#define HOOK_START "HookStart"
#define HOOK_STOP  "HookStop"typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();int main()
{HMODULE hDll = NULL;PFN_HOOKSTART HookStart = NULL;PFN_HOOKSTOP  HookStop = NULL;char ch = 0;//加载dllhDll = LoadLibraryA("HookKeyBoard.dll");//获取导出函数的地址HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, HOOK_START);HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, HOOK_STOP);//开始hookHookStart();//输入q退出hookprintf("输入q退出hook!\n");while (1){char h = _getch();_putch(h);if (h == 'q')break;}//结束hookHookStop();//卸载dllFreeLibrary(hDll);return 0;
}

  

   将第二步中生成的.dll复制到项目目录下,运行。

4、效果

  可以看到,记事本中无法键入内容

而其他软件成功键入(word不行,推测是调用了记事本?)

  输入q退出,恢复。

http://www.lryc.cn/news/2418839.html

相关文章:

  • ghttp数据结构
  • 分享几个免费的开源邮件服务器软件
  • 白帽子技术分析会话劫持实战讲解
  • 15名程序员界的高富帅+白富美
  • 软件测试项目实战案例分解,跟着我一步一步操作【人力资源管理系统】
  • Red Flag Linux 红旗Linux桌面6.0系列
  • 【VB超简单入门】三、开始编程
  • Android设置透明、半透明等效果
  • 自动刷百度下拉词优化工具
  • c++进制与进制转换
  • OpenCV的视频编解码器的编码格式
  • 用JavaScript在网页右下角弹出窗口
  • C#动态循环生成控件(附源码)
  • 泽西岛Java教程
  • vrml场景实例代码_【免费毕设】JAVA3D的网络三维技术的设计与实现(源代码+论文+说明)...
  • 整人BAT\VBS代码 自创
  • 网络安全初学者必备的60个工具,零基础入门到精通,收藏这一篇就够了
  • FileUpload实现多文件上传与下载
  • 电脑xp系统坏了,如何处理
  • html 设置min height,CSS中min-height使用技巧
  • 教育界常用网站汇总
  • 常用搜索引擎搜索串
  • ISA Server是什么
  • 中移动详解Mobile Market运作流程
  • 计算机毕业设计PHP短视频管理小程序(源码+程序+uni+lw+部署)
  • 《数据库系统概念》——关系数据库
  • Postgresql B-tree索引
  • 【汇编】80x86指令系统
  • python爬取电影天堂的下载链接
  • 推荐几个好用的网站导航