Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过argv向C程序输入零字节_Python_C_Security_Memory_Argv - Fatal编程技术网

Python 通过argv向C程序输入零字节

Python 通过argv向C程序输入零字节,python,c,security,memory,argv,Python,C,Security,Memory,Argv,下面是简单的C程序 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { int hex; memcpy(&hex, argv[1], 4); printf("hex %x\n", hex); return 0; } 输出是可预测的:hex 1020101

下面是简单的C程序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
        int hex;
        memcpy(&hex, argv[1], 4);
        printf("hex %x\n", hex);
        return 0;
}
输出是可预测的:
hex 1020101

接下来,我尝试在输入中放入一些零字节

./main `python -c 'print "\x01\x00\x02\x01"'`
结果让我大吃一惊

hex 10201
然后我检查了python到底向主输入输出了什么:

python -c 'print "\x01\x00\x02\x01"' > test
hexdump -C test

00000000  01 00 02 01 0a                                    |.....|
00000005
python似乎诚实地将\x01\x00\x02\x01放入文件并打印行尾符号。 我的理解是argv[1]应该是指向字节模式01000201所在内存的指针。在这种情况下,输出应该是1020001,而不是10201


问题-零字节在哪里?

零字节是字符串终止符,因此在使用backticks时,它永远不会被shell传递。我很确定内核在第一个零之后不会传递任何字节,因为它怎么知道要复制的参数的实际长度呢

您可以通过以下方式轻松验证这一点:

echo `python -c 'print "\x01\x00\x02\x01"'` | hd

在您的程序中,您可以访问未初始化的内存,因为根据all定义,第一个参数在第一个
'\0'
之后结束。结果可能是确定性的,但本质上是未定义的。

通过使用反标记,可以将参数传递给shell。所以零字节永远不会被传递,因为
\0
是字符串终止符。因此,您基本上是在访问未初始化的内存。当我尝试这样做时,输出是
01 02 01 0a
,因此在本例中,它只是吞下
\0
。不过,这并没有改变一个事实,即在参数字符串中不能有零字节……我认为shell不会对零字节执行特殊的操作。基本上,我的错误是我使用了“hextump-C测试”来验证输入,但shell实际传输的是“cat测试”。由于零字节不可打印,它们已经消失。我甚至在考虑编码问题,因为python的
print
在写入
stdout
时会选择控制台的默认编码。但这实际上只是未定义的行为。
echo `python -c 'print "\x01\x00\x02\x01"'` | hd