钩子(hook)

来源:互联网 发布:昆明知行科技有限公司 编辑:程序博客网 时间:2024/06/05 07:35
钩子(hook)是内核对象
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子过程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。   
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
钩子链表和钩子子程:
  每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。 一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始, 而最早安装的钩子放在最后,也就是后加入的先获得控制权。
  Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。
  钩子子程是一个应用程序定义的回调函数(CALLBACK Function),不能定义成某个类的成员函数,只能定义为普通的C函数。用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。

局部钩子
Hook g_mouse;
hook g_heybard;
hwnd g_hwnd;
lresult callback mouseproc(int ncode,wparam ,lparam)
{
     //如果想要消息
      return callnexthookex(g_house,ncode,wparam,lparam);
      return 1l;
}

lresult callback keyboardproc(int ncode,wparam,lparam)
{
//退出当前程序
     if(VK_F2 == wparam && 1==((lparam >>29) &1))
     { 
           sendmessage(g_hwnd,wm_close,0,0);
            unhookwindowsex(g_mouse);
            unhookwindowsex(g_heybard);
     }
     //如果想要传递消息
    //  return callnexthookex(g_heybard,ncode,wparam,lparam);
     // return 1l;
}

在对话框的初始化函数中,下局部鼠标钩子
g_mouse = setwindowshookex(wm_mouse,mouseproc,null,getcurrentthreadid());
g_heybard= setwindowshookex(wm_keyboard,mouseproc,null,getcurrentthreadid());
g_hwnd = m_hwnd;
卸载钩子
UnhookWindowsHookEx(g_hMouse);
UnhookWindowsHookEx(g_heybard);
---------------------------------------------------------
获得当前键盘按下的内容
------------------------------------------------------------------------------
LRESULT CALLBACK KeyboardProc(
   int code,
   WPARAM wParam,
   LPARAM lParam
 )
{
 //LookUpTheMessage
 //if (code == HC_ACTION )
 //{
     if (VK_RETURN == wParam)
     {
    MessageBox(NULL,str,NULL,NULL);
     }
  //当键盘正在被按下则31位返回0,被释放时返回1
  if (/*((lParam >> 30) &1) == 1 &&*/ lParam >>31 & 1== 1 )
  {
  
   CString strtemp;
   //如果是0-9
   if (wParam >= 0x30 && wParam <= 0x39)
   {
    strtemp.Format(_T("%c"),wParam);
    TRACE(_T("%s\n"),strtemp);
    str += strtemp;
   }//如果是a-z
   else if (wParam >= 0x41 && wParam <=0x5A)
   {
    BYTE ks[256];
    GetKeyboardState(ks);
    WORD w;
    UINT scan;
    scan=0;
    ToAscii(wParam,scan,ks,&w,0);
    char ch =char(w);
    TRACE(_T("%c\n"),ch);
    str += ch;
   }
  
  
     }
 //}
 
 //return 1l;
 return CallNextHookEx(g_hKeyBoard,code,wParam,lParam);
}
--------------------------------------------------------------------------------
     char keyname[100]; 
::GetKeyNameText(lParam,keyname,100);//获得按键的键名。 
CString a; 
a.Format("用户按键:%s\r\n",keyname)
鼠标钩子:判断当前鼠标的状态
--------------------------------------------------------------------------------
LRESULT CALLBACK MouseProc(  int nCode,WPARAM wParam, LPARAM lParam
 )
{
 if (HC_ACTION == nCode)
 {
  //打印鼠标操作
  switch (wParam)
  {
  case WM_LBUTTONDOWN:
   {
    ::TRACE("鼠标左键按下\n");
   }
   break;
  case WM_LBUTTONUP:
   {
    ::TRACE("鼠标左键抬起\n");
   }
   break;
  case WM_RBUTTONDOWN:
   {
    ::TRACE("鼠标右键按下\n");
   }
   break;
  case WM_RBUTTONUP:
   {
    ::TRACE("鼠标右键抬起\n");
   }
   break;
  }
 }
 return  CallNextHookEx(g_hMouse,nCode,wParam,lParam);
 
}

------------------------------------------------------------------------------------
全局钩子 dll --idlecounter
统计键盘鼠标空闲的时间。

1.创建一个dll程序。
2。导出最后一个敲击鼠标或者键盘的时间。
--------------------------------------------------
#pragma once

#ifdef IDLE_COUNTER_API 
#else
#define IDLE_COUNTER_API  _declspec(dllimport)
#endif
IDLE_COUNTER_API   BOOL StartIdleCounter();

IDLE_COUNTER_API   void StopIdleCounter();
IDLE_COUNTER_API   int  GetLastTimeclick();

--------------------------------------------------

#ifdef IDLE_COUNTER_API 
#else
#define IDLE_COUNTER_API  _declspec(dllexport)
#endif

HHOOK  g_hmouse;
HHOOK g_hkeyboard;
dword g_nlasttimeclicked;
hmoudle g_hmodule;
Lresult callback mymouseproc(int ncode,wparam,lparam)
{
      if(hc_action == node)
      {
          g_nlasttimeclicked = gettickcount();
      }
     return callnexthookex(g_hmouse,ncode,wparam,lparam);
}

Lresult callback mykeyboardproc(int ncode,wparam,lparam)
{
      if(hc_action == node)
      {
          g_nlasttimeclicked = gettickcount();
      }
     return callnexthookex(g_hkeyboard,ncode,wparam,lparam);
}

IDLE_COUNTER_API   BOOL StartIdleCounter()
{

    //加载全局钩子
    if(!g_hmouse && !g_hkeyboard)
    {
      //获得动态链接库句柄两种方法
       g_hmouse = setwindowshookex(wm_mouse,mymouseproc,
                                      /*g_hmodule*/getmodulehandle(_t("idlecounter"),0));
  g_hkeyboard = setwindowshookex(wm_keyboard,mykeyboardeproc,
                                      /*g_hmodule*/getmodulehandle(_t("idlecounter"),0));

g_nlasttimeclicked = gettickcount();
     }
    return true;
}


IDLE_COUNTER_API   void StopIdleCounter()
{

    //卸载钩子
     unhookwindowsex(g_hmouse);
      unhookwindowsex(g_hkeyboard);
   
}


IDLE_COUNTER_API   int  GetLastTimeclick()
{
    return g_nlasttimeclicked ;
}

-----------------------------------------------------------------

#include "../idlecounter/.h"
startidlecounter();
#pragrma comment(lib,".lib")
int ncount =( gettickcount - getlasttiemclick())/1000;

m_edtidletime.setwindowtext(strvalue);
if(ncount == 5)
{
    //启动屏幕保护或者是其他程序
}

----------------
问题:此程序鼠标在当前程序内滑动,就没问题。当除了程序,就不好使啦。
idlecounter.def
library 'idlecounter'

setions
 idlecounterdata  SHARED 
--------------------------------------
在dll 的头文件中
#pragma data_seg(".idlecounterdata")
HHOOK  g_hmouse;
HHOOK g_hkeyboard;
dword g_nlasttimeclicked;
hmoudle g_hmodule;
#pragma data_seg()
----------------------------------
远程注入


0 0
原创粉丝点击