pyhook的简单使用
实验内容:
通过python编程调用windows的api,编写键盘和鼠标监控的hook,将相关信息保存记录到txt文档中。
实验步骤:
1.Hook技术,pyHook3和pywin32简介
1.1 Hook简介
windows应用程序是基于消息驱动的。各种应用程序对各种消息作出响应从而实现各种功能。
hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。所以说,我们可以在系统中自定义钩子,用来监视系统中特定事件的发生,完成特定功能,如屏幕取词,监视日志,截获键盘、鼠标输入等等。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。Windows消息带了一些程序有用的信息,比如Mouse类信息,就带有鼠标所在窗体句柄、鼠标位置等信息,拦截了这些消息,就可以利用这些信息做出一些功能
每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程序。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
系统钩子与线程钩子:
SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。
线程钩子用于监视指定线程的事件消息。线程钩子一般在当前线程或者当前线程派生的线程内。
系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL) 中。系统自动将包含“钩子回调函数”的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程。
对于 Hook 技术,可以分为两块,第一块是在 Ring3 层的 Hook,俗称应用层 Hook 技术,另外一块自然是在 Ring0 层得 Hook,俗称为内核层 Hook 技术。
1.2 Hook的windows API
操作系统支持多种类型的钩子,每种类型都提供了它特有的消息处理机制。
对于每种类型的钩子,系统都维护一个各自独立的钩子链,钩子链是一个指向用户提供的回调函数钩子过程的链表指针。
Hook的安装:
HHOOK SetWindowsHookEx{
int idHook,//要安装的钩子的类型
HOOKPPROC lpfn,//钩子过程的指针,拦截到制定系统消息后的预处理过程
HINSTANCE hMod,//应用程序实例的句柄,如果是全局钩子,hInstance是DLL句柄(DllMain中给的模块地址。就是包含HookProc的动态库加载地址。否则给0就可以了,即勾自己。 )
DWORD dwThreadId //要安装钩子的线程id,指定被监视的线程,如果明确指定了某个线程的id就只监视该线程,此时的钩子为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子
}
返回值:若此函数执行成功,则返回值就是该挂钩处理过程的句柄;若此函数执行失败,则返回值为NULL(0).
Hook过程:
LRESULT CALLBACK HookProc{ //
int nCode, //该参数是一个钩子标识码,钩子过程会利用它决定下一步的进行的操作。这个标识嘛的值与安装的钩子类型相关
WPARAM wParam,//后面两个参数的定义都依赖于nCode参数,一般用于存放于窗口消息相关的内容
LPARAM lParam}
LRESULT 就是long型,是Windows API的一种返回类型;CALLBACK表示这个函数是给系统调用的,实际上CALLBACK就是__stdcall(回调函数)。HookProc指代自定义的函数。
Hook卸载:
BOOL WINAPI UnhookWindowsHookEx( __in HHOOK hhk);
HHOOK要删除的钩子的句柄。这个参数是函数SetWindowsHookEx的返回值。返回值类型: BOOL,如果函数成功,返回值为非零值。如果函数失败,返回值为零。 要获得更多的错误信息,调用GetLastError函数.
Hook信息传递:
CallNextHookEx是一种函数,可以将钩子信息传递到当前钩子链中的下一个子程,一个钩子程序可以调用这个函数之前或之后处理钩子信息。
LRESULT WINAPI CallNextHookEx( _In_opt_ HHOOK hhk, _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam);
Hook类型:
有很多,举两个例子:
WH_KEYBOARD //当敲击键盘时将触发此钩子
WH_MOUSE //当有鼠标操作时将触发此钩子
1.3 pyHook3与pywin32简介
Pywin32:一个开源的python项目,该模块包含了几乎所有的windows API,供调用。https://github.com/mhammond/pywin32。封装方式是从windows的DLL中按类提取了API函数放在不同位置,比如process进程类API放在win32process模块。
PyHook3:依赖于Pywin32,用于捕捉特定的Windows事件,封装了所有底层调用(比如对SetWindowsHookEx(),UnhookWindowsHookEx(),等函数封装),我们只需要关注程序逻辑。提供键盘和鼠标的Hook。
2.安装pyHook3和pywin32(pycom)
需要注意pyHook和pywin32与python版本的对应。
2.1 查看python版本
Python 3.7,AMD64
2.2 pyHook3安装
pyHook官方只支持python2,所以安装pyhook3
Conda install swig
Pip install pyhook3
2.3 Pycom安装:
Pycom即pywin32
https://github.com/mhammond/pywin32/releases
2.4 查看是否安装成功:
Conda list
安装成功
3.利用Hook实现键盘监控与鼠标监控
3.1 思路:
没有Hook时:
键盘输入--> 系统消息队列 --> 对应应用程序的消息队列 --> 将消息发送到对应的窗口中
添加Hook后:
键盘输入 --> 系统消息队列 --> 对应应用程序消息队列 --> 将消息发送到钩子链中 --> 消息一一调用完毕所有的钩子函数(需要调用CallNextHookEx函数才能将消息传递下去) --> 将消息发送到对应的窗口中
添加两个Hook函数分别对应键盘和鼠标。在Hook函数接收到信息后保存到txt中,完成监控,然后把信息传给目标程序。
3.2 代码实现
思路:
添加一个键盘hook,会获取到键盘信息。Hook函数功能为将信息转化为string后写入txt文档,然后将信息继续传递给目标窗口。
有用的信息为Time 事件时间,MessageName事件名称,WindowName事件所在窗口名,Ascii事件ASCII码,KEY 事件KEY,Scancode扫描码,Alt控制信息。
添加一个鼠标Hook,获取鼠标信息,功能类似于键盘Hook。
有用的信息为Time 事件时间,MessageName事件名称,WindowName事件所在窗口名,Position鼠标所在坐标位置,Wheel鼠标滚轮的信息。
在键盘Hook的函数中判断键盘输入是否为Q,为Q时quit。
存入的文档设置为F://records.txt。
实验结果记录:
1.code:
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 25 11:33:41 2019
@author: erio
"""
#USB 接口的键盘鼠标
import pythoncom
import PyHook3 as pyHook
import win32api
import time path = 'F://records.txt' def onMouseEvent(event):
with open(path, 'a+') as f:
f.write("-----Mouse Event Start-----\n")
# 监听鼠标事件
print ("MessageName:", event.MessageName)
print ("WindowName:", event.WindowName)
print ("Position:", event.Position)
print ("Wheel:", event.Wheel)
print ("---")
# 返回 True 以便将事件传给其它处理程序
# 注意,这儿如果返回 False ,则鼠标事件将被全部拦截
t = time.localtime()
t = time.asctime(t)
result = "Time : " + t + "\n" + "MessageName: "+ str(event.MessageName)+'\n'+"WindowName: " + str(event.WindowName) + \
"\n" +"Position: "+str(event.Position)+'\n'+"Wheel: " +str(event.Wheel)+'\n'
f.write(result)
f.write("-----Mouse Event End-----\n\n\n")
f.close()
return True def onKeyboardEvent(event):
with open(path, 'a+') as f:
# 监听键盘事件
f.write("-----KeyBoard Event Start-----\n")
print ("MessageName:", event.MessageName)
print ("WindowName:", event.WindowName)
print ("Ascii:", event.Ascii, chr(event.Ascii))
print ("Key:", event.Key)
print ("ScanCode:", event.ScanCode)
print ("Alt", event.Alt)
print ("---")
t=time.localtime()
t=time.asctime(t)
result ="Time : " + t + "\n" +"MessageName: "+ str(event.MessageName)+'\n'+"WindowName: " + str(event.WindowName) + " \n" +\
"Ascii: "+str(event.Ascii)+ ' '+chr(event.Ascii)+'\n'+"Key: " + str( event.Key) + "\n" +"ScanCode: "+str(event.ScanCode)+"\n"+\
"Alt: "+str(event.Alt)+'\n'
f.write(result)
f.write("-----KeyBoard Event End-----\n\n\n")
f.close()
if event.Key== 'Q': # 按下F12后终止adsw
win32api.PostQuitMessage()
return True def main():
# 创建一个“钩子”管理对象aaavv q
hm = pyHook.HookManager()
# 监听所有键盘事件
hm.KeyDown = onKeyboardEvent
# 设置键盘“钩子”
hm.HookKeyboard()
# 监听所有鼠标事件
hm.MouseAll = onMouseEvent
# 设置鼠标“钩子”
hm.HookMouse()
# 进入循环,如不手动关闭,程序将一直处于监听状态
pythoncom.PumpMessages() if __name__ == "__main__":
main()
2.records.txt文档展示
实际随机操作后记录在records.txt中。由于记录较长(13kb),截取部分展示。
键盘信息记录:包含普通按键和Alt
信息为Time 事件时间,MessageName事件名称,WindowName事件所在窗口名,Ascii事件ASCII码,KEY 事件KEY,Scancode扫描码,Alt控制信息。
-----KeyBoard Event Start-----
Time : Wed Dec 25 17:19:28 2019
MessageName: key down
WindowName: Pyhook [D:\Pyhook] - ...\records.py [Pyhook] - PyCharm
Ascii: 13
Key: Return
ScanCode: 28
Alt: 0
-----KeyBoard Event End-----
-----KeyBoard Event Start-----
Time : Wed Dec 25 17:19:32 2019
MessageName: key sys down
WindowName: Pyhook [D:\Pyhook] - ...\records.py [Pyhook] - PyCharm
Ascii: 0
Key: Lmenu
ScanCode: 56
Alt: 32
-----KeyBoard Event End-----
-----KeyBoard Event Start-----
Time : Wed Dec 25 17:19:34 2019
MessageName: key sys down
WindowName: Pyhook [D:\Pyhook] - ...\records.py [Pyhook] - PyCharm
Ascii: 0
Key: Lmenu
ScanCode: 56
Alt: 32
-----KeyBoard Event End-----
-----KeyBoard Event Start-----
Time : Wed Dec 25 17:19:34 2019
MessageName: key sys down
WindowName: Pyhook [D:\Pyhook] - ...\records.py [Pyhook] - PyCharm
Ascii: 0
Key: Numpad2
ScanCode: 80
Alt: 32
-----KeyBoard Event End-----
鼠标信息记录:包含移动和按下左键
信息为Time 事件时间,MessageName事件名称,WindowName事件所在窗口名,Position鼠标所在坐标位置,Wheel鼠标滚轮的信息。
-----Mouse Event Start-----
Time : Wed Dec 25 17:19:42 2019
MessageName: mouse move
WindowName: None
Position: (997, 458)
Wheel: 0
-----Mouse Event End-----
-----Mouse Event Start-----
Time : Wed Dec 25 17:19:42 2019
MessageName: mouse move
WindowName: None
Position: (995, 458)
Wheel: 0
-----Mouse Event End-----
-----Mouse Event Start-----
Time : Wed Dec 25 17:19:42 2019
MessageName: mouse left down
WindowName: None
Position: (995, 458)
Wheel: 0
-----Mouse Event End-----
-----Mouse Event Start-----
Time : Wed Dec 25 17:19:42 2019
MessageName: mouse left up
WindowName: Pyhook [D:\Pyhook] - ...\records.py [Pyhook] - PyCharm
Position: (995, 458)
Wheel: 0
-----Mouse Event End-----
pyhook的简单使用的更多相关文章
- 在win64位,python64位2.7版本中安装pyHook
今天看了一篇博文说的是利用pyhook监听键盘鼠标事件(感兴趣的可以看博客园中相关文章),文章中使用的pyHook模块的官方下载地址是:http://sourceforge.net/projects/ ...
- 【pyHook】 监测键盘鼠标事件等
[pyHook] pyHook是一个用来进行键盘.鼠标等层面事件监控的库.这个库的正常工作需要pythoncom等操作系统的API的支持.首先来说说如何安装. 直接pip install pyHook ...
- Python——pyHook监听鼠标键盘事件
pyHook包为Windows中的全局鼠标和键盘事件提供回调. 底层C库报告的信息包括事件的时间,事件发生的窗口名称,事件的值,任何键盘修饰符等. 而正常工作需要pythoncom等操作系统的API的 ...
- 利用Python的pyHook包来进行键盘监听
最近在实习的时候发现一件很蛋疼的事情,那就是我们组的项目因为有后台进程,所有每次运行完以后后台进程都必须要自己手动关闭,每次编译之前忘记关就会有一大堆编译错误,我就想直接弄个可以快捷键直接关闭算了 ...
- python 监视和控制鼠标键盘的输入(使用pynput 而非pyhook)
百度上搜到的文章大多基于pyhook, pip不能直接安装,托管在sourceForge上的代码仓库也找不到. google上发现可以使用pynput,貌似控制更为简单,而且可以直接使用pip安装 示 ...
- Python常用的库简单介绍一下
Python常用的库简单介绍一下fuzzywuzzy ,字符串模糊匹配. esmre ,正则表达式的加速器. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable ...
- 【造轮子】打造一个简单的万能Excel读写工具
大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...
- Fabio 安装和简单使用
Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
随机推荐
- SVM 支持向量机算法-原理篇
公号:码农充电站pro 主页:https://codeshellme.github.io 本篇来介绍SVM 算法,它的英文全称是 Support Vector Machine,中文翻译为支持向量机. ...
- eCATT使用前的配置
如果想在SAP中使用eCATT,必须做一下相关的配置才行,下面简单介绍这几步:1.SM30,输入表T000,然后点击维护,或者是进入事物SCC4,进入对应的clint属性编辑视图下,将CATT and ...
- STM32F207时钟系统解析
在前几天的文章<晶振原理解析>中介绍了晶振如何产生时钟的,板子使用的是25M无源晶振,下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的. 01.时钟系 ...
- PKU2186 Popular Cows 受欢迎的牛
题目描述 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N(N<=10000)头牛,给你M(M<=50000)对整数(A,B),表示牛A认为牛B受欢迎.这种关系是具有传递性的,如果A认为B ...
- [Usaco2007 Dec]宝石手镯
题目描述 贝茜在珠宝店闲逛时,买到了一个中意的手镯.很自然地,她想从她收集的 N(1 <= N <= 3,402)块宝石中选出最好的那些镶在手镯上.对于第i块宝石,它的重量为W_i(1 & ...
- Python+Selenium+Unittest实现PO模式web自动化框架(4)
1.PageLocators目录下的具体模块 2.PageLocators目录下主要放置个页面的元素定位.用于统一管理个页面的定位元素. 例如:登录页面的元素定位login_page_locator. ...
- LinuxCentos7下安装Mysql8.x以及密码修改
LinuxCentos7下安装Mysql以及密码修改 引言: 之前都是用Docker或者yum自动安装,这次主要是下载压缩包解压安装,中间也有些小波折,记录如下,以供参考: 1.删除旧的MySQL 检 ...
- vue项目中如何引用tinymce
最近公司在做一个CMS系统的项目,其中富文本编辑框用的很多,目前流行的也很多,包括wangEditor.TinyMCE.百度ueditor.kindeditor.CKEditor等.经过自己的一番翻箱 ...
- Lambda 表达式 学习
最近几天在学习Lambda,给我的理解就是一个匿名函数的升级版,代码极大可能的简洁了很多,不需要像以前一样必须使用众多的代码才能实现相关功能. 慢慢积累学习,将Java 8的相关知识进行一个学习. 用 ...
- Spark日志,及设置日志输出级别
Spark日志,及设置日志输出级别 1.全局应用设置 2.局部应用设置日志输出级别 3.Spark log4j.properties配置详解与实例(摘录于铭霏的记事本) 文章内容来源: 作者:大葱拌豆 ...