gpt4 book ai didi

c - 只有当一个重要的指针被覆盖时,缓冲区溢出才会导致段错误吗?

转载 作者:行者123 更新时间:2023-12-04 12:30:59 25 4
gpt4 key购买 nike

假设我有一个程序声明了一个 char buffer[size] 和另一个变量,并使用 gets(buffer); 将数据写入 buffer。如果 gets 提供的输入太长,那么它将从缓冲区溢出,进入下一个变量(假设该变量位于 buffer 之后的下一个地址):

void f(){
char str[12] = "hello_world";
char buffer[1];

gets(buffer); // provided with a random char and then "hello_kitty"

printf("str = %s\n", str); // no crash. Just prints "hello_kitty" as expected
}

当使用“合法输入”(意思是 - 没有溢出第二个缓冲区)运行它时,这是可以的。即使我稍微溢出缓冲区也没有问题,但输入太多后程序崩溃了。

据我所知,这(意思是 - 不溢出第二个缓冲区)不应该导致任何崩溃。可能导致崩溃的原因是破坏了保存指令指针的内存,因此它现在将指向一个无效地址(这是页面错误吗?)。

这是正确的吗?不影响任何堆栈/帧/指令指针的错误写入会导致崩溃吗?

最佳答案

简明扼要地回答你的问题,不。继续阅读以获得更长的答案。

缓冲区溢出导致段错误的最典型方式是溢出的缓冲区驻留在堆栈上,溢出覆盖了返回指针。当返回指针在函数返回时弹回指令指针时,通常会发生段错误,因为处理器试图读取您无权访问的内存。

最后一句话很重要。覆盖返回指针只是可能发生段错误的一种方式。事实上,任何覆盖稍后用于访问内存的内存地址的缓冲区溢出都可能导致段错误,或者如果试图写入内存,则会导致访问冲突。 p>

例如,假设您在堆上分配了一个结构。该结构采用以下形式:

 struct sample_struct {
char bytes[20];
struct sample_struct *next;
};

如果在没有正确验证边界的情况下将数据复制到 bytes 成员中,内存中的下一项将是 next 指针。如果这个指针被覆盖并且随后试图从中读取,则很可能会发生段错误,假设现在那里的值表示一个您无法控制的内存地址。如果您碰巧在内存空间中找到一个地址,结果将是尝试将位于那里的字节解释为 struct sample_struct,这可能会导致其他问题。


请注意,不要假设覆盖上面示例结构中的指针只需要 21 到 24 个字节;除非您指示编译器打包该结构,否则该结构的内存分配可能会包含额外的字节以进行对齐。

关于c - 只有当一个重要的指针被覆盖时,缓冲区溢出才会导致段错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45740014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com