我试图了解Linux中一个C程序溢出的两种不同行为(称之为vulnerability_prog),它要求输入,以便允许溢出缓冲区。据我所知,编译器以特定方式布置堆栈帧,有时会造成一些不可预测性。我无法理解的是,当我使用python脚本溢出缓冲区以向程序提供20个字符时,处理内存的方式不同,而不是手动运行vulnerability_prog并手动输入20个字符。
示例程序声明了一个“char name [20]”数组,目标是将其溢出并将特定值写入将被覆盖的另一个变量中。 (这是来自经典的战争游戏网站。)
据我所知,处理器(64位)一次读取8个字节,因此需要填充不是8的倍数的数组,以保持内存的有序性。因此,我的char [20]实际上占用了24个字节的内存,处理器可以将其作为8字节字。 意外的行为是这样的:
使用python脚本时,溢出的行为如下:
$python -c'print "A"*20 + "\xre\xhe\xyt\xhe"' | /path/vulnerable_prog
20个字符溢出缓冲区,预期值写入内存中的正确位置。
但是,当您尝试通过从命令提示符运行程序并手动输入20个字符来溢出缓冲区,然后将所需的十六进制字符串写入内存时,必须使用一个额外的十六进制字符才能使值最终会出现在您想要的正确位置:
$echo$ 'AAAAAAAAAAAAAAAAAAAA\xre\xhe\xyt\xhe\xaf'
(然后将'echo'的输出复制并粘贴到vulnerability_prog从命令行运行时提供的提示中)
脚本和命令行开发之间的字符数组填充的这种差异在哪里发挥作用? 我一直在ISO/IEC 9899:201x进行大量关于C结构填充和阅读的研究,但找不到任何可以解释这种细微差别的东西。 (这是我关于Stack Overflow的第一个问题,所以如果我没有正确地问这个问题我会道歉。)
答案 0 :(得分:0)
您的Python脚本在管道传输时实际上会向/path/vulnerable_prog
发送25个字符。 print语句添加换行符。这是你的Python程序加上一个小的Python脚本,它对写入其标准输入的字符进行计数:
python -c'print "A"*20 + "\xre\xhe\xyt\xhe"' | python -c "import sys; print(len(sys.stdin.read()))"
我猜测你并没有将echo
中的换行符粘贴到程序的提示符中。不幸的是,我不认为我有足够的信息来解释为什么你需要25个而不是24个字符来实现你的尝试。
P.S。欢迎来到Stack Overflow!