第4章钩子函数和窗口子类化

合集下载

钩子函数讲解

钩子函数讲解

钩⼦函数讲解钩⼦,⼏乎所有的键盘监控程序都使⽤钩⼦机制来捕获系统的击键信息。

⼤家知道,在DOS操作系统下,如果要截获某种系统功能,可以在编程中采取截获中断的办法,⽐如要获取击键信息,可以使⽤9号中断调⽤,要获取应⽤程序对⽂件操作功能的调⽤可以截获21号中断。

DOS下截获中断的⽅法是这样的随意和⽅便,不论是驱动程序还是应⽤程序都可以操作,这样就给⼀些恶意程序留下了可乘之机,对系统的安全造成了极⼤的隐患。

⽽在Windows 2000下就不同了,Windows 2000采⽤了保护模式,在保护模式下的中断描述符表是受系统保护的,应⽤程序是不可能再通过修改中断向量来截获系统中断了。

这在提供了更⾼安全性的同时,实际上对应⽤程序在调⽤底层功能⽅⾯造成了很⼤的不便。

不过,Windows采取了⼀些变通的⽅法,将⼀些系统的底层调⽤封装在了⾃⼰的API函数中,通过向⽤户提供接⼝使⽤户可以受限的使⽤⼀些系统调⽤。

钩⼦,⼏乎所有的键盘监控程序都使⽤钩⼦机制来捕获系统的击键信息。

⼤家知道,在DOS操作系统下,如果要截获某种系统功能,可以在编程中采取截获中断的办法,⽐如要获取击键信息,可以使⽤9号中断调⽤,要获取应⽤程序对⽂件操作功能的调⽤可以截获21号中断。

DOS下截获中断的⽅法是这样的随意和⽅便,不论是驱动程序还是应⽤程序都可以操作,这样就给⼀些恶意程序留下了可乘之机,对系统的安全造成了极⼤的隐患。

⽽在Windows 2000下就不同了,Windows 2000采⽤了保护模式,在保护模式下的中断描述符表是受系统保护的,应⽤程序是不可能再通过修改中断向量来截获系统中断了。

这在提供了更⾼安全性的同时,实际上对应⽤程序在调⽤底层功能⽅⾯造成了很⼤的不便。

不过,Windows采取了⼀些变通的⽅法,将⼀些系统的底层调⽤封装在了⾃⼰的API函数中,通过向⽤户提供接⼝使⽤户可以受限的使⽤⼀些系统调⽤。

TIPS:钩⼦是Windows的消息处理机制中提供的⼀个监视点,应⽤程序可以在这⾥安装⼀个过滤程序,这样就可以在系统中的消息流到达⽬的程序前监控它们。

钩子函数的写法

钩子函数的写法

钩子函数的写法钩子函数(Hook functions)是一种在特定时机执行的函数,常用于插件开发、事件处理等场景。

在编写钩子函数时,可以按照以下方式进行:1. 定义一个函数,作为钩子函数的具体实现。

2. 根据需要确定触发钩子函数的时机,例如在特定事件发生前、后或中间进行处理。

3. 在相应的时机调用钩子函数,传递必要的参数。

4. 根据业务逻辑和需求,在钩子函数内部执行相应的操作,可以修改数据、调用其他函数等。

5. 根据具体情况,可能需要在钩子函数中返回一个值或进行错误处理。

以下是一个示例,展示了钩子函数的基本写法:```pythondef pre_processing_hook(data):# 钩子函数的前置处理逻辑print("执行钩子函数前置处理")# 可以修改传入的数据data += " modified"# 返回修改后的数据return datadef main_process(data):# 主要处理逻辑print("执行主要处理逻辑")# 调用钩子函数processed_data =pre_processing_hook(data)# 处理钩子函数返回的数据print("处理钩子函数返回的数据:", processed_data)# 调用示例data = "原始数据"main_process(data)```在上述示例中,`pre_processing_hook` 函数作为一个钩子函数,在`main_process` 函数的执行过程中被调用。

钩子函数在这里扮演了对数据进行预处理的角色,并返回处理后的数据供主要处理逻辑使用。

需要注意的是,钩子函数的具体实现和调用方式可能因编程语言、框架或应用场景而异,上述示例仅为一种通用写法的示意。

在实际开发中,根据具体需求和开发环境进行相应的调整和扩展。

钩子技术原理

钩子技术原理

钩子技术原理
钩子技术(Hooking)是一种在计算机编程中常用的技术,它允许开发者拦截和修改特定的操作或事件。

钩子技术的原理是通过在操作系统或应用程序中插入特定的代码段(钩子函数),以便在特定事件发生时执行自定义的操作。

以下是钩子技术的一般原理:
钩子注册:开发者通过调用操作系统提供的API函数,将自定义的钩子函数注册到目标操作系统或应用程序中。

这些API函数通常提供了不同类型的钩子,如键盘钩子、鼠标钩子、消息钩子等。

事件拦截:一旦钩子函数被注册,它将被插入到操作系统或应用程序的事件处理流程中。

当特定的事件发生时,操作系统或应用程序将调用已注册的钩子函数。

自定义操作:在钩子函数中,开发者可以执行自定义的操作。

这可以包括修改事件的参数、拦截和修改事件的处理流程、记录事件信息、发送自定义的消息等。

钩子链:在某些情况下,多个钩子函数可以被注册,并形成一个钩子链。

当事件发生时,钩子链中的每个钩子函数都会被依次调用,允许开发者在不同的层次上进行操作。

需要注意的是,钩子技术是一种强大的编程技术,但也需要谨慎使用。

滥用钩子技术可能会导致系统不稳定、安全漏洞或不可预测的行为。

因此,在使用钩子技术时,开发者应该遵循最佳实践,并确保对目标系统或应用程序的行为有充分的了解。

python 钩子函数 通俗

python 钩子函数 通俗

python 钩子函数通俗
Python钩子函数,也称为钩子,是一种在特定时间或事件发生时,自动执行的函数。

钩子通常用于扩展或修改现有程序的行为。

在Python中,钩子可以用于拦截程序执行的某些事件,例如函数调用、变量赋值、异常处理等。

在Python中,钩子函数通常使用装饰器实现。

装饰器是一种包装函数的技术,它允许在不修改原始函数代码的情况下,为函数添加额外的功能。

钩子函数通常定义为装饰器函数,并与原始函数一起使用。

例如,以下是一个简单的钩子函数,它在函数调用时打印一条消息:
```
def my_hook(func):
def wrapper(*args, **kwargs):
print('Calling function', func.__name__)
return func(*args, **kwargs)
return wrapper
@my_hook
def my_function():
print('Hello world!')
my_function()
```
在这个例子中,`my_hook`是一个装饰器函数,它接受一个函数作为参数并返回一个包装器函数。

`wrapper`函数打印一条消息,然后调用原始函数`func`。

通过将`@my_hook`装饰器应用于
`my_function`函数,我们可以在函数调用时自动执行`my_hook`函数。

除了函数调用之外,钩子函数还可以用于捕获程序中的异常,拦截变量赋值等事件。

通过使用钩子函数,我们可以轻松扩展和修改现有程序的行为,从而实现更高效和灵活的编程。

钩子函数参数传递方式

钩子函数参数传递方式

钩子函数参数传递方式
钩子函数参数传递方式有三种:
第一种是通过函数的参数传递。

这种方式比较直接,通过将参数传递给钩子函数来实现参数的传递。

通过钩子函数的参数可以传递任何类型的数据,包括普通
的数据类型和自定义的对象类型。

第二种是通过全局变量传递。

这种方式需要在程序中定义全局变量来保存参数,然后在钩子函数中通过访问这个全局变量来获取参数。

这种方式可能会涉及到并
发问题,因此需要处理好全局变量的同步问题。

第三种是通过闭包传递。

这种方式也比较简单,通过在钩子函数外部定义一个闭包,将需要传递的参数作为闭包的参数传递进去,在钩子函数内部就可以访问到这个参数了。

这种方式比较灵活,可以处理一些需要动态传递参数的情况。

以上三种方式各有优缺点,需要根据具体的情况来选择合适的方式。

在实际使用中,我们一般会根据钩子函数的使用场景、传递的参数类型和数量等因素综合
考虑,选择最适合的传递方式。

高级图形界面库设计方法

高级图形界面库设计方法
I SSN 100 9- 89 4
CN 22 - 1323/ N
长春工程学院学报 ( 自 然科学版) 2007 年 第 8 卷 第 I 期 J .Changchun Inst .Tech. ( Nat.Sci.Edi . ) ,2007 ,Vol .8,No. I
17 / 2 8 55 -5 8
高级图形界面库设计 方法
作者简介 : 黄同( 1980,6 一) , 汉) , 男( 河南南阳, 硕士研究生 主要研究信号处理、 系统软件开发。
型一一对应的。比如, WH_KEYBOARD 表示安装的 是键盘钩子, WH_MOU 表示是鼠标钩子等。Lpfn SE
是钩子函数的地址 。HMod 是钩子 函数所在 的实例
的句柄。对于线程钩子, 该参数为 NULL;对于系统 钩子 , 参 数 为 钩 子 函 数 所 在 的 DLL 句 柄。 该 dwThr adId 指定钩子所监视的线程的线程号。对于 e 全局钩子 , 该参 为 NULL。如果 函 调用成功, 钩 子函 被安装在 idHook 类型钩子链的最开头, 同时
由于程序中往往有很多窗口如果在程序中使用cwndsubclass2windowsubclassdlgitem直接对每个窗口子类化若仅对对话框上所有控件重新绘制可以采enumchildwindows方法枚举所有子窗口并子类化但对sdimdi程序来说就没有那么简单了所以采用枚举窗口并子类化的方法对于可供dlsdimdi各种类型的程序使用的图形界面库是受到限制的最好的办法是再借助于钩子技术在窗口创建的时候就直接子类化于图形界面库是对使用该库的程序进行美化所以我们需要采用用户界面线程钩子
WH_SYSM SGFILTER。其中WH_C ALLWNDPROC类型 的钩子可以监视所有发往窗 口过程的消息, 无铃

消息钩子函数入门篇

消息钩子函数入门篇

消息钩子函数入门篇【摘要】消息钩子函数是一种常见的编程技术,用于在特定事件发生时触发自定义功能。

本文将介绍消息钩子函数的基本概念,包括其定义、作用和使用方法。

我们将通过实例演示消息钩子函数的具体应用,并解释与之相关的一些重要概念。

在结尾部分,我们将对本文内容进行总结,展望未来消息钩子函数的发展,以及提出一些建议。

希望通过本文的介绍,读者能够对消息钩子函数有一个更深入的理解,并在实际项目中灵活应用。

【关键词】消息钩子函数、入门、介绍、目的、背景、作用、使用、实例、相关概念、总结、展望、结束语1. 引言1.1 消息钩子函数入门篇- 介绍消息钩子函数是一种在软件开发中非常常见的概念,它可以让我们在特定的事件发生时执行自定义的逻辑。

在程序执行的过程中,系统会触发一些特定的事件,比如用户点击按钮、发送请求等,这时就可以通过消息钩子函数来捕获这些事件并进行相应的处理。

消息钩子函数的概念在不同的编程语言和框架中有着不同的实现方式,但其核心思想是相通的。

通过消息钩子函数,开发者可以在程序的不同阶段插入自定义的逻辑,这样可以更灵活地控制程序的行为。

在本篇文章中,我们将深入介绍消息钩子函数的概念和应用,帮助读者更好地理解和应用这一重要的技术。

从消息钩子函数的基本概念、作用和使用方法,到实际的应用案例和相关概念的解释,我们将全方位地探讨消息钩子函数的入门知识,希望能够帮助读者更好地利用这一功能提升自己的编程技能。

的内容将在接下来的文章中一一展开,让我们一起来深入学习吧!1.2 消息钩子函数入门篇- 目的消息钩子函数入门篇是一种非常有用的编程技术,它可以让开发人员在特定的事件发生时执行特定的功能。

在编程中,我们经常需要在某些事件发生时执行一些额外的操作,比如在用户点击按钮时验证表单数据,在用户登录时发送通知等。

而消息钩子函数就是为了实现这种需求而设计的。

这篇文章的目的是帮助读者了解什么是消息钩子函数,以及它们的作用和使用方法。

pytorch register钩子函数

pytorch register钩子函数

pytorch register钩子函数全文共四篇示例,供读者参考第一篇示例:PyTorch是一个主流深度学习框架,提供了许多便捷的功能和工具来简化深度学习模型的开发和训练过程。

钩子函数(hook)是一个非常强大的功能,可以帮助用户在模型的各个阶段插入自定义的逻辑,比如在每次前向传播或反向传播过程中获取中间数据或梯度信息。

本文将介绍PyTorch中register钩子函数的用法和实例。

## 什么是钩子函数钩子函数是一种在PyTorch中非常重要的概念,它允许用户在模型的某些关键节点插入自定义的逻辑,以便实现一些特定的功能或目的。

用户可以通过钩子函数获取模型中间层的输出,监控梯度的变化,实现梯度剪裁等。

PyTorch提供了两种类型的钩子函数,分别是register_forward_hook和register_backward_hook。

## register_forward_hookregister_forward_hook允许用户在每次前向传播过程中注册一个钩子函数,该钩子函数可以获取模型中间层的输出或其他信息。

register_forward_hook接受一个函数作为参数,这个函数的输入参数有三个:模块,输入和输出。

在这个函数中,用户可以通过输出参数获取模块的输出数据。

```import torchimport torch.nn as nndef hook_fn(module, input, output):print(module)print('input:', input)print('output:', output)model = nn.Linear(2, 1)hook = model.register_forward_hook(hook_fn)hook.remove()```在这个示例中,我们首先定义了一个模型nn.Linear(2, 1),然后注册了一个钩子函数hook_fn。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第4章钩子函数和窗口子类化钩子是操作系统消息处理的一种机制。

通过钩子,应用程序可以安装一个钩子回调过程让系统调用,从而监视系统中的消息队列,在这些消息到达目标窗口之前对这些消息进行处理。

本章主要介绍钩子函数的基本概念以及几种常用钩子的应用举例。

4.1 钩子函数早在Windows3.x的时候,就有了钩子函数,它经历了Windows9x/NT/2000/XP/2003各个操作系统,始终保持了最大的兼容性。

可以说大部分的钩子函数适用于现在所有的Win32操作系统,钩子函数在系统编程方面有着广泛的应用前景。

首先应该承认钩子会降低系统的性能,因为它增加系统处理每一个消息的开销,所以用户除非必要才安装钩子,而且还要尽可能早地去除钩子。

操作系统支持多种类型的钩子,每种类型都提供了它特有的消息处理机制,比如应用程序使用WH_MOUSE钩子只能监视鼠标的消息队列。

对于每种类型的钩子,系统都维护一个各自独立的钩子链,钩子链是一个指向用户提供的回调函数钩子过程的链表指针。

当与特定类型的钩子相关的窗口消息发生时,系统会把消息依次传递给钩子链中的每一个回调过程,传递的过程由用户定义的回调过程实现。

一般情况下,用户提供的钩子回调过程必须调用钩子链中的下一个回调过程。

否则钩子处理可能会中断,出现不可预测的结果。

钩子过程可以监视窗口消息,也可以修改甚至停止钩子消息的继续传递,不让它到达钩子链中的下一个目标过程。

钩子过程需要用户调用SetWindowsHookEx函数进行安装。

钩子过程一般遵循下面的调用规范。

LRESULT CALLBACK HookProc(intnCode,WPARAMwParam,LPARAMlParam);其中HookProc是应用程序提供的函数名。

nCode参数是一个钩子标识码,钩子过程会利用它决定下一步进行的操作。

这个标识码的值与安装的钩子类型有关。

每种类型都有它的自身定义。

后面两个参数的定义依赖于nCode参数,一般用于存放与窗口消息相关的内容。

SetWindowsHookEx函数会自动安装一个钩子过程,这个过程位于钩子链表的头部,最后安装的钩子函数总是最先得到响应。

前面的钩子处理过程可以决定是否调用钩子链中的下一个过程,这可以通过调用CallNextHookEx函数实现。

注意:某些钩子类型能够监视发生的窗口消息系统自动把消息依次传递给钩子链中的每一个钩子过程,而不管用户是否调用CallNextHookEx函数。

全局钩子会监视同一桌面环境下所有的窗口消息,而线程钩子只能监视单个线程内发生的消息。

由于全局钩子能够在同一桌面的所有应用环境下调用,所有这个钩子过程必须在一个动态链接库中实现。

注意:全局钩子一般只用于调试目的,应尽可能地避免使用。

全局钩子会显著地降低系统的性能,增加系统的开销,并可能会与安装同一全局钩子的应用程序发生冲突。

钩子函数的处理应该尽可能简单,并要快速退出。

对于处理复杂的过程,可以借助于发送异步处理窗口消息的方式实现。

操作系统提供了以下一些钩子,这些钩子允许用户监视系统消息处理的某一个方面。

如表4-1所示:安装钩子函数要用到SetWindowsHookEx函数。

对于全局钩子而言,钩子过程必须在一个动态链接库模块中实现,这个过程必须作为动态链接库的输出函数,以便能够在安装钩子程序中通过调用LoadLibrary/GetProcAddress函数获得回调过程的地址,然后把回调函数的地址传递给SetWindowsHookEx函数。

HOOK PROC hkprcSys Msg;Static HINSTANCE hinstDLL;Static HHOOK hhookSysMsg;hinstDLL=LoadLibrary((LPCTSTR)"c:\\windows\\sysmsg.dll");hkprcSysMsg=(HOOKPROC)GetProcAddress(hinstDLL,"SysMessageProc");hhookSysMsg=SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0);同样释放全局钩子函数要用到UnhookWindowsHookEx,这个钩子函数本身不会释放包含钩子过程的动态链接库。

这是因为全局钩子会被同一桌面的所有应用程序调用,系统会自动调用LoadLibrary函数,把实现钩子过程的动态链接库映射到受它影响的当前进程的地址空间中去。

同样,最后系统会自动在所有使用该动态链接库的应用程序不再使用这个钩子时,调用FreeLibrary函数释放动态链接库。

编写全局钩子,最好不要使用MFC,也尽可能地不要使用C运行库函数,应该尽可能地使用API函数代替使用这些函数,比如常用lstrcpy代理strcpy、_tcscpy等。

这是因为全局钩子会被映射到受它影响的所有进程的地址空间,一个不依赖这些运行库的运行的程序可能会产生更多的潜在冲突。

比如一个采用VisualBasic或者Java编写的应用程序,它们不会使用MFC类库。

另外全局钩子中的全局变量,当映射到某个进程中时,它将变成属于该进程所有的私有变量,不能被其他进程共享,因为它们映射的地址是不同的。

为了实现变量共享,可以使用前面谈到的共享节的办法。

#pragma data_seg(".Share")HANDLE hWnd=NULL;#pragma dta_seg()#pragma comment(linker,"/section:.Share,rws")当然还可以借助于其他方式进行通信,比如共享内存等。

如果用户采用窗口消息(SendMessge、PostMessage),一定不要采用传递指针的方法,因为在另外一个进程中无法访问另外一个进程的地址空间。

4.2 键盘钩子的应用键盘钩子有着广泛的用途,比如在WindowsNT环境下,用户可以直接调用GetLastInputInfo函数获得上一次输入的信息,通过这个信息得到一个当时的时间戳,通过该时间决定在若干时间内没有用户输入(键盘和鼠标)触发某些任务。

然而Windows9x并没有提供这样的函数,为了得到上一次键盘和鼠标动作的时间,就必须实现一个全局键盘和鼠标,记录钩子函数回调时发生的时间。

另外键盘钩子禁止用户在多个进程间切换。

Windows提供的多任务机制使用户可以自由地在多个应用程序间自由切换,每一个应用程序作为一个进程都拥有独立的进程地址空间,各个程序之间互不影响。

特别是在WindowsNT环境下,一个应用程序的挂起,一般不会影响其他程序的运行,操作系统可以很轻松地把挂起的进程杀死,从而使系统得到正常响应。

然而这种机制同时也会助长用户同时运行多个程序,开多个窗口,从而使系统不堪重负,反应迟缓。

这对于普通的个人用机不会有什么影响,但对于工业实时控制计算机而言,情况就大不一样。

由于WindowsNT 并不是一个实时的操作系统,一个程序的运行尽管不会直接影响其他程序,但是如果它对系统资源如CPU、内存占用过多,就会直接影响其他程序的快速响应,比如完全格式化一个质量不好的软盘、浏览次品光盘、刻录光盘、复制大文件等。

因此对于运行重要程序的计算机而言,重要程序应该独占系统资源,禁止任务切换,以便提高系统的实时性和可靠性,以防意外事件发生。

另外,对于文献检索的公共机房,机房工作人员一般也不希望检索人员来回切换程序。

(1)在Windows9x环境下,应用程序可以通过不同的参数调用SystemParametersInfo函数,实现允许和禁止任务切换。

方法如下:例4-1Windows9x环境下禁止任务切换。

UINT nPreviousState;SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,TRUE,&nPreviousState,0); //禁止任务切换SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,FALSE,&nPreviousState,0); //允许任务切换只是应用程序退出前,必须恢复允许任务切换状态。

(2)对于WindowsNT4.0ServicePack3或更高版本,包括Windows2000和WindowsXP,应用程序可以通过安装低级键盘钩子(WH_KEYBOARD_LL)实现禁止任务切换。

在Windows9x/Me环境下不起作用。

#define _WIN32_WINNT 0x0400HHOOK hhkLowLevelKybd;LRESULT CALLBACK LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam){ KBDLLHOOK STRUCT*pkbhs=(KBDLLHOOKSTRUCT*)lParam;BOOL bControlKeyDown=0;switch(nCode){ Case HC_ACTION:bControlKeyDown=GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT)*8) -1); //检查是否按下Ctrl键if(pkbhs->vkCode==VK_ESCAPE&&bControlKeyDown) return 1; //禁止Ctrl+Escif(pkbhs->vkCode==VK_TAB&&pkbhs->flags&LLKHF_ALTDOWN) return 1; //禁止Alt+Tabif(pkbhs->vkCode==VK_ESCAPE&&pkbhs->flags&LLKHF_ALTDOWN) return 1; break; //禁止Alt+Escdefault: break;return CallNextHookEx(hhkLowLevelKybd,nCode,wParam,lParam); }int WINAPIWinMain(HINSTANCE hinstExe,HINSTANCE,PTSTR pszCmdLine,int){ hhkLowLevelKybd=SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,hinstExe,0); //安装钩子过程MessageBox(NULL,TEXT("Alt+Esc,Ctrl+Esc,and Alt+Tab are now disabled.")TEXT("Click"Ok" to terminate this application and re-enable these keys."),TEXT("Disable Low-Level Keys"),MB_OK);UnhookWindowsHookEx(hhkLowLevelKybd); return(0); }(3)在WindowsNT环境下还有一种方法,通过枚举窗口,禁止除当前窗口以外的所有窗口,程序退出前,恢复这些窗口为允许状态。

相关文档
最新文档