您的位置:首页 > 其它

学习笔记-HOOK钩子(1)l

2006-03-27 22:00 776 查看
基本概念



[/b]

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

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

Hook
(钩子)增加了系统处理的数量,系统需要处理每一个消息,所以尽量在必要的情况下安装钩子,并且尽快移除系统钩子。

 

摘要:
Windows
系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是
Windows
系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入,屏幕取词,日志监视等等。可见,利用钩子可以实现许多特殊而有用的功能。因此,对于高级编程人员来说,掌握钩子的编程方法是很有必要的。

 

 

<title>
How to set a Windows hook in Visual C# .NET
</title>

link : http://support.microsoft.com/kb/318804/en-us
Global hooks are not supported in the .NET Framework
[/b]

Except for the

WH_KEYBOARD_LL
low-level hook and the

WH_MOUSE_LL
low-level hook, you cannot implement global hooks in the Microsoft .NET Framework. To install a global hook, a hook must have a native DLL export to inject itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export. The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.

Low-level hook procedures are called on the thread that installed the hook. Low-level hooks do not require that the hook procedure be implemented in a DLL.

(下面是微软网站上的中文版文章
)

<title>HOW TO
:在
Visual C# .NET
中设置窗口挂钩
</title>

您无法在
Microsoft .NET
[/b]

框架中实现全局挂钩。

[/b]

若要安装全局挂钩,挂钩必须有一个本机动态链接库
(DLL)
导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个
DLL
导出,而
.NET
框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。

 

[/b]

可以看出,这里的翻译存在问题确切的说是少了我们需要的信息,原文中分明提到了
[/b]

low-lever
[/b]


[/b]

      

[/b]
WH_KEYBOARD_LL
low-level hook and the
WH_MOUSE_LL
low-level hook
是除外的,也就是说
.NET Framework
下支持这两个
low-lever hook
,原因也说得很清楚了。我认为我们可以简单点理解,钩子需要把自身的
DLL
注入到其它的进程空间中,(牵涉到在
Win32
环境运行机制的问题:不同的进程在内存中的拥有各自的内存空间),但是需要
.NET Framework
支持的

dll

导入到不需要
.NET Framework
支持的进程中,那我们的就

dll

不能正常工作了,所以说不支持全局的
Hook
,而
low-lever hook
不需要

dll

注入这一过程,所以能完成全局钩子的任务。

 

让我们看看
MSDN
[/b]

对这两个
low-lever hook
[/b]

是怎么描述的:

[/b]

LowLevelKeyboardProc
[/b]

Function
[/b]

[/b]

The

LowLevelKeyboardProc
[/b]

[/b]
hook procedure is an application-defined or library-defined callback function used with the

SetWindowsHookEx
[/b]

[/b]
function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "

injected
[/b]
".
However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.

The HOOKPROC type defines a pointer to this callback function. LowLevelKeyboardProc is a placeholder for the application-defined or library-defined function name.

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

LowLevelMouseProc
[/b]

Function
[/b]

The

LowLevelMouseProc
[/b]

[/b]
hook procedure is an application-defined or library-defined callback function used with the

SetWindowsHookEx
[/b]

[/b]
function. The system call this function every time a new mouse input event is about to be posted into a thread input queue. The mouse input can come from the local mouse driver or from calls to the mouse_event function. If the input comes from a call to mouse_event, the input was "injected".
However, the WH_MOUSE_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.

The HOOKPROC type defines a pointer to this callback function. LowLevelMouseProc is a placeholder for the application-defined or library-defined function name.

[/b]

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

至此真相大白了!!!
[/b]

[/b]

 

[/b]

一些运行机制:
[/b]

[/b]


Win16
环境中,
DLL
的全局数据对每个载入它的进程来说都是相同的;而在
Win32
环境中,情况却发生了变化,
DLL
函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入
DLL
时,操作系统自动把
DLL
地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该
DLL
的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的
DLL
的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。

因此,在
Win32
环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个

Dll

的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。

#pragmadata_seg
预处理指令用于设置共享数据段。例如:

#pragmadata_seg

(

"SharedDataName")

HHOOK hHook=NULL;

#pragmadata_seg()

 


#pragmadata_seg("SharedDataName")

#pragmadata_seg()
之间的所有变量将被访问该

Dll

的所有进程看到和共享。再加上一条指令
#pragma comment(linker,"/section:.SharedDataName,rws"),
那么这个数据节中的数据可以在所有
DLL
的实例之间共享。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。

当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里
(
以下简称
"
地址空间
")
。这使得
DLL
成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。

 

[/b]

[/b]

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: