我有一段代码只是 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
发生了什么。
我是一名优秀的程序员,十分优秀!