参考博客

一、SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx(
__in int idHook, \\钩子类型
__in HOOKPROC lpfn, \\回调函数地址
__in HINSTANCE hMod, \\实例句柄
__in DWORD dwThreadId); \\线程ID

这里使用的钩子类型idHook 是WH_MOUSE_LL。

在使用SetWindowsHook截获鼠标事件时,如果使用WH_MOUSE参数,则只能监控钩子所在模块的鼠标事件。

如需要截获整个系统的鼠标事件,那么使用WH_MOUSE_LL参数。

二、自定义消息通信

这里和参考的一样,将其写成MFC DLL然后使用导出函数。

通过发送消息SendMessage的方式,让dll和主程序进行通信(SendMessage 同步),

这里要注意使用的是自定义消息的方式来进行通信,就像IPC中的自定义消息一样,.dll与MFC中的消息定义必须完全一样:

 //自定义消息,用于处理dll发来的消息
//该消息的定义和dll中定义的消息必须一样
#define WM_MOUSEMESSAGE WM_USER + 100

DLL部分代码:

.dll中

 // 安装低级鼠标子函数,截获系统所有的鼠标消息
BOOL WINAPI StartHookMouse(HWND hwnd)
{
//这里自身的窗口句柄传过来 __hWnd = hwnd; /*
在使用SetWindowsHook截获鼠标事件时,如果使用WH_MOUSE参数,则只能监控钩子所在模块的鼠标事件。
如需要截获整个系统的鼠标事件,那么使用WH_MOUSE_LL参数。 */
__hhkMouse = SetWindowsHookEx(
WH_MOUSE_LL,
LowLevelMouseProc,
__hInstance, ); if (NULL == __hhkMouse)
{
return FALSE;
}
else
{
return TRUE;
} }
 // 定义低级鼠标子函数
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// 有鼠标消息时,将其发给主程序 if (__hWnd != NULL && nCode == HC_ACTION)//HC_ACTION 有鼠标信息
{
//通知MFC
::SendMessage(__hWnd, WM_MOUSEMESSAGE, wParam, lParam);
} return CallNextHookEx(__hhkMouse, nCode, wParam, lParam); }

然后,主程序收到该消息后,将其显示在程序界面上。

这边为了给主程序发送消息,在主程序调用安装鼠标钩子的函数时,我们需要将主窗口的句柄通过参数传递到dll中,这样我们就可以发送消息给主程序了。

三、共享代码段,所有线程共享

如果一个程序运行了两个实例,很遗憾,这两个程序的代码并不会共享,因为程序代码在程序运行时就被装载到内存,第二个程序再启动时,系统没法判断也不会判断这个程序是否还是原来的程序(如果程序被更新或更改),所以仍然会把程序代码重新加载到内存的另一块区域。

代码的共享体现应该是链接库中,特别是动态链接库中。因为库被设计成动态链接的,所以程序可以在运行后再确定代码所在的内存地址,这也就能实现多个程序调用同一块代码了。

 // 共享代码段,所有线程共享
#pragma data_seg("SHARED")
static HHOOK __hhkMouse = NULL; // 鼠标钩子句柄
static HINSTANCE __hInstance = NULL; // 本DLL的实例句柄
static HWND __hWnd = NULL; // 调用DLL的主窗口句柄
#pragma data_seg()
#pragma comment(linker,"/section:SHARED,rws")

四、卸载hook

// 卸载低级鼠标钩子
VOID WINAPI StopHookMouse()
{
if (__hhkMouse != NULL)
{
::UnhookWindowsHookEx(__hhkMouse);
}
}

/***********************************/

五、MFC中的自定义消息

首先必须得和dll中的完全一样,定义一个自定义消息,必须完全一样

(这里可以参考博客http://www.cnblogs.com/hcxblog/archive/2012/10/02/2710261.html)

然后要写自定义消息的三句话:

1.消息映射

2.消息处理函数的声明

3.消息处理函数的实现

    ON_MESSAGE(WM_MOUSEMESSAGE, &CLowLevelHookMouseDlg::OnMouseMessage) //消息映射

    afx_msg LRESULT OnMouseMessage(WPARAM wParam, LPARAM lParam);

LRESULT CLowLevelHookMouseDlg::OnMouseMessage(
WPARAM wParam, LPARAM lParam)

----------------------------------------------------------------------------------------

使用函数:

 HINSTANCE __hInstanceDll = NULL;

 typedef BOOL (CALLBACK *StartHookMouse)(HWND hwnd);
typedef VOID (CALLBACK *StopHookMouse)();
 //启动鼠标钩子
void CLowLevelHookMouseDlg::OnBnClickedButtonStarthook()
{
// TODO: 在此添加控件通知处理程序代码
__hInstanceDll = LoadLibrary(_T("HookDll.dll"));
if (__hInstanceDll == NULL)
{
::MessageBox(NULL,(LPCTSTR)GetLastError(),L"LoadLibrary() Error",);
return;
} StartHookMouse StartHook;
StartHook = (StartHookMouse)::GetProcAddress(
__hInstanceDll, "StartHookMouse");
if (StartHook == NULL)
{
::MessageBox(NULL, (LPCTSTR)GetLastError(), L"GetProcAddress() Error", );
} if (StartHook(this->m_hWnd))
{
m_List.InsertItem(m_List.GetItemCount(), _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T("启动鼠标钩子成功")); CButton *pButton = (CButton *)GetDlgItem(IDC_BUTTON_STARTHOOK)->EnableWindow(FALSE); CButton *Button = (CButton *)GetDlgItem(IDC_BUTTON_STOPHOOK)->EnableWindow(TRUE); }
else
{
m_List.InsertItem(m_List.GetItemCount(), _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T("启动鼠标钩子失败"));
}
} //结束鼠标钩子
void CLowLevelHookMouseDlg::OnBnClickedButtonStophook()
{
// TODO: 在此添加控件通知处理程序代码 StopHookMouse StopHook;
__hInstanceDll = LoadLibrary(_T("HookDll.dll"));
if (__hInstanceDll == NULL)
{
::MessageBox(NULL, (LPCTSTR)GetLastError(), L"LoadLibrary() Error", );
return;
} StopHook = (StopHookMouse) ::GetProcAddress(
__hInstanceDll, "StopHookMouse"); if (StopHook == NULL)
{
m_List.InsertItem(m_List.GetItemCount(), _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T("获取函数 StopHookMouse 失败")); return;
}
else
{
StopHook();
m_List.InsertItem(m_List.GetItemCount(), _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T(""));
m_List.SetItemText(m_List.GetItemCount() - , , _T("停止HOOKMOUSE成功"));
CButton *pButton = (CButton *)GetDlgItem(IDC_BUTTON_STOPHOOK)->EnableWindow(FALSE); CButton *Button = (CButton *)GetDlgItem(IDC_BUTTON_STARTHOOK)->EnableWindow(TRUE); } if (__hInstanceDll != NULL)
{
::FreeLibrary(__hInstanceDll);
} // 确保list control 最后一行可见 跳转到stop那行
m_List.EnsureVisible(m_List.GetItemCount() - , FALSE); }

六、最后

剩下的都是一些简单的实现了,这里觉得重要的写在了上面。其他的实现比较常规。

1.其中有两个checkbox的实现做了发现没有达到想要的效果就废掉了。

2.还有就是源博主中如果多点了几次hook,在unhook的时候会出问题,所以这里

        CButton *pButton = (CButton *)GetDlgItem(IDC_BUTTON_STOPHOOK)->EnableWindow(FALSE);

Ring3 x86 x64 通过.

以上就是本次的一个小总结,如有不妥还请批评指正。

再次感谢。

代码:
链接:http://pan.baidu.com/s/1dEPx03J  密码:y463

IPC自定义消息代码:

链接:http://pan.baidu.com/s/1o795ZRW 密码:dt6p

HOOK - 低级鼠标Hook的更多相关文章

  1. 基于 VirtualApp 结合 whale hook框架实现hook第三方应用

    要点 1. whale hook framework 使用示例: 2. 参考项目:VirtualHook: 3. 按照 VirtualHook 修改 VirtualApp: 4. 编写 hook pl ...

  2. Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook

    前文介绍了导入表hook,现在来说下导出表的hook.导出表的hook的流程如下.1.获取动态库基值 void* get_module_base(pid_t pid, const char* modu ...

  3. windows hook + pyhook3 + python win32api hook + C 键盘hook

    安装pyhook3见:https://www.cnblogs.com/lqerio/p/12096710.html 使用见:https://www.cnblogs.com/lqerio/p/12106 ...

  4. 如何通过HOOK改变windows的API函数(找到函数的相对偏移)

    我们知道,系统函数都是以DLL封装起来的,应用程序应用到系统函数时,应首先把该DLL加载到当前的进程空间中,调用的系统函数的入口地址,可以通过GetProcAddress函数进行获取.当系统函数进行调 ...

  5. 窗口置顶 - 仿TopWind

    前置学习:低级鼠标hook,获得鼠标状态. 这个在原来获得鼠标状态的基础上,加上一个事件处理即可. TopWind就是一个可以置顶窗口的文件,避免复制粘贴的时候的来回切换(大窗口与小窗口),算是一个实 ...

  6. HOOK API (一)——HOOK基础+一个鼠标钩子实例

    HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手 ...

  7. 钩子编程(HOOK) 屏蔽全部按键、鼠标及系统功能键 (4)

    摘要:上篇文章<钩子编程(HOOK) 安装系统全局钩子>已经具体的解说了全局钩子的安装.本文将增强一下钩子的功能.实现屏蔽全部按键鼠标与系统功能键.要实现这个功能.须要安装两个全局钩子,& ...

  8. c# 使用hook来监控鼠标键盘事件的示例代码

    如果这个程序在10几年前,QQ刚刚兴起的时候,有了这个代码,就可实现盗号了. 当然使用钩子我们更多的是实现"全局快捷键"的需求. 比如 程序最小化隐藏后要"某快捷键&qu ...

  9. 键盘Hook【Delphi版】

    原文:https://www.cnblogs.com/edisonfeng/archive/2012/05/18/2507858.html 一.钩子的基本概念 a) Hook作用:监视windows消 ...

随机推荐

  1. [spring源码] 小白级别的源码解析(一)

    一直都在用spring,但是每次一遇到spring深入的问题,就是比较懵的状态.最近花了段时间学习了一下spring源码. 1,spring版本介绍 虽然工作中,一直在用到spring,可能有时候,并 ...

  2. ProtoBuf3.3 安装记录

    翻了很多教程,下载了 PB 的源码在自己的 mac 上编译及安装,记录下新的 1. 首先是下载源码了 https://github.com/google/protobuf/releases 虽然是 g ...

  3. UTC,BJT时间的换算

    题目内容:UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8.现在,你的程序要读入一个整数,表示BJT的时和分.整数的个位和十位表示分,百位和千位表示小时.如果小时小于10,则没有千位 ...

  4. hdu多校第4场 B Harvest of Apples(莫队)

    Problem B. Harvest of Apples Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Su ...

  5. multipath配置详细参考

    1.配置文件结构及位置multipath配置文件/etc/multipath.conf由节(section),子节(sub-section),属性(atribute)和属性值(value)等组成,其结 ...

  6. CST时区,MYSQL与JAVA-WEB服务器时间相差13个小时的问题

    最近倒腾了一台阿里云主机,打算在上面装点自己的应用.使用docker安装了安装mysql后,发现数据库的存储的时间与java-web应用的时间差8个小时,初步怀疑是docker容器时区的问题.经过一系 ...

  7. .Netcore使用Session

    1.使用Session(进程内) 在startup中添加方法 services.AddSession  app.UseSession() services.AddDistributedMemoryCa ...

  8. python信号量

    同进程的一样 Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1:调用release() 时内置计数器+1:计数器不能小于0:当计数器为0时,acquire()将阻塞线 ...

  9. day051 Django创建

    Django的下载安装 下载Django: pip3 install django==1.11.14 创建Django project(项目) 步骤1: 步骤2: 步骤3: 配置settings属性 ...

  10. nginx搭建以及其配置文件

    nginx搭建: 参考link:https://blog.csdn.net/wxyjuly/article/details/79443432 nginx配置文件详解: 参考link:https://w ...