zoukankan      html  css  js  c++  java
  • python 钩子函数

    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()
    
  • 相关阅读:
    Ubuntu18.04连不上网的解决办法
    springboot 踩雷 invalid bound statement (not found): com.atguigu.springboot.mapper.employeemapper.getempbyid
    IDEA的pom文件总是出现Failed to read artifact descriptor forXXX:jar:unknow的解决方法
    IDEA快捷键记录
    在ubuntu18.04中使用chorme浏览器,发现鼠标向下滑动速度真的很慢!更改鼠标滚动速度解决!!
    使用docker拉取镜像时,一直报错get https://registry-1.docker.io/v2/: net/http: tls handshake timeout
    启动django服务器访问admin站点时,django服务器自动关闭的问题解决方案。
    mathtype 6.9 setup cannot continue as an installation of mathtype 7 has be detected。彻底删除MathType的方法。
    转载:Microsoft Office 365激活,一键激活,无需登录Microsoft账号,无需下载KMS等激活工具,cmd命令激活。
    SpringBoot快速开发01
  • 原文地址:https://www.cnblogs.com/megachen/p/9833393.html
Copyright © 2011-2022 走看看