LyScript实现Hook改写MessageBox的方法详解
作者:lyshark 发布时间:2023-01-07 03:35:16
标签:LyScript,Hook,MessageBox
LyScript 可实现自定义汇编指令的替换功能,用户可以自行编写一段汇编指令,将程序 * 定的通用函数进行功能改写与转向操作,此功能原理是简单的Hook操作。
首先我们先来实现一个Hook模板,在代码中实现中转机制,如下代码以MessageBoxA
函数为案例实现修改汇编参数传递。
from LyScript32 import MyDebug
# 传入汇编列表,写出到内存
def assemble(dbg, address=0, asm_list=[]):
asm_len_count = 0
for index in range(0,len(asm_list)):
# 写出到内存
dbg.assemble_at(address, asm_list[index])
# print("地址: {} --> 长度计数器: {} --> 写出: {}".format(hex(address + asm_len_count), asm_len_count,asm_list[index]))
# 得到asm长度
asm_len_count = dbg.assemble_code_size(asm_list[index])
# 地址每次递增
address = address + asm_len_count
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("连接状态: {}".format(connect_flag))
# 找到MessageBoxA
messagebox_address = dbg.get_module_from_function("user32.dll","MessageBoxA")
print("MessageBoxA内存地址 = {}".format(hex(messagebox_address)))
# 分配空间
HookMem = dbg.create_alloc(1024)
print("自定义内存空间: {}".format(hex(HookMem)))
# 写出FindWindowA内存地址,跳转地址
asm = [
f"push {hex(HookMem)}",
"ret"
]
# 将列表中的汇编指令写出到内存
assemble(dbg,messagebox_address,asm)
dbg.close()
上方代码中可以看到,首先获取到MessageBoxA
函数内存地址,然后我们通过dbg.create_alloc(1024)
分配一段空间,并利用assemble()
函数写出一个跳转指令。
此段代码执行后,MessageBoxA
处的指令将被替换,跳转到我们自己分配的内存中去。
接着我们就来实现功能改写,将弹窗中的消息替换成我们自己的版权信息,此处先给出代码。
from LyScript32 import MyDebug
# 传入汇编列表,写出到内存
def assemble(dbg, address=0, asm_list=[]):
asm_len_count = 0
for index in range(0,len(asm_list)):
# 写出到内存
dbg.assemble_at(address, asm_list[index])
# print("地址: {} --> 长度计数器: {} --> 写出: {}".format(hex(address + asm_len_count), asm_len_count,asm_list[index]))
# 得到asm长度
asm_len_count = dbg.assemble_code_size(asm_list[index])
# 地址每次递增
address = address + asm_len_count
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("连接状态: {}".format(connect_flag))
# 找到MessageBoxA
messagebox_address = dbg.get_module_from_function("user32.dll","MessageBoxA")
print("MessageBoxA内存地址 = {}".format(hex(messagebox_address)))
# 分配空间
HookMem = dbg.create_alloc(1024)
print("自定义内存空间: {}".format(hex(HookMem)))
# 写出FindWindowA内存地址,跳转地址
asm = [
f"push {hex(HookMem)}",
"ret"
]
# 将列表中的汇编指令写出到内存
assemble(dbg,messagebox_address,asm)
# 定义两个变量,存放字符串
MsgBoxAddr = dbg.create_alloc(512)
MsgTextAddr = dbg.create_alloc(512)
# 填充字符串内容
# lyshark 标题
txt = [0x6c, 0x79, 0x73, 0x68, 0x61, 0x72, 0x6b]
# 内容 lyshark.com
box = [0x6C, 0x79, 0x73, 0x68, 0x61, 0x72, 0x6B, 0x2E, 0x63, 0x6F, 0x6D]
for txt_count in range(0,len(txt)):
dbg.write_memory_byte(MsgBoxAddr + txt_count, txt[txt_count])
for box_count in range(0,len(box)):
dbg.write_memory_byte(MsgTextAddr + box_count, box[box_count])
print("标题地址: {} 内容: {}".format(hex(MsgBoxAddr),hex(MsgTextAddr)))
# 此处是MessageBox替换后的片段
PatchCode =\
[
"mov edi, edi",
"push ebp",
"mov ebp,esp",
"push -1",
"push 0",
"push dword ptr ss:[ebp+0x14]",
f"push {hex(MsgBoxAddr)}",
f"push {hex(MsgTextAddr)}",
"push dword ptr ss:[ebp+0x8]",
"call 0x76030E20",
"pop ebp",
"ret 0x10"
]
# 写出到自定义内存
assemble(dbg, HookMem, PatchCode)
print("地址已被替换,可以运行了.")
dbg.set_debug("Run")
dbg.set_debug("Run")
dbg.close()
首先程序运行后,会经过assemble(dbg,messagebox_address,asm)
汇编写出的位置,此处是一个跳转,直接跳转到我们自己申请的内存空间内。
当EIP走到此处后,跳转到我们自己构建的弹窗位置,此处的代码如下。
当弹窗运行后,读入的内存地址有两处MsgBoxAddr
是消息MsgTextAddr
是文本,这两处位置都被python中的push {hex()}
替换掉了,当运行弹窗后,就是执行我们自己的函数。
来源:https://www.cnblogs.com/LyShark/p/16684396.html


猜你喜欢
- 本文实例讲述了Python实现pdf文档转txt的方法。分享给大家供大家参考,具体如下:首先,这是一个比较粗糙的版本,因为已经够用了,而且对
- 今天晚上小编在加班时有朋友咨询关于SQL Server 2005 更改安装路径目录的问题,告诉了朋友,顺手又在网上找了其它几个方法,第一个方
- 本文实例讲述了Python Web框架之Django框架文件上传功能。分享给大家供大家参考,具体如下:上传方式:- Form表单上传文件-
- 本文实例讲述了Python学习笔记基本数据结构之序列类型list tuple range用法。分享给大家供大家参考,具体如下:list 和
- 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深。案例如下:在使用S
- openlayer是目前我们gis常用的一款开源的,并且反馈都特别好的软件了,像之前的ol3, 风靡一时,地图实现也很简单,很实用,目前vu
- new Array() new Array(len) new Array([item0,[item1,[item2,...]]] 使用数组对
- asp防止用户同时登陆的方法,实现这个功能可有两种方式:1.使用application用application对象:如果做的是大型社区,可能
- 开门见山,直接使用 skimage 库为图像添加高斯噪声是很简单的:import skimageorigin = skimage.io.im
- 装饰器实现Python 函数重载函数重载指的是有多个同名的函数,但是它们的签名或实现却不同。当调用一个重载函数 fn 时,程序会检验传递给函
- 如下所示:#coding=utf-8#布局自定义尺寸from tkinter import *class App:def __init__(
- 不加(0)的用法:set rs=conn.execute(sql)'将这个结果赋给rs这时要读取这个记录集第一个字段的数据就用rs(
- 本文介绍基于Python中ArcPy模块,对大量栅格遥感影像文件进行批量掩膜与批量重采样的操作。首先,我们来明确一下本文的具体需求。现有一个
- //User 用户的基本信息,也是USERINFO表中的3个列package 登陆判断;public class User { &
- 解决方法:应对这种情况有以下几种方法:1、购买第三方软件(一般估计很少人买)2、自己编程一个小软件来执行,但是这个逻辑性要求比较高,而且编程
- 这篇文章主要介绍了python3 反射的四种基本方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- Vignere密码Vignere Cipher包含用于加密和解密的Caesar Cipher算法. Vignere Cipher与Caesa
- 下面继续为大家带来XHTML与HTML兼容的16条指引!1.避免将页面声明为XML类型,页面使用UTF-8或者UTF-16字符集。2.在空元
- 本文介绍了Vue生命周期和手动挂载,分享给大家,具体如下:1、vue的生命周期: 2、$mount()手动挂载 当Vue实例没有el属性时,
- 什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般