【问题标题】:Not getting a segmentation fault when expecting it预期时没有出现分段错误
【发布时间】:2011-07-09 09:35:45
【问题描述】:

我正在处理缓冲区溢出问题,但我对在 Mac OS 上运行以下简单 C 程序时发现的内容感到困惑。

#include <stdio.h>

int main(void) {

        char buf[2];

        scanf("%s", buf);

        printf("%s\n", buf);

}

通过将 buf 的长度设置为 2 个字节,我预计在输入字符串“CCC”时会导致分段错误,但这并没有发生。只有当输入长度为 24 个字符的字符串时,才会出现分段错误。

发生了什么事?是不是跟字符编码有关?

谢谢。

【问题讨论】:

    标签: c segmentation-fault undefined-behavior


    【解决方案1】:

    一旦你溢出缓冲区,你的程序的行为是不确定的。任何事情都有可能发生。你无法预测。

    缓冲区之后可能有也可能没有一些填充字节,这些字节恰好对您的代码执行不重要。你不能依赖它。不同的编译器,在 32 位和 64 位中编译,调试设置......所有这些都可能在溢出后改变你的代码执行。

    【讨论】:

    • 我明白了。我认为一分钱已经下降。恶意攻击者的目标是溢出堆栈的其余部分并因此覆盖寄存器?但是,他们将如何预测堆栈的剩余部分?操作系统每次都会分配固定数量的内存吗?
    • 查看汇编输出,反复试验是确定“剩余堆栈”的最佳选择。在相同的环境中执行相同的二进制文件是可能的,但完全不能保证。缓冲区溢出不会覆盖寄存器。它们覆盖堆栈或堆。
    • @Martin 典型的想法是溢出堆栈上的缓冲区,以便覆盖堆栈上的一些数据,这些数据指示 CPU 从函数返回后将返回的位置。有关更多详细信息,请尝试使用谷歌搜索“粉碎堆栈”。
    • 哦,所以攻击者会用'shellcode'填满堆栈?但是,执行如何跳转到 shellcode 的开头?抱歉,我脑子里有大量来自各种来源的信息,我正试图将它们拼凑在一起。 :)
    • 我在看到 Karl 的帖子之前发表了评论。谢谢你们的帮助,伙计们。
    【解决方案2】:

    因为buf 在堆栈上。当您开始覆盖它时,您开始覆盖属于操作系统不会捕获的程序的堆栈,具体取决于那里分配的其他内容(例如,编译器创建的寄存器的溢出插槽)。仅当您越过分配的堆栈边界时,操作系统才有机会引发段错误。

    【讨论】:

      【解决方案3】:

      这与内存布局有关。如果您的进程可以访问您正在覆盖的内容(映射为writable 的页面),则操作系统没有机会看到您正在做“错误”的事情。

      确实,在做这样的事情时,从 C 程序员的眼中“那是完全错误的!”。但是在操作系统的眼中“好吧,他正在向某个页面写东西。页面映射是否具有足够的权限?如果是,OKAY”。

      【讨论】:

        【解决方案4】:

        根本无法保证您会遇到分段错误。 char buf[2]覆盖后有更多数据可能会也可能不会导致分段错误。

        【讨论】:

          【解决方案5】:

          buf 是在堆栈上分配的,您只是在覆盖一个未使用的区域,很有可能没有人会抱怨它。在某些平台上,您的代码将接受整个段落。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-11-15
            • 2013-06-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多