2

我在发现一个问题时遇到了一些麻烦。鉴于以下情况:

int match(char *s1, char *s2) {
    while( *s1 != '\0' && *s2 != '\0' && *s1 == *s2 ){
        s1++; s2++;
    }
    return( *s1 - *s2 );
}

int main() {
    char str1[8], str2[8];
    scanf("%s", str1);
    scanf("%s", str2);
    if (match(str1, str2) == 0)
        printf("They are the same.\n");
    else
        printf("They are not the same.\n");
}

哪两个不同值的输入字符串可用于使程序打印消息“它们是相同的”?(以上代码不可更改)

我知道当数组被添加到堆栈中时,它们被“推入”其中并且信息被写入相同的方向。因此,如果我在 str2 中输入“AAAAAAAAA”(A x 9),它会溢出并且 str1 会打印“A”。

我的第一次尝试是为 str2 输入 A x 16,希望程序会用 8 个 A 覆盖 str1 中的值,并且程序只会读取 str2 中的 8 个值。str1 确实有 A x 8 的值,但 str2 保留了 A x 16 的值。

有没有办法用它来解决这个问题?还是我想错了?

编辑:这个问题是要在具有过时的、因此易受攻击的 Linux 版本的特定机器上运行的。我已经通过 gdb 运行程序,它显示两个字符串在内存中彼此相邻,并且 str2 溢出到 str1。那么我的问题是,我可以使用它来使 str2 和 str1 在比较它们时看起来与程序相同吗?

4

5 回答 5

3

哪两个不同值的输入字符串可用于使程序打印消息“它们是相同的”?(以上代码不可更改)

不存在这样定义明确的场景。要求毫无意义。

我知道当数组被添加到堆栈中时,它们被“推入”其中并且信息被写入相同的方向。因此,如果我在 str2 中输入“AAAAAAAAA”(A x 9),它会溢出并且 str1 会打印“A”。

这是不正确的。缓冲区str1(可以包含7个字母 + 1 个空终止符)会溢出,从那里可能会发生任何事情,您会调用未定义的行为。可能的未定义行为的一些示例是:分段错误/崩溃和烧毁,或程序似乎正常工作。

不能保证 str2 与 str1 相邻分配。也不能保证 str1 在 str2 之前分配。甚至没有任何保证它们被分配在堆栈上,尽管这很有可能。

有没有办法用它来解决这个问题?

不。

还是我想错了?

是的。

于 2013-10-14T14:08:14.503 回答
2

我有另一个想法:如果你输入“A”和“A A”会发生什么?据此 '%s' 需要非空白字符,sscanf因此它将在 "A A" 中的第一个 "A" 之后停止读取(注意空格字符)。标签“缓冲区溢出”具有误导性。

于 2013-10-14T14:33:14.710 回答
1

覆盖缓冲区会调用未定义的行为。任何事情都有可能发生,所以你绝不能依赖它。

此外,str1并且str2不一定在内存中彼此相邻,您不能依赖它。

可能的解决方案

char buffer[16];
char * str1 = &buffer[8];
char * str2 = &buffer[0];

这样你就可以安全地从str2to溢出str1(但不能从str1to str2)。不过,您仍然应该进行适当的长度检查。

于 2013-10-14T13:57:20.140 回答
1

你试过相反的方法吗?这取决于堆栈的布局方式。我会为str1尝试“AAAAAAAAAA”,为str2尝试“AAAAAAA”(7x'A')。AFAIR 堆栈从上到下增长。

请参阅此处以获取解释。

编辑:我知道如果你写超过数组限制会发生邪恶(未定义)的事情,但问题明确告诉不要改变程序。看起来像是了解软件开发中的安全风险的练习。

于 2013-10-14T14:02:37.297 回答
0

哪两个不同值的输入字符串可用于使程序打印消息“它们是相同的”?

你的字符串比较函数是错误的。return( *s1 - *s2 );在这里没有意义。将功能更改为

int match(char *s1, char *s2) {
    while( *s1 != '\0' && *s2 != '\0') {
        if(*s1 != *s2 )
             return 1;
        s1++; s2++;
    }

    return 0;
}
于 2013-10-14T13:53:43.733 回答