摘要: 本文主要演示linux平台下的栈溢出,首先依据理论对演示样例代码进行溢出攻击;结果是溢出攻击成立,可是与设想的有区别。然后採用GDB调试工具对发生的意外。进行深入的分析。

測试的平台:1.  ubuntu 9;   gcc 4.4.1;   Gdb 7.0-ubuntu

2.  ubuntu系统安装在virtual box 3.2.8虚拟机上。

演示样例代码例如以下:

#include

void overflow(char* arg)

{

char buf[12];

strcpy(buf, arg);

}

int main(int argc, char *argv[])

{

if(argc > 1)

overflow(argv[1]);

return 0;

}

假设依照一般的方式编译:

gcc –o stackoverflow stackoverflow.c

linux系统可以探測到程序中的stack  overflow,从而终止程序,例如以下图所看到的:

那有没有办法让系统不探測到stack overflow。此处能够在编译时,禁用堆栈保护,详细命令例如以下:

gcc –fno-stack-protector –o stackoverflow stackoverflow.c

然后採用gdb调试stackoverflow,

这里的输出跟设想的存在非常大的区别,由于设想中的函数栈例如以下:

前面的12个字节填充buf,然后接下来的4个字节填充ebp,最后的4个字节填充RET地址。那么照理说,这里的eip应该是0x65656565,那为什么此处是0x61616161,刚好是aaaa的值呢?

依据单步调试的结果。发现eip变为0x61616161是在main函数退出后达到的,依照设想应该是在overflow退出时。eip变为0x65656565。

为什么overflow退出后还能回到main函数?可能的原因:输入的字符串没有覆盖掉ret地址,可是字符串却意外地将main的返回地址给覆盖掉了?

但就算是覆盖,为什么覆盖的值没有採用e的值,而是採用的a的值?要知道a是在字符串的起始处?这点的确让人奇怪。

1. 我们还是採用一步步调试的方式来观察问题所在。先看下gcc编译后的反汇编代码:

使用到的命令:

set disassembly-flavor intel  //将汇编设定为intel风格;

disassemble main  //反汇编main函数。

Main函数:

1. push ebp

2. mvo ebp, esp

3. and esp, 0xfffffff0

4. sub esp, 0x10

5. cmp DWORD PTR [ebp+0x8], 0x1

6. jle 0x804841d

7. mov eax, DWORD PTR [ebp+0xc]

8. add eax, 0x4

9. mov eax, DWORD PTR [eax]

10. mov DWORD PTR [esp], eax

11. call 0x80483e4

12. mov eax, 0x0

13. leave

14. ret

然后再来看下。overflow的反汇编代码,命令:disassemble overflow

Overflow函数:

1. push ebp

2. mov ebp, esp

3. sub esp, 0x28

4. mov eax, DWORD PTR[ebp+0x8]

5. mov DWORD PTR[esp+0x4], eax

6. lea eax, [ebp-0x14]

7. mov DWORD PTR [esp], eax

8. call 0x804831c

9. leave

10. ret

我们单步调试上述的指令,关注当中esp值的变化。

总图例如以下,后面是对当中每一步的分析:

在完毕main.1后,命令p $esp后,esp的值变为:Esp = 0xbffff438

Main.3后。esp的值变为0xbffff430,预计是用于对齐;

Main.4后,esp的值为0xbffff420;

Main.7-10,这里主要将argv[]的arg[1]字符串的首地址取出来。而且将其放置在esp中,此时esp的值为0xbffff420;

运行overflow.1后。esp的值变为:0xbffff41c,当中存放着main的下一条语句的地址。

通过命令:x $esp能够看到overflow返回的地址:

0xbffff41c   0x0804841d

Overflow.1运行后,esp的值变为0xbffff418,用于存放ebp的值;

Overflow.3运行后,esp的值变为0xbffff3f0,

Overflow.5-7运行后,将字符串的地址放置在3f0+0x4地址处,然后再将暂时字符串也即buf的首地址[ebp-0x14]放置在3f0地址处(当前的esp指向处);

运行完overflow.8后,我们查看buf起始处后,发现的确完毕了内容的赋值,命令例如以下:

X 地址。

运行完leave指令后,发现esp的值变为:0xbffff41c。刚好指向的返回main的地址;然后再运行ret指令后。发现esp变为0xbffff420。然后,程序跳回到main函数;

然后再运行main函数中的leave指令,依照设想中leave指令运行后。esp的值应该变为43c,指向main的返回地址;可是实际我们运行后,esp的值变为0xbffff404,当中的内容刚好是0x61616161。也就是aaaa的值;这里我们測试时使用的參数的头四个字符刚好是aaaa;

到这里为止,就明确整个问题的症结:

Main函数中调用leave指令时。esp的值并没有调整到位。本来应该指向43c(前面的地址忽略)的,此处却指向的404?

那么为什么会产生这种状况?照理说这是编译器该干的事。为什么此处编译器没有尽责呢?

奇怪的是:

不发生栈溢出时,也即我们输入的字符串长度不超过12时,main中的leave指令运行后,程序能够正常的返回到43c的位置,顺利退出。

那这里的问题就非常奇怪了:栈溢出是发生在overflow中。程序能够从overflow中顺利返回到main中,然后main的leave指令就不正常了。假设overflow中没有栈溢出,程序也顺利返回到main函数,然后main的leave指令能够正常工作。

上述的问题的症结在于搞清楚leave指令本身;猜想其可能会依赖某些寄存器,或者依赖特定的存储单元来达到恢复目的。

首先看看能不能stepi进入leave;答案是leave是单条指令。不是一个处理函数;

所以我们试试能不能从寄存器上发现点什么。发现事实上对比vistual studio中的操作,

Leave指令应该等效为:

Mov  esp, ebp

Pop  ebp

之前关注的都是esp,那依照上面的等效的话,接下来应该关注ebp寄存器的变化。

所以,接下来要做的1. 首先验证上述的的等效成立,2. 要盯着ebp在运行过程中的变化。

对于问题1的验证,我们偷个懒,直接baidu之,发

gdb 查看是否 栈溢出_[原理分析]Linux下的栈溢出案例分析-GDB调试操练[1]相关推荐

  1. linux抓包库libpcap,linux下libpcap抓包分析.doc

    linux下libpcap抓包分析 HYPERLINK "/Seiyagoo/archive/2012/04/28/2475618.html" linux下libpcap抓包分析 ...

  2. linux下IIC驱动开发分析

    1.  IIC规范 IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备.IIC总线产生于在80年代,最初为音频和 ...

  3. java 收集系统资源_方法:Linux 下用JAVA获取CPU、内存、磁盘的系统资源信息

    CPU使用率: InputStream is = null; InputStreamReader isr = null; BufferedReader brStat = null; StringTok ...

  4. linux下usb转串口驱动分析

    linux下usb转串口驱动分析 分类: linux driver 2012-06-08 15:11 456人阅读 评论(0) 收藏 举报 linux struct interface returni ...

  5. linux rapidio测试,Linux 下RapidIO 子系统的分析与实现.pdf

    Linux 下RapidIO 子系统的分析与实现.pdf 第36 卷 第9 期 计 算 机 工 程 2010 年5 月 V Computer Engineering May 2010 ol.36 No ...

  6. linux下code-server离线远程web浏览器调试C++代码

    linux下code-server离线远程web浏览器调试C++代码 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:129518033 文章目录 lin ...

  7. html u蓝色下滑线,htmlu标签添加下划线的案例分析

    html标签添加下划线的案例分析 发布时间:2020-09-22 11:00:25 来源:亿速云 阅读:87 作者:小新 html标签添加下划线的案例分析?这个问题可能是我们日常学习或工作经常见到的. ...

  8. linux跟踪内存检测原理,wooyun/Linux下基于内存分析的Rootkit检测方法.html at master · exitmsconfig/wooyun · GitHub...

    Linux下基于内存分析的Rootkit检测方法 - 路人甲 原文地址:http://drops.wooyun.org/tips/4731 0x00 引言 某Linux服务器发现异常现象如下图,确定被 ...

  9. logger 参数列表过长_[源码级解析] 巧妙解决并深度分析Linux下rm命令提示参数列表过长的问题...

    在维护实习单位服务器的过程中,偶然发现一个有350万文件的文件夹需要清理,于是我习惯性执行了rm -rf ./*,却在数秒后被告知"参数列表过长".在一番折腾过后,我终于通过取巧的 ...

  10. was查看java内存_性能测试WAS内存使用的探索和分析

    性能测试中,CPU和内存是关注最多的两个性能指标.以我行应用最多的系统架构(WAS+Oracle)来说,CPU使用率高的问题多发生于数据库,比如索引不当引发的表扫描.绑定变量使用不当引发的硬解析.连接 ...

最新文章

  1. Class Activation Mapping(CAM)
  2. 强化学习(一)——专业术语及OpenAI Gym介绍
  3. win7笔记本电脑如何分割和重命名磁盘
  4. optional判断是否为空_乐字节Java8核心特性之Optional
  5. c++中友元函数详解
  6. 2019 最新阿里中间件Java 4轮面试题!60万年薪起步~
  7. oracle零碎要点---ip地址问题,服务问题,系统默认密码问题
  8. Xamarin.Form 超链接 用手势实现
  9. 崩坏学园2及大部分采用ETC1压缩格式的Unity3D游戏的拆包图处理
  10. 文件系统挂载、卸载及相关的工具 ⑨
  11. 安装VMware15.5+安装win10虚拟机操作系统(非常详细)
  12. SQL Server存储过程实例
  13. 禁忌搜索算法求解TSP问题-python实现
  14. Cmake查找所有指定cpp文件并进行编译
  15. 计算机关机时间设置方法,电脑如何设置定时关机 电脑定时关机设置方法
  16. CAN/RS-485为什么要用双绞线?
  17. UOJ449. 【集训队作业2018】喂鸽子 [概率期望,min-max容斥,生成函数]
  18. 武汉大学计算机转专业2021,通知|关于做好2021年普通本科生转专业工作的通知...
  19. CentOS cowsay “会说话的小动物”
  20. element ui 上一页下一页_vue翻页器,包括上一页,下一页,跳转

热门文章

  1. 2008RDS高可用:DNS轮询
  2. centos7.2如何升级到centos7.3最新版本
  3. [Android] 软件中选择文件夹功能
  4. 暗黑3服务器维护时间多久,暗黑3亚服维护近24小时 将封10万账号
  5. [数据结构] 树链剖分
  6. vue组件中传值遇到的一些问题
  7. Springboot中使用JWT
  8. java list 某个重复列_Java 开发的编程噩梦,这些坑你没踩过算我输
  9. python注释中文_python注释不能识别中文
  10. linux下启动管理,rEFInd启动管理器配置文件详解