Python struct模块 | 使用pack函数进行字节序打包
struct 模块是 Python 的标准库之一,主要用于处理 C 结构体数据的打包和解包。
1. struct模块中的常见函数
struct.pack
:打包数据为字节序列struct.unpack
:从字节序列解包数据struct.calcsize
:计算结构体大小struct.pack_into
:将数据打包到缓冲区struct.unpack_from
:从缓冲区解包数据
2. struct.pack() 函数
2.1 功能:将 Python 数据类型打包成字节序列 bytearray
2.2 函数原型
struct.pack(format, v1, v2, ...)
2.3 参数:
- format:格式化字符,定义如何打包数据;常用的例如 "i", "L", 大小符号">"代表字节序;
- v1, v2, ...:要打包的数据;
实例1:按照大端序发送一个数据包,内容是0x1234
from struct import pack
buffer = pack(">i", 0x1234)
格式化字符:
b
:有符号字节B
:无符号字节i
:有符号整型(4 字节)I
:无符号整型(4 字节)L
:无符号长整型(32位系统上4字节,64位系统上8字节)Q
:unsigned long long(8字节)>
:大端序<
:小端序s
:字符串(需要指定长度,如10s
表示 10 字节的字符串)
场景用例:编写ROP的时候,使用pack函数打包gadget的内存地址(x86架构可使用"<L"或"<I”)
gadget = pack("<L", 0x53535353)
- 对于32位目标架构,可使用
“<I”
打包地址(4字节); - 对于64位目标架构,可使用
“<Q”
打包地址(8字节);
3. 字节序的表达方式
*思考以下三种方式有什么区别、分别用于什么场景:
- buffer = bytearray([0x41]*8)
- buffer = b"A"*8
- buffer = pack("<i", 0x41414141)
- 可变的字节序列(bytearray)
- 不可变的字节序列(bytes)
- 真正的“字节序打包”,pack("<i", 0x41414141)
附:快速验证函数输出的方法
摸索一个新的函数,其中一个有效方法是打印输出进行验证。直接打开 Python解释器 输入并进行验证是最近发现的非常高效的方法。
如果没有理解错误的话,这个程序就是Python解释器,最原始最快速的验证方法,非常适合用来测试像学习新函数过程中的一小段代码。
(勤动手实践,验证心中猜想,启动成本低且好用的工具是学习的利刃)