Hook函数三步走(SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx)

简介: Hook函数三步走(SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx)

Hook(Windows系统机制)


Hook定义


Hook是Windows中提供的一种用以替换DOS下“中断”的系统机制,中文译为“挂钩”或 “钩子” 。


在对特定的系统事件进行hook后,一旦发生已hook事件,对该事件进行hook的程 序就会收到系统的通知,这时程序就能在第一时间对该事件做出响应。


钩子(Hook) ,是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定 窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处 理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。


钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出, 在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函 数即可以加工处理(改变) 该消息,也可以不作处理而继续传递该消息,还可以强制结束消息 的传递。


Hook原理


• 每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定 的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程序。当与指定的Hook类 型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息, 或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始, 而最早安装的钩子放在最后,也就是后加入的先获得控制权。


• Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放 其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系 统会自动为它做卸载钩子的操作。


• 钩子子程是一个应用程序定义的回调函数(CALLBACK Function) ,不能定义成某个类的成员函数,只能定 义为普通的C函数。用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可 以是系统中所有线程的事件。


系统钩子与线程钩子


SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。


线程钩子用于监视指定线程的事件消息。线程钩子一般在当前线程或者当前线 程派生的线程内。


系统钩子 监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有 的应用程序,所以钩子函数必须放在独立的动态链接库(DLL) 中。系统自动将 包含“钩子回调函数”的DLL映射到受钩子函数影响的所有进程的地址空间中, 即将这个DLL注入了那些进程。


钩子函数


我师父说:就研究明白这三个函数,钩子基本就会了。


设置钩子: SetWindowsHookEx


函数功能:该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件相关.


函数原形:


HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId );


参数:


  • idHook:指示欲被安装的挂钩处理过程之类型,此参数可以是以下值之一:


image.png

image.png


  • lpfn:指向相应的挂钩处理过程.若参数dwThreadId为0或者指示了一个其他进程创建的线程之标识符,则参数lpfn必须指向一个动态链接中的挂钩处理过程.否则,参数lpfn可以指向一个与当前进程相关的代码中定义的挂钩处理过程.


  • hMod:指示了一个动态链接的句柄,该动态连接库包含了参数lpfn 所指向的挂钩处理过程.若参数dwThreadId指示的线程由当前进程创建,并且相应的挂钩处理过程定义于当前进程相关的代码中,则参数hMod必须被设置为NULL(0).


  • dwThreadId:指示了一个线程标识符,挂钩处理过程与线程相关.若此参数值为0,则该挂钩处理过程与所有现存的线程相关.


返回值:


若此函数执行成功,则返回值就是该挂钩处理过程的句柄;若此函数执行失败,则返回值为NULL(0)。若想获得更多错误信息,请调用GetLasError函数。


参数说明:


备注:若参数hMod为NULL,而参数dwThreadld为0或者指示了一个其他进程创建的线程标识符,则会产生错误.


对函数CallNextHookEx进行调用以下链接下一个挂钩处理过程是可选的,但也是被推荐的否则,其他安装了此挂钩的应用程序将无法获得此挂钩通知,从而可能导致错误的行为.除非您确实希望防止其他应用程序看到此挂钩通知,您应当调用函数CallNextHookEx。


在终止一个应用程序之前,必须调用函数UnhookWindowsHookEx以释放与此挂钩相关的系统资源.


挂钩的作用域依赖与挂钩的类型.一些挂钩只能被设置成系统作用域,其他挂钩(如下所示)还可以被设置为某一特定线程的作用域:


image.png

image.png


对于一个特定的挂钩类型,现成的挂钩先被调用,然后才是系统挂钩被调用。


系统挂钩作为共享资源,安装一次就对所用应用程序产生影响。所有的系统挂钩函数必须在库中。系统挂钩应当被限制用于一些特殊用途的应用程序或者用来作为应用程序调试的辅助工具。不再需要挂钩的库应当将相应的挂钩处理过程删除掉。


释放钩子: UnhookWindowsHookEx


通过SetWindowsHookEx函数删除挂钩链中安装的钩子过程。


函数原型:


BOOL WINAPI UnhookWindowsHookEx(
  _In_ HHOOK hhk
);


参数


  • hhk [in]


类型:HHOOK


要取下钩子的把手。此参数是通过先前调用SetWindowsHookEx获得的钩子句柄


返回值


类型:BOOL


如果函数成功,返回值不为零。


如果函数失败,返回值为零。要获取扩展错误信息,请调用GetLastError。


备注:


即使在UnhookWindowsHookEx返回后,挂钩过程也可能处于被另一个线程调用的状态。如果钩子过程没有被并发调用,则挂钩过程将在UnhookWindowsHookEx返回之前立即被删除。


继续钩子: CallNextHookEx


在线程级的钩子中经常用到 GetCurrentThreadID 函数来获取当前线程 的 ID


将钩子信息传递给当前钩子链中的下一个钩子过程。钩子过程可以在处理钩子信息之前或之后调用这个函数。


函数原型:


LRESULT CallNextHookEx(
  [in, optional] HHOOK  hhk,
  [in]           int    nCode,
  [in]           WPARAM wParam,
  [in]           LPARAM lParam
);


参数


  • [in, optional] hhk


类型:HHOOK


该参数可以忽略,是可选的。


  • [in] nCode


类型:int


传递给当前钩子过程的钩子代码。下一个挂钩过程使用此代码来确定如何处理挂钩信息。


  • [in] wParam


类型:WPARAM


传递给当前钩子过程的wParam值。此参数的含义取决于与当前钩子链关联的钩子类型。


  • [in] lParam


类型:LPARAM


传递给当前钩子过程的lParam值。此参数的含义取决于与当前钩子链关联的钩子类型。

返回值


类型:LRESULT


该值由链中的下一个钩子过程返回。当前的钩子过程也必须返回这个值。返回值的含义取决于钩子类型。有关详细信息,请参阅各个挂钩过程的说明。


函数备注


挂钩程序安装在链条中,适用于特定挂钩类型。CallNextHookEx调用链中的下一个钩子。


调用CallNextHookEx是可选的,但强烈推荐;否则,安装了钩子的其他应用程序将不会收到钩子通知,因此可能会出现不正确的行为。除非您绝对需要防止其他应用程序看到通知,否则您应该调用CallNextHookEx。


Hook小案例


提示:运行这个程序你会丧失鼠标控制权,别乱动别的鼠标按键切换什么的,运行后摁下enter键,关掉弹窗就恢复了


提示:运行这个程序你会丧失鼠标控制权,别乱动别的鼠标按键切换什么的,运行后摁下enter键,关掉弹窗就恢复了


提示:运行这个程序你会丧失鼠标控制权,别乱动别的鼠标按键切换什么的,运行后摁


#include <Windows.h>
#include <cmath>
LRESULT CALLBACK HookMFunc(int iCode, WPARAM wParam, LPARAM lParam)
{
  PMSLLHOOKSTRUCT pmsh = (PMSLLHOOKSTRUCT)lParam;
  bool bControl = false;
  static float scr_x = GetSystemMetrics(SM_CXSCREEN);
  static float scr_y = GetSystemMetrics(SM_CYSCREEN);
  static float scr_c_x = scr_x / 2.0f;
  static float scr_c_y = scr_y / 2.0f;
  float dx = pmsh->pt.x - scr_c_x;
  float dy = pmsh->pt.y - scr_c_y;
  float fds = sqrt(dx*dx + dy*dy);
  if (fds > 10)
  {
    float at = atan2(dy, dx);
    // 陷阱光标
    SetCursorPos(int(scr_c_x + cos(at) *100), int(scr_c_y + sin(at) * 100));
    bControl = true;
  }
  return (bControl ? 1 : CallNextHookEx(NULL, iCode, wParam, lParam)); // 继续钩子
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  HHOOK hHm = SetWindowsHookEx(WH_MOUSE_LL, HookMFunc, hInstance, NULL);
  MessageBox(NULL, L"当你点击之后系统会自动释放控制权", L"提示", MB_OK);
  return 0;
}


相关文章
|
1月前
|
机器学习/深度学习 存储 数据可视化
以pytorch的forward hook为例探究hook机制
【10月更文挑战第10天】PyTorch 的 Hook 机制允许用户在不修改模型代码的情况下介入前向和反向传播过程,适用于模型可视化、特征提取及梯度分析等任务。通过注册 `forward hook`,可以在模型前向传播过程中插入自定义操作,如记录中间层输出。使用时需注意输入输出格式及计算资源占用。
|
2月前
|
JSON 算法 数据安全/隐私保护
brida和frida练习hook逆向技术【中】
本文介绍了如何在未加壳、未混淆的 APK 中定位并破解加密算法,并使用 Burp 插件 autoDecoder 进行自动化加解密及口令爆破。文中详细描述了从反编译到配置插件的全过程,并提供了关键要素如 AES 算法、SECRET_KEY 和 Base64 编码的具体应用。此外,还展示了如何调整并发数以提高爆破成功率。
37 0
brida和frida练习hook逆向技术【中】
|
2月前
|
Java Android开发 数据安全/隐私保护
brida和frida练习hook逆向技术【上】
使用zangcc测试包.apk,练习 Brida 和 Frida 的 Hook 逆向技术。
18 0
brida和frida练习hook逆向技术【上】
|
3月前
|
前端开发 JavaScript 开发者
React生命周期方法完全指南:深入理解并高效应用每个阶段的钩子——从初始化到卸载的全方位解析
【8月更文挑战第31天】本文详细介绍了React组件生命周期方法,包括初始化、挂载、更新和卸载四个阶段的关键钩子。通过探讨每个阶段的方法,如`componentDidMount`和`componentWillUnmount`,帮助开发者在正确时机执行所需操作,提升应用性能。文章还提供了最佳实践,指导如何避免常见错误并充分利用最新钩子。
86 0
|
5月前
|
测试技术 编译器 C#
一篇文章讲明白hook(钩子程序)(转载)
一篇文章讲明白hook(钩子程序)(转载)
237 0
|
6月前
|
存储 Python
[重学Python]Day3 函数和模块的使用
本文介绍了Python中的函数和模块的使用。函数用于避免代码重复,通过`def`定义,参数可有默认值或可变参数。模块管理同名函数,通过`import`导入。示例包括计算最大公约数和最小公倍数、判断回文数和素数的函数,以及检测回文素数的程序。
41 0
|
6月前
|
前端开发 API 数据处理
useEffect 实践案例(2):自定义 hook
useEffect 实践案例(2):自定义 hook
|
6月前
|
存储 前端开发
useSyncExternalStore,一个陌生但重要的 hook
useSyncExternalStore,一个陌生但重要的 hook
623 0
|
缓存 前端开发 JavaScript
React 中的状态管理和副作用处理解决方案 :Hook
在现代 Web 前端开发中,构建复杂的用户界面已成为一项重要任务。随着应用程序规模和复杂性的增加,状态管理和副作用处理变得愈发关键。为了应对这些挑战,React 引入了 Hooks Pattern(钩子模式),这是一种用于管理组件状态和处理副作用的技术。本文将详细介绍 Hooks Pattern 的概念、优点和缺点,适用场景,开源实现方案,以及在知名项目中的应用
144 0
|
存储 前端开发 API
我打破了 React Hook 必须按顺序、不能在条件语句中调用的枷锁!
不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确。(如果你对此感到好奇,我们在下面会有更深入的解释。)