WIN95中日志钩子(JournalRecord Hook)的使用

原创 2001年05月04日 22:22:00

      钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。在WINDOWS中,日志钩子是个很特别的钩子,它只有全局钩子一种,是键盘鼠标等输入设备的消息在系统消息队列被取出时发生的,而且系统中只能存在一个这样的日志钩子,更重要是,它不必用在动态链接库中,这样可以省却了为安装一个全局钩子而建立一个动态链接库的麻烦。利用日志钩子,我们可以监视各种输入事件,下面的示例可以用来记录键盘的输入,当有按键发生时,自动记录按键动作的日期和时间以及当前激活的窗口名称。本示例在中文WIN98,Borland C++ Builder4中编译通过。

---- 1.新建一个工程,在窗体Form1中放置两个按钮Button1和Button2, CAPTION分别 为“安装日志钩子”和“卸载日志钩子”。

---- 2. 定义如下全局变量:

HHOOK g_hLogHook=NULL;     //钩子变量
HWND g_hLastFocus=NULL;     
//记录上一次得到焦点的窗口句柄
const int KeyPressMask=0x80000000;  //键盘掩码常量
char g_PrvChar;      //保存上一次按键值

3.在Button1的OnClick事件中输入:

void __fastcall TForm1::Button1Click(TObject *Sender)
 {
  if  (g_hLogHook==NULL)
   g_hLogHook = SetWindowsHookEx
(WH_JOURNALRECORD,
        (HOOKPROC)JournalLogProc,
HInstance,0);  //安装日志钩子
 }

4.在Button2的OnClick事件中输入:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
 if (g_hLogHook!=NULL)
  {UnhookWindowsHookEx(g_hLogHook);
   g_hLogHook=NULL;
  }  //卸载日志钩子
}

5.输入钩子回调函数:
HOOKPROC JournalLogProc(int iCode, 
WPARAM wParam, LPARAM lParam)
{
 if (iCode<0) return (HOOKPROC)CallNextHookEx (g_hLogHook,iCode,wParam,lParam); if (iCode="=HC_ACTION)" {EVENTMSG *pEvt="(EVENTMSG" *)lParam; int i; HWND hFocus; //保存当前活动窗口句柄 char szTitle[256]; //当前窗口名称 char szTime[128]; //保存当前的日期和时间 FILE *stream="fopen(“c://logfile.txt”,"a+t");" if (pEvt->message==WM_KEYDOWN)     
    {int vKey=LOBYTE(pEvt- >paramL);    // 取得虚拟键值
     char ch;
     char str[10];
     hFocus=GetActiveWindow();     
  //取得当前活动窗口句柄
     if(g_hLastFocus!=hFocus)     
  //当前活动窗口是否改变
      {GetWindowText(hFocus,szTitle,256);
       g_hLastFocus=hFocus;
       strcpy(szTime,DateTimeToStr(Now())
.c_str());  //得到当前的日期时间
       fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle);  //写入文件
       fprintf(stream,"%c%c",32,32);  
      }
     int iShift=GetKeyState(0x10);  
//测试SHIFT,CAPTION,NUMLOCK等键是否按下
     int iCapital=GetKeyState(0x14);
     int iNumLock=GetKeyState(0x90);
     bool bShift=(iShift & KeyPressMask)==KeyPressMask;   
     bool bCapital=(iCapital & 1)==1;
     bool bNumLock=(iNumLock & 1)==1;
     if (vKey >=48 && vKey<=57) // 数字0-9 if (!bShift) fprintf(stream,"%c",vKey); if (vKey>=65 && vKey<=90) // A-Z a-z {if (!bCapital) if (bShift) ch="vKey;" else ch="vKey+32;" else if (bShift) ch="vKey+32;" else ch="vKey;" fprintf(stream,"%c",ch); } if (vKey>=96 && vKey<=105) // 小键盘0-9 if (bNumLock) fprintf(stream,"%c",vKey-96+48); if (vKey>=186 && vKey<=222) // 其他键 {switch (vKey) {case 186:if (!bShift) ch=";" ; else ch=":" ;break; case 187:if (!bShift) ch="=" ; else ch="+" ;break; case 188:if (!bShift) ch="," ; else ch="<" ;break; case 189:if (!bShift) ch="-" ; else ch="_" ;break; case 190:if (!bShift) ch="." ; else ch=" >" ;break; case 191:if (!bShift) ch="/" ; else ch="?" ;break; case 192:if (!bShift) ch="`" ; else ch="~" ;break; case 219:if (!bShift) ch="[" ; else ch="{" ;break; case 220:if (!bShift) ch="//" ; else ch="|" ;break; case 221:if (!bShift) ch="]" ; else ch="}" ;break; case 222:if (!bShift) ch="/" '; else ch="/"" ;break; default:ch="n" ;break; } if (ch!="n" ) fprintf(stream,"%c",ch); } // if (wParam>=112 && wParam<=123) // 功能键 [F1]-[F12] if (vKey>=8 && vKey<=46) //方向键 {switch (vKey) {case 8:strcpy(str,"[BK]");break; case 9:strcpy(str,"[TAB]");break; case 13:strcpy(str,"[EN]");break; case 32:strcpy(str,"[SP]");break; case 33:strcpy(str,"[PU]");break; case 34:strcpy(str,"[PD]");break; case 35:strcpy(str,"[END]");break; case 36:strcpy(str,"[HOME]");break; case 37:strcpy(str,"[LF]");break; case 38:strcpy(str,"[UF]");break; case 39:strcpy(str,"[RF]");break; case 40:strcpy(str,"[DF]");break; case 45:strcpy(str,"[INS]");break; case 46:strcpy(str,"[DEL]");break; default:ch="n" ;break; } if (ch!="n" ) {if (g_PrvChar!="vKey)" {fprintf(stream,"%s",str); g_PrvChar="vKey;" } } } } if (pEvt->message==WM_LBUTTONDOWN || pEvt- >message
==WM_RBUTTONDOWN)
      {hFocus=GetActiveWindow();
       if (g_hLastFocus!=hFocus)
        {g_hLastFocus=hFocus;
         GetWindowText(hFocus,szTitle,256);       
     strcpy(szTime,DateTimeToStr(Now()).c_str());  
//得到当前的日期时间
     fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle);  //写入文件
     fprintf(stream,"%c%c",32,32);  
        }
      }
 fclose(stream);
 return (HOOKPROC)CallNextHookEx
(g_hLogHook,iCode,wParam,lParam);
}

---- 将工程编译执行后,每当激活一个窗口时,就会把当前窗口名称写入文件c:/logfile.txt中,当有按键时,按键的名称也会写入此文件中,这里的并没有处理全部的按键,读者可根据需要添加相应的语句。要捕捉键盘的按键动作,用键盘钩子(Keyboard Hook)也同样可以实现,但是用日志钩子却比键盘钩子要方便许多。首先,如果要捕捉其他应用程序的按键,即做成全局钩子,键盘钩子一定要单独放在动态链接库中,而日志钩子却不必;其次,在键盘钩子函数得到的键盘按键之前,系统已经处理过这些输入了,如果系统把这些按键屏蔽掉,键盘钩子就无法检测到它们,例如,当输入屏幕保护程序密码时,键盘钩子无法检测到用户输入了那些字符,而日志钩子却可以检测到。

---- 无论是哪种钩子, 都会增加系统处理消息的时间,从而降低系统的性能,我们只有在必要的时候才安装这些钩子,而且尽可能在不需要时移走它们。

利用TortoiseSVN钩子脚本,自动填写/导入日志信息

使用TortoiseSVN提交时,每次都填写日志信息比较繁琐。Subversion命令行客户端可以通过选项“--file”(“-F”)从文件载入日志信息。TSVN虽然可以很方便的选择历史消息,但是当前...
  • CaiKanXP
  • CaiKanXP
  • 2011年02月23日 17:30
  • 9004

CI框架源码阅读笔记6 扩展钩子 Hook.php

CI框架允许你在不修改系统核心代码的基础上添加或者更改系统的核心功能(如重写缓存、输出等)。例如,在系统开启hook的条件下(config.php中$config['enable_hooks'] = ...
  • ohmygirl
  • ohmygirl
  • 2014年11月09日 14:33
  • 6980

thinkphp 钩子的简单实现和总结

首先,钩子(Hook)是thinkphp中的一种扩展,我们可以将钩子插入框架中的任意位置来执行特定的行为(Behavior)。(按照我个人的拙见,钩子相当于在控制器里面内嵌了一个控制器,但两个控制器的...
  • laughing2333
  • laughing2333
  • 2015年09月23日 18:05
  • 3136

(插件设计与简单应用)php中钩子(hook)的应用示例demo

我们先来回顾下原本的开发流程; 产品汪搞出了一堆需求; 当用户注册成功后需要发送短信、发送邮件等等; 然后聪明机智勇敢的程序猿们就一扑而上; 把这些需求转换成代码扔在 用户注册成功 和 跳转到...
  • u014263216
  • u014263216
  • 2016年11月22日 15:29
  • 818

HOOK钩子机制

最近在看一些编程相关的书籍和资料,知识碰见了,就想把它记下来,以便日后能用的上,也可能只是浅显的概念!可能有错,但是有值得参考的地方,慢慢充电吧! 一、理解:钩子,顾名思义就是钩东西的,...
  • gogoky
  • gogoky
  • 2016年05月03日 20:44
  • 1859

控制台程序安装全局钩子

   今天在写一个程序的时候发现的问题,在以前的学习过程中没有遇到过,所以记录以备后查程序大致是这样的 A:主程序 控制台程序 负责安装一个WH_KEYBOARD_LL钩子,其中钩子的安装于回调函数在...
  • cmdhack
  • cmdhack
  • 2011年01月12日 19:15
  • 2560

vc 局部钩子HOOK(线程钩子)

HHOOK SetWindowsHookEx(   int idHook,        // type of hook to install  即钩子类型   HOOKPROC lpfn,   ...
  • u013678464
  • u013678464
  • 2014年05月24日 03:44
  • 1236

[转]PHP hook钩子类

不多说什么,用于做插件,消息监听之类的东西,反正用处挺大的,不清楚的请移步看看百科知识。   当然,代码之后只有使用的测试,而没有删除的测试,各种问题自行解决吧,还有功能不强,理论上应该可以设置...
  • u011250882
  • u011250882
  • 2015年07月06日 21:33
  • 2281

HOOK钩子 指定程序

HOOK的应用一般有3个: (1)本程序内的钩子(一般用处不大) (2)全局钩子 (3)其他任意指定线程的钩子 由于最近要做一个关于针对指定应用程序的劫持,在网上看了很多资料,大部分是讲全局钩子的。针...
  • zhengspace1
  • zhengspace1
  • 2015年01月23日 16:21
  • 1526

QT实现鼠标钩子

HHOOK mouseHook=NULL; LRESULT CALLBACK mouseProc(int nCode,WPARAM wParam,LPARAM lParam ) { if(nC...
  • qq_34389528
  • qq_34389528
  • 2017年07月28日 22:17
  • 288
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WIN95中日志钩子(JournalRecord Hook)的使用
举报原因:
原因补充:

(最多只允许输入30个字)