通过 argv 输入零字节到 C 程序

Input zero bytes to C program via 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;
}

我做了如下实验

./main `python -c 'print "\x01\x01\x02\x01"'`

输出是可预测的: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。

问题 - 零字节在哪里?

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

您可以通过

轻松验证这一点
echo `python -c 'print "\x01\x00\x02\x01"'` | hd

在您的程序中,您访问未初始化的内存是因为所有定义的第一个参数在第一个 '[=11=]' 之后结束。结果可能是确定性的,但本质上是未定义的。