gpt4 book ai didi

有人可以协助解释具有术语 'stack smash' 的回溯输出吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:15:08 26 4
gpt4 key购买 nike

请解释在运行程序后堆栈粉碎的以下结果,其中我提供的输入远远超过字符数组的容量。

    *** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7f856d8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7f85690]
./a.out[0x804845f]
[0x666a6473]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:07 91312 /home/mawia/a.out
08049000-0804a000 r--p 00000000 08:07 91312 /home/mawia/a.out
0804a000-0804b000 rw-p 00001000 08:07 91312 /home/mawia/a.out
084cd000-084ee000 rw-p 084cd000 00:00 0 [heap]
b7e6d000-b7e7a000 r-xp 00000000 08:07 221205 /lib/libgcc_s.so.1
b7e7a000-b7e7b000 r--p 0000c000 08:07 221205 /lib/libgcc_s.so.1
b7e7b000-b7e7c000 rw-p 0000d000 08:07 221205 /lib/libgcc_s.so.1
b7e8a000-b7e8b000 rw-p b7e8a000 00:00 0
b7e8b000-b7fe3000 r-xp 00000000 08:07 238955 /lib/tls/i686/cmov/libc-2.8.90.so
b7fe3000-b7fe5000 r--p 00158000 08:07 238955 /lib/tls/i686/cmov/libc-2.8.90.so
b7fe5000-b7fe6000 rw-p 0015a000 08:07 238955 /lib/tls/i686/cmov/libc-2.8.90.so
b7fe6000-b7fe9000 rw-p b7fe6000 00:00 0
b7ff6000-b7ff9000 rw-p b7ff6000 00:00 0
b7ff9000-b8013000 r-xp 00000000 08:07 221196 /lib/ld-2.8.90.so
b8013000-b8014000 r-xp b8013000 00:00 0 [vdso]
b8014000-b8015000 r--p 0001a000 08:07 221196 /lib/ld-2.8.90.so
b8015000-b8016000 rw-p 0001b000 08:07 221196 /lib/ld-2.8.90.so
bfd00000-bfd15000 rw-p bffeb000 00:00 0 [stack]
Aborted

请解释以下内存映射的细节以及本报告中给出的各种细节的意义。

编辑:

代码只是简单地输入一个字符串。我故意输入的字符串的大小大于我定义的字符数组的长度,以产生堆栈粉碎。代码:

 int main()

{
int a;
char s[10];
scanf("%s",s);
return 0;
}

谢谢。

最佳答案

编辑:只需重新阅读您的问题的标题。你想知道为什么它被称为 Stack Smash。当您调用在 C 中创建的数组的函数时,会为您的所有局部变量、函数的参数和函数的返回地址生成一个框架。这个框架是在堆栈上制作的,被称为堆栈框架;听起来很公平。这个栈帧应该只属于那个函数,并且应该与它周围的其他栈帧有边界;如果它可以改变其他堆栈框架,后果可能是可怕的。它会打破整个“功能有自己的范围”的想法。因此,因为你的数组是一个局部变量,它被放置在那个堆栈帧中,当你在其中放置太多信息时,你只是继续写入,直到到达堆栈帧的边界,然后你继续前进,C 将让你那样做。它设定了界限并让您随意打破它们。这种超出框架边界的行为被称为“粉碎”堆栈,因为您正好跑过其他重要数据。破坏堆栈就是在不应该写入的地方破坏堆栈数据。

首先我应该说它不会给你太多信息,除非你碰巧知道哪些 c 指令被放置在内存的哪个部分。

回溯会告诉您在失败之前正在运行的代码;即你的程序在你溢出的数组上调用了 libc 代码。

内存映射告诉您内存的哪些部分专用于什么,例如您的程序在哪里,它调用的库在哪里,堆在哪里以及堆栈在哪里。它还为您提供了那些内存位置 rwxp 的权限(读取、写入、可执行、PROC_STACK),尽管我不确定 PROC_STACK 位。

基本上,除非您知道您的程序在内存中的映射,否则这是无用的信息。您也可以使用更有用的调试器。这告诉你一些事情:

  1. 您的程序破坏了 libc,这可能意味着多种情况。
  2. 您用代码破坏了堆栈。

我假设您知道您的数组是在调用它的函数的堆栈帧中初始化的,因此,当您压入太多值时,您会离开帧并破坏堆栈。

希望对您有所帮助。如果您想了解更多,请询问。

关于有人可以协助解释具有术语 'stack smash' 的回溯输出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/789900/

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