日志钩子(JournalRecord Hook)的使用

-- 钩子是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)也同样可以实现,但是用日志钩子却比键盘钩子要方便许多。首先,如果要捕捉其他应用程序的按键,即做成全局钩子,键盘钩子一定要单独放在动态链接库中,而日志钩子却不必;其次,在键盘钩子函数得到的键盘按键之前,系统已经处理过这些输入了,如果系统把这些按键屏蔽掉,键盘钩子就无法检测到它们,例如,当输入屏幕保护程序密码时,键盘钩子无法检测到用户输入了那些字符,而日志钩子却可以检测到。

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

转载于:https://www.cnblogs.com/henryzc/archive/2005/10/27/262990.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优先队列

CSTL——优先队列 一、相关定义 优先队列容器与队列一样&#xff0c;只能从队尾插入元素&#xff0c;从队首删除元素。但是它有一个特性&#xff0c;就是队列中最大的元素总是位于队首&#xff0c;所以出队时&#xff0c;并非按照先进先出的原则进行&#xff0c;而是将当前队列…

linux命令行抓取网页快照-(xvfb+CutyCapt)

linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;又一个 WordPress 博客Browse: Home / 2009 / 十一月 / linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;By saymoon on 2009年11月…

php过waf木马,一款过waf的一句话木马分析 | CN-SEC 中文网

摘要中午&#xff0c;下班回来&#xff0c;就看一个朋友给我发了几个马儿 让我看看解解密码 很简单中午&#xff0c;下班回来&#xff0c;就看一个朋友给我发了几个马儿 让我看看解解密码 很简单猛不猛我不知道 那时候手机 太长的看着就烦 就回到家瞅瞅了首先我们看这…

你没干什么坏事,你怕什么?

如图我很久就知道深信服这家企业&#xff0c;记得是几年前&#xff0c;我有一个同学跟我说&#xff0c;有一个比较厉害的朋友在这个企业上班&#xff0c;拿到了非常不错的薪水&#xff0c;我如果想去这个公司看看&#xff0c;可以让这位朋友帮忙搭线。后面查这个企业&#xff0…

C++中的explicit关键字用法

c中的explicit关键字用来修饰类的构造函数&#xff0c;被修饰的类的构造函数不能进行隐式类型的转换&#xff0c;既然有"显式"那么必然就有"隐式"&#xff0c;那么什么是显示而什么又是隐式的呢&#xff1f; 如果c类的构造函数有一个参数&#xff0c;那么…

警告用户:VoIP电话存在诸多风险

IP电话是目前最为受欢迎的通信方式&#xff0c;但最近VoIP安全组织表示其拥有许多安全隐患。 该组织发布了一份IP电话供应商潜在的安全风险清单。旧式的公共开关网络电话&#xff08;PSTN&#xff09;并没有远离风险&#xff0c;而今VoIP也要加入这一风险行列。 秘密被偷听&…

织梦文章添加字段填栏目id,内容页调用字段里的栏目文章

在模型里增加个字段&#xff0c;然后在添加文章的时候&#xff0c;在字段里填了栏目id进去 在前台的内容页&#xff0c;调用这个字段栏目的多个文章出来 {dede:field.field1 runphpyes} global $dsql; $sql "select arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault…

python用循环打出阶梯图形,matplotlib阶梯图的实现(step())

step函数概述step函数用于绘制阶梯图。根据源码可知&#xff0c;step函数是对plot函数的轻量级封装&#xff0c;很多概念和用法与plot函数非常相似。def step(self, x, y, *args, wherepre, dataNone, **kwargs):cbook._check_in_list((pre, post, mid), wherewhere)kwargs[dra…

xbmc addons

XBMC新版“扩展功能”简介 目录1. 扩展功能模块结构2. 图片文件指引 2.1 icon.png2.2 fanart.jpg3. addon.xml 3.1 <addon>元素3.2 <requires>元素3.3 <extension>元素3.4 xbmc.addon.metadata extension4. extension类别本贴介绍将在即将发布的XBMC Dharma&…

嵌入式还有哪些风口值得入?

大家好&#xff0c;我是写代码的篮球球痴前两天发了篇文章说到嵌入式薪资的&#xff0c;很多人想知道目前有哪些不错的行业可以加入&#xff0c;这篇文章罗列了很多风口行业。我相信&#xff0c;半导体芯片会是很重要的方向&#xff0c;但是不管路修得多好&#xff0c;都需要汽…

两个学习指针的例子

下面的结果是多少&#xff1f; int a5; int *example1(int b) { ab; return &a; } int *example2(int b) { int c5; bc; return &b; } void main() { int *a1example1(10); int *b1example2(10); cout <<”a1”<<*a1; cout <<”b1”<&l…

java 统计单词个数和标点符号

把随机输入的一句话比如:Its only a test!存放在一个char[]的数组中&#xff0c;统计char[]中的单词个数和标点符号的个数。 package com.faintbear; import java.io.*; publicclassTest{ public static void main(String[] args) throws Exception{ BufferedReade…

Luogu 4244 [SHOI2008]仙人掌图

BZOJ 1023 如果我们把所有的环都缩成一个点&#xff0c;那么整张图就变成了一棵树&#xff0c;我们可以直接$dp$算出树的直径。 设$f_x$表示$x$的子树中最长链的长度&#xff0c;那么对于$x$的每一个儿子$y$&#xff0c;先用$f_x f_y 1$更新答案&#xff0c;再用$f_y 1$更新…

trim的返回值php,php trim()函数

(1)trim()函数。该函数可以去除字符串开始位置以及结束位置的空格&#xff0c;并返回去掉空格后的字符串。该函数声明如下&#xff1a;string trim ( string str [, string charlist])默认的情况下&#xff0c;该函数去除的字符如下。" " (ASCII 32 码为(0x20))&…

outlook 2007 自动答复邮件

outlook 2007自动答复邮件 步骤 1&#xff1a;创建邮件模板 提示 从 Microsoft Office Online 下载正式&#xff08;英文&#xff09;或者非正式&#xff08;英文&#xff09;外出邮件模板。 在“文件”菜单上&#xff0c;指向“新建”&#xff0c;然后单击“邮件”。在“选项…

我的朋友去国外出差回不来了

年前&#xff0c;我一个朋友因为项目调试需要去国外出差&#xff0c;出国的时候好好的&#xff0c;然后飞到当地没几天疫情突然爆发&#xff0c;国内取消了那个国家的航班&#xff0c;然后就直接滞留在当地回不来了。我朋友从事的是硬件开发&#xff0c;包括器件选型、原理图设…

再谈borland与MS对BUG的不同态度~

在讨论Delphi 6 SP1对BUG的修补问题时(http://www.delphibbs.com/delphibbs/dispq.asp?lid648516)&#xff0c;我提及“强烈建议Borland针对自己的产品出hotfix&#xff0c;而不是让大家非得等到Server Pack”&#xff0c;随后与y9y兄讨论到Borland和MS的不同态度。或者我们可…

JDBCUtils

1 package database;2 3 import java.sql.Connection;4 import java.sql.DriverManager;5 import java.sql.ResultSet;6 import java.sql.SQLException;7 import java.sql.Statement;8 9 /** 10 * <p> 11 * Description:JDBCUtils工具类 12 * </p> 13 * 14 *…

oracle 11g 组合分区,Oracle数据库

数据库分区是每种数据库都需具备的关键功能之一。几乎所有的Oracle数据库都使用分区功能来提高查询的性能&#xff0c;Oracle 11g分区功能可以简化数据库的日常管理维护工作&#xff0c;大大减轻了DBA(数据库设计和管理工程师)的工作负担。分区是探索数据仓库技术选项之一&…

实现购物车的原理

购物车的功能包括以下几项&#xff1a; n 把商品添加到购物车&#xff0c;即订购 n 删除购物车中已定购的商品 n 修改购物车中某一本图书的订购数量 n 清空购物车 n 显示购物车中商品清单及数量、价格 实现购物车的关键在于服务器识别…