为何Python输出0x90(NOP)时会附带0xc2字节?
问题描述
执行命令python3 -c "print('\x41'*200)" > out.txt可输出200个0x41('A')字节及末尾的0x0a换行符,hexdump out.txt验证结果正常。但执行python3 -c "print('\x90'*200)" > out.txt输出NOP sled(0x90)时,每个0x90后都附带0xc2字节,hexdump结果显示为90c2重复。而Perl命令perl -e 'print "\x90" x 200' > out.txt可正常输出200个0x90字节。请问为何Python会出现该情况?
原因分析
核心差异在于Python和Perl对输出内容的编码处理逻辑不同:
- Python 3的
print函数默认会将字符串以UTF-8编码输出到标准输出。\x41是ASCII范围内的字符(0x00-0x7F),在UTF-8中本身就是单字节表示,所以输出正常;但\x90超出了ASCII的单字节范围,属于UTF-8中需要双字节编码的字符(对应Unicode的U+0090),因此会被编码为0xc2 0x90两个字节输出。 - Perl的
print默认直接输出原始字节数据,不会做编码转换,所以\x90会被直接写入文件,没有额外字节。
解决办法
如果要在Python中输出纯原始字节,避免编码转换,可以用以下两种方式:
- 直接操作标准输出的字节缓冲区:
python3 -c "import sys; sys.stdout.buffer.write(b'\x90'*200 + b'\n')" > out.txt - 修改标准输出的编码为
latin-1(该编码会将每个Unicode字符直接映射为对应单字节):python3 -c "import sys; sys.stdout.reconfigure(encoding='latin-1'); print('\x90'*200)" > out.txt
内容的提问来源于stack exchange,提问作者ramon
相关产品推荐
相关产品推荐

