十六进制中python3的奇怪行为

时间:2019-02-06 08:17:52

标签: python

我正在尝试利用缓冲区,并且使用 python 3 的代码如下:

python3 -c "print ('A' * 44 + '\xcb\x85\x04\x08')" | ./vuln

或使用 2.7 的另一种方式:

python2.7 -c "print 'A' * 44 + '\xcb\x85\x04\x08'" | ./vuln

但是在这种情况下,只有2.7可以正常工作,所以我尝试检查十六进制:

python2.7 -c“打印'A'* 44 +'\ xcb \ x85 \ x04 \ x08'” | hexdump
0000020 4141 4141 4141 4141 4141 4141 85cb 0804
0000030 000a

python3 -c“打印('A'* 44 +'\ xcb \ x85 \ x04 \ x08')” | hexdump
0000020 4141 4141 4141 4141 4141 4141 8bc3 85c2
0000030 0804 000a

它不依赖于系统(我曾在ubuntu和arch上尝试过),不依赖于终端机(也尝试过其他版本)
看起来python 3添加了一些东西并更改了内存,但是为什么而且真的很正常?

2 个答案:

答案 0 :(得分:3)

在Python 2中,字符串和字节范围是相同的。这给非ASCII字符串带来了问题,因此他们在Python 3中对其进行了更改。在Python 3中,您需要一种bytes类型。构造字节字符串的最简单方法是在文字前面加上b

b'A' * 44 + b'\xcb\x85\x04\x08'

但是,您不能像在Python 2中那样直接打印bytes。Python 3可以很好地表示您的字节,如下所示:

b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xcb\x85\x04\x08'

很明显,这全是ASCII,而不是您想要的字节。要将字节直接写入stdout,请使用sys.stdout.buffer.write:

python3 -c "import sys;sys.stdout.buffer.write(b'A' * 44 + b'\xcb\x85\x04\x08')"

请注意,这不会在末尾写换行符:

0000020 41 41 41 41 41 41 41 41 41 41 41 41 cb 85 04 08

输出某些字节似乎有点麻烦,尤其是与Python 2相比。这是因为Python 3确实改善了人类可读文本的输出方式。这样的结果是,不进行任何编码就更难打印字节,因为在输出文本时这通常是不正确的。

答案 1 :(得分:0)

我的猜测是000a和0804 000a是字符串结尾和回车符。我在ASCII表中查找了它们。

ASCII descriptions of the following hex values:
0a = LF -> Newline.
00 = NULL
08 = backspace
04 = end of transmission

为什么Python引入了这些退格键,而EOT字符对我来说还是不清楚的。尝试使用python格式化功能将其格式化为字符。