关于钩子(HOOK)

来源:互联网 发布:js锚点跳转 编辑:程序博客网 时间:2024/05/22 08:25
以前做钩子的时候没写记录的习惯。昨天马力叫我重新做一个。这次补上。
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
至于是否需要把钩子写在DLL里面取决于需求,如果只HOOK本进程得消息,可以把消息回调函数和调用钩子的函数写在一起,也就是只需要写个EXE就可以了。如果要HOOK全局消息,需要全局钩子,这样,需要把HOOK代码注入到系统每个进程里面去。而实现这个最好的方法,就是用DLL来实现。系统会自动把该DLL注入到所有的进程空间中。所以,不一定是必须要写DLL来HOOK。

相关函数:
创建新的钩子函数加
   HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId)
钩子类型:比如  WH_KEYBOARD_LL,
回调函数地址:钩子处理函数 LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
实例句柄:应用程序的实例句柄
线程ID:要为哪个线程安装钩子.如果它为0则为全部线程都安装钩子,即为全局钩子.这就是获得全部应用程序消息控制权的开始

卸载钩子函数
BOOL UnhookWindowsHookEx( HHOOK hhk) 
hhk为前一个函数的返回值。

我也不知道如何描述的函数= =
  LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) 。

这次需求仅仅是屏蔽,那就是不需要记录信息。仅仅是勾取消息后直接丢弃。

设置键盘底层钩子
HHOOK key_hHook = SetWindowsHookEx(
   WH_KEYBOARD_LL,
   KeyHookProc,
   base,
   //g_hInst,
   0);
鼠标底层钩子
HHOOK mouse_hHook = SetWindowsHookEx(
   WH_MOUSE_LL,
   MouseHookProc,
   base,
   0 );

之后关于钩子函数,屏蔽即是PC机不作出回应。那么钩出的所有消息不做任何处理,直接给予抛弃处理。即return true;   


关于DLL,转载下在论坛看的一段。因为自己也不是很懂。
Win32 DLL的入口和出口函数都是DLLMain这同Win16 DLL是有区别的。只要有进程或线程载入和卸载DLL时,都会调用该函数,其原型是:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;第二个参数指明了当前调用该动态连接库的状态,它有四个可能的值:DLL_PROCESS_ATTACH(进程载入)、DLL_THREAD_ATTACH(线程载入)、DLL_THREAD_DETACH(线程卸载)、DLL_PROCESS_DETACH(进程卸载)。在DLLMain函数中可以通过对传递进来的这个参数的值进行判别,根据不同的参数值对DLL进行必要的初始化或清理工作。由于在Win32环境下,所有进程的空间都是相互独立的,这减少了应用程序间的相互影响,但大大增加了编程的难度。当进程在动态加载DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。当DLL内存被映射到进程空间中,每个进程都有自己的全局内存拷贝,加载DLL的每一个新的进程都重新初始化这一内存区域,也就是说进程不能再共享DLL。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。一种方法便是把这些需要共享的数据单独分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,建立一个内存共享的DLL。 


之后即是动态链接库的加载。
静态加载需要动态链接的DLL和LIB以及H头文件。
之后添加代码
#include<xxx.h>
#pragma comment(lib,"XXX.lib").
之后直接引用函数。

动态加载:
typedef BOOL  (_stdcall * AddProc)(需导出的函数参数名)
  HINSTANCE hInst;
  
  hInst=LoadLibrary("动态链接库名.dll");
  AddProc m_Unlock=(AddProc)GetProcAddress(hInst,"函数名");//获取Dll的导出函数
  AddProc m_Lock=(AddProc)GetProcAddress(hInst,"函数名");//获取Dll的导出函数

不过动态加载的方法在使用的时候我的程序会停止工作。具体原因不明。静态加载没问题。
0 0
原创粉丝点击