首页 > 代码库 > [原理分析]Linux下的栈溢出案例分析-GDB调试操练-加强版

[原理分析]Linux下的栈溢出案例分析-GDB调试操练-加强版

摘要:

原来的版本:http://blog.csdn.net/bigbug_zju/article/details/39892129 

原版本中的问题主要在于调试过程中,蛮力的痕迹太重,没有很好地体现常用的调试准则;本文在原版本的基础上融入参考文献中提及的调试原则,重新审视和操练该问题,希望尽量体现出调试中常用的思维法则。

测试的平台:
1.  ubuntu 9;   gcc 4.4.1;   Gdb 7.0-ubuntu
2.  ubuntu系统安装在virtual box 3.2.8虚拟机上;

问题重述:

此处简要地描述下原来的问题,具体细节查看原文,我们希望采用stackoverflow aaaabbbbccccddddeeee中的eeee的值覆盖stackoverflow中overflow到main函数的返回地址,调用overflow返回到main函数时,控制eip,使其中的值为0x63636363;但是实际过程中问题在于eip的值并不是设想的0x63636363,而是0x61616161;

原因何在?

调试过程:

调试原则1:要去看,不是去想;

一开始,我们不能假设性地认为问题就出在overflow返回到main的过程中(既然出问题了,就说明系统的行为跟你想象的差别很大,问题发生在何处都不奇怪)而应该实际地单步运行下看看,看看问题到底在什么地方?通过设置断点,以及单步运行,我们发现eip的控制并不出现在overflow返回到main的过程,而是main函数退出的

过程;

调试原则2:理解系统

根据函数的调用过程,在call前会将当前主函数的下一句地址压栈;在进入函数后,首先执行:push ebp; mov ebp, esp;

退出函数时,mov esp, ebp; pop ebp。最后调用ret指令时,将call指令压入的下一句地址弹出到eip中。根据上述系统模型,大概需要查看的分支为:

1. main函数返回的地址被修改(也即call main时函数压入的地址),也即esp所指向的返回地址的内容被改变;

2. 还有,返回地址中的内容没有改变,esp所指向的返回地址被改变;

调试原则3:先排除易于验证的分支;

调试原则4:非正常的情况与正常的情况进行比较;

上述的两个调试分支,排除的难以程度相近,我们随便选择1入手.

....to be done.


参考文献:

调试九法:软硬件错误的排查之道,David J. Agans著,赵俐译,人民邮电出版社。

[原理分析]Linux下的栈溢出案例分析-GDB调试操练-加强版