当前位置: 首页 > 编程日记 > 正文

一个简单的缓冲区溢出的思考

从大二开始真正接触技术开始,从最早的HTML,PHP,WEB开发。一直以为以后可能会从事开发的工作,碰巧大三上的时候和同专业的郭子,邹豪参加了南京的一个信息安全技能大赛,才真正找到了兴趣的方向,也从懵懵懂懂开始懂了信安怎么学,像海贼王里面一样,感觉到了新世界了(好吧,我又YY了......)

最近参加了ISCC2013的比赛,历时一个月的过程,虽然过程很辛苦,每天除了吃饭睡觉都在想题目(我不会告诉你我有一题是在睡觉的时候想出来的,做梦梦到单步调试....)。但是感觉收获颇丰,貌似比以前牛逼了一点点。也因此萌生了要开一个技术博客,写一点自己原创的东西,算是总结提高吧。

在做溢出关第一题的时候,遇到了缓冲区溢出的问题,之前从没接触过这东西,汇编也不懂。于是各种查资料,看小甲鱼的汇编视频,总算是把原理搞明白了,希望在这里分享一些关于缓冲区溢出和汇编的基础知识,小白一个,大神路过不要拍砖啊。

首先看一段代码:

#include<stdio.h>
void why_here(void) /*这个函数没有任何地方调用过*/
{
  printf("why u here ?!\n");
  _exit(0);
}
int main(int argc,char * argv[])
{
  int buff[1];
  buff[2]=(int)why_here;
  return 0;
}

用GCC或者VC编译运行一下,会发现why_here函数被运行了,地球人都知道这是缓冲区溢出,但是在底层代码到底发生了什么呢?

原因是是因为错误的越界溢出赋值导致了函数返回地址被错误的覆盖了,程序流执行到这里之后不是正常的返回而是执行了被覆盖的地址。这样说有点抽象,我们用VC进行debug一下,看看汇编代码到底做了什么。

发生溢出的C代码:

6:    int main(int argc,char * argv[])
7:    {
00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,44h
00401076   push        ebx
00401077   push        esi
00401078   push        edi
00401079   lea         edi,[ebp-44h]
0040107C   mov         ecx,11h
00401081   mov         eax,0CCCCCCCCh
00401086   rep stos    dword ptr [edi]
8:        int buff[1];
9:        buff[2]=(int)why_here;
00401088   mov         dword ptr [ebp+4],offset @ILT+5(why_here) (0040100a)
10:       return 0;
0040108F   xor         eax,eax
11:   }
00401091   pop         edi
00401092   pop         esi
00401093   pop         ebx
00401094   mov         esp,ebp
00401096   pop         ebp
00401097   ret

这两行是函数调用的常用语句,EBP是基址寄存器,目的是在进入函数前将EBP保护起来,一遍出来的时候可以恢复现场(计算机组成原理上的知识)。

下面这句  sub   esp,44h 应该就是为新进入的函数预留栈空间。接下来就是经典的三个push为main函数传参。

............

我们重点看这行代码:

00401088   mov     dword ptr [ebp+4],offset @ILT+5(why_here) (0040100a)

将why_here的函数入口基地址放入[ebp+4]中,这样看也许看不出什么不妥,我们对比一下正常的情况。

下面是正规规范编写的C代码:

#include<stdio.h>
void why_here(void) /*这个函数没有任何地方调用过*/
{
  printf("why u here ?!\n");
  _exit(0);
}
int main(int argc,char * argv[])
{
  int buff[1];
  buff[0]=(int)why_here;(因为buff只申请了一个int型,也就是4字节的内存空间,所以只能只能保存一个32位的函数RVA地址)
  return 0;
}

对应的汇编

6:    int main(int argc,char * argv[])
7:    {
00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,44h
00401076   push        ebx
00401077   push        esi
00401078   push        edi
00401079   lea         edi,[ebp-44h]
0040107C   mov         ecx,11h
00401081   mov         eax,0CCCCCCCCh
00401086   rep stos    dword ptr [edi]
8:        int buff[1];
9:        buff[0]=(int)why_here;
00401088   mov         dword ptr [ebp-4],offset @ILT+5(why_here) (0040100a)
10:       return 0;
0040108F   xor         eax,eax
11:   }
00401091   pop         edi
00401092   pop         esi
00401093   pop         ebx
00401094   mov         esp,ebp
00401096   pop         ebp
00401097   ret

我看到这里的时候就恍然大悟了,嗖嘎斯内。因为溢出赋值覆盖了EIP(也就是指令寄存器,导致了函数返回后,程序的执行流被改变了)。

这里我们详细讨论一下:

进入main 函数后的栈内容下:
[ eip ][ ebp ][ buff[0] ]
高地址<---- 低地址

因为在栈空间中,栈是向下生长的,而赋值是向上生长的。所以正常情况下[ebp-4]的赋值是正常的系统允许的,因为这个空间本来就系统为你分配好了。但是如果我们越界赋值[ebp+4]就会怎么?

  对!导致了EIP被覆盖,即发生了缓冲区溢出,可能有朋友要问了,你这么说有什么依据呢?我们还是回到汇编代码:

00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,44h
00401076   push        ebx
00401077   push        esi
00401078   push        edi

在开头的4个push入栈操作对应结尾了4个pop出栈操作。

00401091   pop         edi
00401092   pop         esi
00401093   pop         ebx
00401094   mov         esp,ebp
00401096   pop         ebp

00401097   ret

EBP被完好的保存了,注意到这里有个汇编指令ret,这是返回的意思,它的原理实质上等于2条汇编指令的组合:

pop EIP

jmp

将栈上的最底下的4字节空间弹栈赋值给EIP,并跳转到EIP对应的那条指令执行。而这个所谓的栈底的4个空间的内容就是在进入main函数前入栈的,目的是为了等main函数执行完后可以继续执行main之后的指令,这也就是一般的函数调用的原理(因为这里只有一个main函数,所有有些特殊,不过本质上一样的)。

而所谓的溢出本质上是我们覆盖了这段EIP对应的栈空间,然后操作系统就傻乎乎的以为这就是真实的返回地址,pop并执行了,然后就.........所以说童话里都是骗人的

这个程序很简单,但是第一次分析的时候也花了我不少力气,以后希望能更多的研究一些原理性的东西,也继续和大家分享!

最后,希望这次的ISCC能玩的开心

转载于:https://www.cnblogs.com/LittleHann/archive/2013/05/26/3100165.html

相关文章:

Spring-boot+Vue = Fame 写blog的一次小结

前言 作为一个程序员&#xff0c;总是要有一个属于自己的博客。然后作为一个造轮子的程序员&#xff0c;肯定不满足于直接使用现有的博客系统&#xff0c;于是我便自己写了一个带后台管理的博客系统。 体验地址&#xff1a; zzzzbw.cn 技术选型 作为一个Javaer&#xff0c;服务…

gitee查看当前账号_upic+gitee图床,自由书写Markdown

使用的软件Typora&#xff1a;Markdown文档编辑器(https://www.typora.io/)upic&#xff1a;图床工具(https://github.com/gee1k/uPic)创建自己的GitHub图床1 创建账号https://gitee.com/,自行创建账号就可以了和github很相似&#xff0c;但是速度更快2创建仓库内容按照自己的习…

CentOS中vsftp安装与配置

1. 安装 使用chkconfig --list来查看是否装有vsftpd服务&#xff1b; 使用yum命令直接安装&#xff1a;yum -y install vsftpd 然后为它创建日志文件&#xff1a;touch /var/log/vsftpd.log 这样简单的两个命令就完成了vsftp的安装&#xff0c;但是如果你现在想这样ftp://your_…

纸上原型设计 VS 桌面原型工具设计,你更喜欢谁?

2019独角兽企业重金招聘Python工程师标准>>> 纸上原型设计&#xff0c;作为传统的原型设计方式&#xff0c;简单快速&#xff0c;成本低廉&#xff0c;为大部分设计师所喜爱。而桌面原型工具设计&#xff0c;作为伴随电脑科技发展而出现的原型设计方式&#xff0c;快…

韩宇:CV学习路线

CV学习路线 对于刚入门CV的同学来说&#xff0c;通过看视频学习效率会比看书高&#xff0c;如下是我亲身实践较为高效的CV学习路线。 1. 计算机视觉概述 计算机视觉本身又包括了诸多不同的研究方向&#xff0c;比较基础和热门的几个方向主要包括&#xff1a; 物体识别和检测…

mysql获取删除的条数_如何从mysql表中删除数百万条记录而不会减速

有没有一种很好的方法来删除很多记录而不会减慢网站的速度&#xff1f;我需要从没有索引和主键的MySQL表中删除数百万条记录。我阅读了SO和网上的各种教程&#xff0c;基本策略是限制删除查询&#xff0c;在删除之间休眠一两秒钟&#xff0c;然后重复此过程直至完成。我也(使用…

某大型银行深化系统之二十:异常规范

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 1异常抛出与捕捉规则 1.1任何抛出异常的方法必须先声明异常 {// Constructorpublic MyClass( String name ) throws NullPointerException, llegalArgumentException {...} } 1.2异常声明后&#xf…

女朋友的Mysql练习题

2019独角兽企业重金招聘Python工程师标准>>> 一、设有一数据库&#xff0c;包括四个表&#xff1a;学生表&#xff08;Student&#xff09;、课程表&#xff08;Course&#xff09;、成绩表&#xff08;Score&#xff09;以及教师信息表&#xff08;Teacher&#xf…

中国电子学会图形化四级编程题:解密

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100&#xff0c;小马老…

python函数模块概念_python中模块和包的概念

1.模块一个.py文件就是一个模块。这个文件的名字是&#xff1a;模块名.py。由此可见在python中&#xff0c;文件名和模块名的差别只是有没有后缀。有后缀是文件名&#xff0c;没有后缀是模块名。每个文件(每个模块)都是一个独立的名称空间&#xff0c;也就是说可以在两个(多个)…

linux-glibc内存管理小结2(内存相关系统调用的实现)

在上一节ptmalloc源码分析中我们提到dlmalloc向系统申请内存的方式有两种, 对应Linux系统下分别是sbrk()与mmap()系统调用. 本节我们就来看下brk()/sbrk()与mmap()/munmap()的实现, 作为切入点来一窥内核内存管理的特点. 在正文开始之前我们先大致描述一下内核内存管理的模型. …

【组队学习】【30期】7. CV中的Transformer

CV中的Transformer 航路开辟者&#xff1a;安晟领航员&#xff1a;尚育鹏航海士&#xff1a;安晟、袁明坤、闫永强 基本信息 开源内容&#xff1a;https://github.com/datawhalechina/dive-into-cv-pytorch [第六章]内容属性&#xff1a;打磨课程内容说明&#xff1a;17年在…

天堂Lineage(單機版)從零開始架設教學

此篇文章 內容大部份連結 已失效&#xff0c; 我已另外寫一篇更快速安裝的文章。 前言: 網路遊戲天堂在數年前&#xff0c;被日本人分析封包的方式。模擬出Lineage server端的行為。 不像天堂II&#xff0c;及RO是由內部洩漏出Server端程式。也由於天堂Server的熱門以至於私服人…

python爬虫天气实例scrapy_python爬虫之利用scrapy框架抓取新浪天气数据

scrapy中文官方文档&#xff1a;点击打开链接Scrapy是Python开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛&#xff0c;可以用于数据挖掘、监测和自动化测试&#xff0c;Scrapy吸引人的地方在于它是一…

中国电子学会图形化四级编程题:绘制雪花

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100&#xff0c;小马老…

C++ Primer 读书笔记 - 第十三章

1. Initialization和Assignment不一样。其中Initialization包括direct-initialization (如A a(...))和copy-initialization (如 A a b;) 注意A a b为copy-initialization&#xff0c; 而A a; A b; a b;为Assignment。 2. We cannot copy objects of the IO types, so we can…

Linux-LNMP(静态元素不记录日志和过期时间,防盗链,解析php,代理,支持ssl)

Linux-LNMP-Nginx配置二 静态文件不记录日志和过期时间Nginx防盗链Nginx访问控制Nginx解析php相关配置Nginx代理Nginx负载均衡SSL原理生成SSL密钥对Nginx配置SSL静态文件不记录日志和过期时间在Nginx服务器的虚拟主机配置文件(/usr/local/nginx/conf/vhost/norecord.conf)中定义…

mysql数据库优化命令_MySQL数据库优化总结

一个&#xff1a;MySQL标准数据库优化注意事项1.数据库设计(表设计合理)三范式(规范的模式)三范式包含&#xff1a;第一范式&#xff1a;1NF是对属性的原子性的约束。要求属性具有原子性&#xff0c;不可再分解。(仅仅要是关系型数据库都满足)第二范式&#xff1a;2NF是记录的唯…

C++ 卸载程序

目的&#xff1a;用C写一个自己的卸载程序来完成程序的卸载工作&#xff0c;同时运行后要删除卸载程序本身&#xff0c;并删除卸载程序所在的文件夹。 注&#xff1a;在程序退出的时候写上 自己的卸载代码。 // FileName: Uninstall.h #pragma onceclass CUninstall { private:…

《火星救援VR》原班人马打造全新AR游戏,让可爱小飞龙伴随你左右

曾开发了《火星救援》的VR团队即将发布AR游戏《Follow Me Dragon》&#xff0c;让可爱小飞龙“融入”真实世界。 开发商The Virtual Reality Company曾经打造过风靡一时的《火星救援》VR游戏。今日&#xff0c;他们刚刚发布了一款名为《Follow me Dragon》的AR游戏。 目前&…

【组队学习】【30期】时间序列分析

时间序列分析 航路开辟者&#xff1a;李岳昆、易远哲领航员&#xff1a;王洲烽航海士&#xff1a;李岳昆、易远哲 基本信息 开源内容&#xff1a;https://github.com/datawhalechina/team-learning-data-mining/tree/master/TimeSeries内容属性&#xff1a;打磨课程内容说明…

mysql二进制日志管理_MYSQL二进制日志管理脚本

MYSQL二进制日志管理脚本脚本原理是每小时对进行flush生成新的二进制日志&#xff0c;将二进制日志备份至NFS&#xff0c;并压缩存放&#xff1a;#!/bin/bash#Purpose:管理二进制日志&#xff0c;每小时刷新二进制日志&#xff0c;并将日志复制到nfs服务器上&#xff0c;方便以…

iPhone App开发实战手册学习笔记(5)之IOS常用机制

1 前言 在IOS开发中&#xff0c;相信大家一定听说过委托&#xff0c;数据源&#xff0c;target&#xff0c;action等等&#xff0c;今天我们就来简单的学习一下这些内容。 2 详述 2.1 委托和数据源 大家是否曾经有不知道如何去执行一项任务的时候&#xff1f;或许是修理一台洗碗…

Datawhale组队学习周报(第035周)

希望开设的开源内容 目前Datawhale的开源内容分为两种&#xff1a;第一种是已经囊括在我们的学习路线图内的Datawhale精品课&#xff0c;第二种是暂未囊括在我们的学习路线图内的Datawhale打磨课。我们根据您的投票来确定精品课程的排期&#xff0c;打磨课程一旦完成&#xff…

【Project Euler】530 GCD of Divisors 莫比乌斯反演

【题目】GCD of Divisors 【题意】给定f(n)Σd|n gcd(d,n/d)的前缀和F(n)&#xff0c;n10^15。 【算法】莫比乌斯反演 【题解】参考&#xff1a;任之洲数论函数.pdf 这个范围显然杜教筛也是做不了的&#xff0c;而且考虑直接化简f(n)也遇到了困难&#xff0c;所以考虑将前缀和的…

php mysql 星级评分_jQuery+PHP实现星级评分

本例实现的效果&#xff1a;过渡动画显示评分操作。及时更新平均得分和用户所评的分数。后台限制用户重复评分操作&#xff0c;并在前端及时显示。XHTMLHTML结构分为用于显示灰星星div#big_rate、亮星星div#big_rate_up、分数span#s及span#g和提示信息div#my_rate。CSS.rate{wi…

Xt800、DEFY自带号码归属地更新包,更新至2013.4【数据总数278360条】

总结了http://bbs.gfan.com/forum.php?modviewthread&tid5603346&extrapage%3D1&page1和http://bbs.mfunz.com/thread-706813-1-1.html&#xff0c;经测试在我的XT800上可用&#xff0c;可以把其他的第三方来电软件通通删掉了。 特点&#xff1a;能够显示运营商&a…

中国电子学会图形化四级编程题:程序优化

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100&#xff0c;小马老…

当代艺术遇上虚拟现实:幻境视界打造基业VR美术馆

VR展览也许并不少&#xff0c;但专业的艺术展却难得一见。幻境世界周志强希望能借助VR技术&#xff0c;实现“一地办展、全球同展、永不闭馆”&#xff0c;更好地传播当代艺术。 从米开朗琪罗到库尔贝&#xff0c;再到雷诺阿&#xff0c;大师们不断找到新的艺术语言来阐释人体…

python二叉搜索树建立_700. 二叉搜索树的搜索(Python)

题目难度&#xff1a;★☆☆☆☆类型&#xff1a;二叉树给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 NULL。例如&#xff0c;给定二叉搜索树:4/ \2 7/ \1 3和值: 2你应该返回…