c - 为什么这不能通过退出函数利用

标签 c gdb stack buffer-overflow

我有一段代码只是 strcpy() 100 字节长的缓冲区中的 argv1。之后,出于测试目的,我放置了 exit(0) 或 exit(1) 函数。没用别的。我从 gdb 得到的结果如下

 (gdb) i r eip
 eip            0x8048455   0x8048455 <main+65>
 (gdb) info frame
 Stack level 0, frame at 0xbffff260:
eip = 0x8048455 in main (exploitable.c:9); saved eip 0x41414141
source language c.
Arglist at 0xbffff258, args: argc=1094795585, argv=0xbffff304
 Locals at 0xbffff258, Previous frame's sp is 0xbffff260
 Saved registers:
 ebp at 0xbffff258, eip at 0xbffff25c
(gdb) i r eip
eip            0x8048455    0x8048455 <main+65>
(gdb) c
Continuing.
[Inferior 1 (process 2829) exited normally]

既然保存的 eip 是 0x41414141,为什么在离开当前堆栈后执行将转到无效的 0x41414141 地址?肯定它与退出功能有关,但我无法理解它:/

我知道解释在下面的代码里但是我看不懂

   => 0x08048455 <+65>: mov    DWORD PTR [esp],0x0
   0x0804845c <+72>:    call   0x8048350 <exit@plt>

最后一行暗示执行转到退出函数,我不确定 0x08040455 行是否显示传递给退出函数的 0 参数。 exit 函数在运行时没有任何 leave/ret 指令?因为“恰好”在主框架之外的框架的保存的 eip 被覆盖了!

最佳答案

exit 函数不返回。它调用用 atexit() 定义的函数,进行一些清理,并通过使用函数 0 (EXIT) 调用 Linux 来终止进程。

使用 return 1/return 0 而不是 exit(1)/exit(0),如果您想检查 main() 完成后您的 EIP 发生了什么。

关于c - 为什么这不能通过退出函数利用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20832570/

相关文章:

c - 如何将 time_t 变量打印为 float ?

c - 堆栈帧上的访问链接是什么?

c - 递归函数行为

c - SIGSEGV 不应该出现在某处,没有 NULL 指针

c++ - 无法在 gdb 中设置断点

android - 如何检查 Activity 是否仍在堆栈中?

在 C 中检查可用的堆栈大小

c - 修改C字符串常量?

c++ - gdb 为具有虚函数的类打印非字符串值的静态 const 数组的无效地址

c - FreeRTOS 应用程序堆栈可用内存随着时间的推移而减少