Intel x86_64环境下Pwntools p32函数输出与预期不符问题咨询
测试环境与复现流程
环境配置
- 硬件架构:Intel x86_64
- 操作系统:64位Ubuntu
- 运行依赖:Python 3.7.4(Anaconda构建版本)、Pwntools v4.3.1
复现代码
$ python Python 3.7.4 (default, Aug 13 2019, 20:35:49) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. >>> from pwn import * >>> addr = 0xbffffb78 >>> print(p32(addr)) b'x\xfb\xff\xbf'
输出结果的成因
显示形式差异的原因
当前输出和预期的字节序列没有内容层面的区别,差异完全来自Python 3对bytes类型对象的字符串展示规则:
- 当打印bytes对象时,解释器不会把所有字节都用
\xHH十六进制转义格式展示,仅对不可打印的ASCII字符、非ASCII范围的字节使用转义表示 - 落在ASCII可打印范围(32~126)的字节,会直接展示为对应的可打印字符
- 本次涉及的第一个字节值
0x78,正好对应ASCII表中的小写字母x,因此被直接展示为x,而非转义形式\x78
你可以通过逐字节提取的方式校验实际内容:
>>> [hex(byte) for byte in p32(0xbffffb78)] ['0x78', '0xfb', '0xff', '0xbf']
和预期的字节序列完全一致,不存在打包错误。
字节序逻辑说明
Pwntools的p32()默认采用小端序打包32位数值,将目标整数拆分为4个8位字节后,按照低字节在前、高字节在后的顺序拼接,对于数值0xbffffb78:
- 从高到低拆分的原始字节为
0xbf、0xff、0xfb、0x78 - 小端序重排后的字节顺序为
0x78、0xfb、0xff、0xbf
完全符合打包预期。
不依赖Pwntools的32位数值打包实现
以下两种都是可直接使用的标准实现,无需额外第三方依赖:
- 基于Python内置
struct模块实现(最通用的方式):
使用格式符<I代表小端序、32位无符号整数的打包规则,示例:import struct target_addr = 0xbffffb78 packed_bytes = struct.pack("<I", target_addr) # 返回结果: b'x\xfb\xff\xbf',和p32输出完全一致 - 手动逐字节拆分实现:
按位运算依次提取数值的低8位、次低8位、次高8位、高8位,拼接为bytes对象,示例:def pack_32bit_little_endian(value: int) -> bytes: return bytes([ value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, (value >> 24) & 0xff ]) # 调用pack_32bit_little_endian(0xbffffb78)会返回相同的正确结果
内容的提问来源于stack exchange,提问作者CPUU
相关产品推荐
相关产品推荐

