钩子学习笔记

来源:互联网 发布:数控套料软件 编辑:程序博客网 时间:2024/04/27 00:35
 

一.钩子过程就像是一个监听|侦查者,os先把消息发给钩子过程,钩子捕获消息后再决定对消息的处理

二.安装钩子过程的原型说明
HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId );

idHook
是指定安装钩子过程的类型,如WH_MOUSE

lpfn
是指向相应的钩子过程,若参数dwThreadId0,或者指向其他进程创建的线程表示符号,则lpfn应该指向动态链接库中的钩子过程

hMod
指向lpfn所在的dll的句柄,if  dwThreadId由当前进程创建 and 钩子过程在当前进程相关代码中,hMod应该是NULL

dwThreadId 
指向与钩子过程相关的进程,若为0,则钩子与桌面上运行的所有进程都相关

返回值:是所安装的钩子过程的句柄,返回非零表示已经对消息进行处理,如果返回0,则系统把消息传递给目标窗口过程

 

安装钩子的一个例子:

HHOOK g_hMouse=NULL;

LRESULT CALLBACK MouseProc(

  int nCode,      // hook code

  WPARAM wParam,  // message identifier

  LPARAM lParam   // mouse coordinates

)

{

      return 1;

}

 g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId() );

 


三。钩子链的概念:可以安装多个钩子进程形成钩子链,最后安装的钩子总在链的前面,钩子过程完成对消息的处理后可以调用LRESULT CallNextHookEx( HHOOK hhk int nCode WPARAM wParam, LPARAM lParam  );
消息传递给钩子链的下一个钩子过程

Hhk 指定当前钩子过程句柄,就是调用SetWindowsHookEx返回值

 

四,屏蔽组合键消息

LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

 

If( VK_F4==wParam && ( 1==(lParam>>29 & 1) ) )

lParam的第29位:如果alt按下,则其值为1,否则为0

 

五,捕获消息后重发另一个消息

在消息捕获后可以用SendMessage来发送消息

SendMessage有三个版本,分别是全局的,CWindow的,Cwnd

钩子是全局函数,应该调用全局的sendmessage

SendMessage的第一个参数是目标窗口句柄,我们应该用一个全局变量来保存他,定义全部变量g_hWnd,OnInitDialog中把m_hWnd赋值给g_hWnd

然后::SendMessage(g_hWnd,WM_CLOSE,0,0);

 

六,全局钩子,前面我们介绍的钩子全部是当前进程内的,驻于进程内存内。只能处理当前进程的消息,如果我们想屏蔽当前正在运行的所有进程的的鼠标键盘消息,那么钩子过程必须放到动态链接库中。

SetWindowsHookEx的第三个参数要求指定钩子过程所在dll模块句柄,两种方式实现,首先是用DllMain,定义全局实例g_hInst,然后在DllMain函数中保存系统传递过来的Dll模块句柄

 

HINSTANCE g_hInst;

BOOL WINAPI DLLMain( HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved  )

{

   G_hInst=hinstDLL;

}

 

Void SetHook()

{

   g_hMouse=SetWindowHookEx( WH_MOUSE,MouseProc,g_hInst,0 );

}

 

另一种方法是调用GetModuleHandle函数来得到指定dll模块句柄,如果指定的模块已经被映射到当前进程中了,那么该函数返回该指定模块的句柄,模块名是.exe或者.dll

 

七,模块定义文件

LIBRARY Hook //指定dll内部名称

EXPORTS  //指定该dll导出函数名称,从dll导出函数是有序号的,可以自己制定序号,用@ith

SetHook @2

 

八,dll的使用,加载dll,调用dll里的函数

dll文件复制到客户程序目录下

在调用dll的函数之前声明

_declspec(dllimport) void SetHook();

表明SetHook是从dlllib文件中输入的,为了能连接上Hook.dll,需要在link选项卡中输入 ???hook.lib,这样就可以调用dll中的函数了

 

九,钩子的卸载

UnhookWindowsHookEx(g_hMouse);

 

十,深入探讨

dll被多个进程使用时,这些进程可以共享dll的代码和数据。但似乎并没有共享,如果多个进程可以共享同一份可写入数据的话是很危险的。假设dll中数据区有一个指针类型变量,如果第一个进程修改了这个变量的地址值,第二个进程如果共享这个变量的话,这个修改后的地址可能指向其他数据。

为了解决这个问题,windows采用写入时复制机制,当某进程要修改数据时,将复制一片完全一样的dll数据空间,这样你访问你的,别人访问的还是修改前的数据。

原创粉丝点击