吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9581|回复: 16
收起左侧

[调试逆向] 逆向工程日记之缓冲区溢出的基本原理(一)

  [复制链接]
折木穆 发表于 2019-9-30 21:49

@TOC

前言

Hello,各位广大的网友们好。笔者为大二在校大学生,软件学院。为践行费曼学习法,并在前辈的建议下开始写自己的一系列博客,网上对于缓冲区溢出的例子基本在与Linux环境下操作。对未了解Linux内核以及常见操作指令的新手并不友好。鉴于此写下此文。

实验前提

  1. 实验环境 :windows 10;
  2. 使用工具 :IDA pro , OllyDBG,vc6.0;
  3. 目标软件 :test1.exe , test2.exe

所需基础

基础汇编指令

简单C语言基础

数据结构(仅堆栈)

即使上面基础缺失,本文任有大量的注释及解释帮助理解。

概要

通过编写两个C例程序,使用工具OD,IDA pro进行逆向分析。针对汇编语句中CALL机制剖析缓冲区溢出的基本原理。

实验开始

编写实验程序text1.exe  , text2.exe

text1.exe中C代码如下:

#include<stdio.h>  //引入头文件
#include<string.h>

char name[] = "zhemu";  //定义全局变量

int main()            //返回值 主函数main()
{
    char buffer[8];   //开辟8个字节的空间用来存储变量name
    strcpy(buffer,name);  //内置函数(作用):将变量name内容赋值给buffer变量
    printf("%s\n",buffer);  //输出在控制台
    getchar();               //方便观察 作用:等待用户输入按键
    return 0;                //返回值
}

text1.c中 ,变量name赋值给buffer后并未引起缓冲区溢出

text2.exe中C代码如下:

#include<stdio.h>  //引入头文件
#include<string.h>

char name[] = "zhemuzhemu";  //定义全局变量 !!多了个zhemu

int main()            //返回值 主函数main()
{
    char buffer[8];   //开辟8个字节的空间用来存储变量name
    strcpy(buffer,name);  //内置函数(作用):将变量name内容赋值给buffer变量
    printf("%s\n",buffer);  //输出在控制台
    getchar();               //方便观察 作用:等待用户输入按键
    return 0;                //返回值
}

text1.c中 ,变量name赋值给buffer后引起缓冲区溢出

对text1.exe进行逆向分析。

将vc6.0生成的debug版本exe拖入OllyDBG进行逆向分析

OllyDBG载入方式:
1.鼠标拖动exe进入到OD控件区域
2.文件-附加-选择运行中的进程
第一次载入
!由于新版本的Visual Studio,微软加入GS机制,防止缓冲区溢出的情况出现

由上图:004015B0地址为软件初始运行地址,并非main函数的起始地址。可通过F7/F8一步步运行至main函数所在地址。过于繁琐,所以采用IDA快速定位main函数所在地址,如下图:

在这里插入图片描述
快速定位main函数所在地址
1.双击进入main
2.右键选择Text View,初始默认为Graph View
可得main函数地址如下图:
在这里插入图片描述
4.IDA 快捷键Ctrl+x 定位上一层交叉引用。(简单理解就是从哪里来 ,谁调用它)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由此可知,开始main函数上一个地址00401693,重返OD进行堆栈溢出研究
在这里插入图片描述
通过OD中快捷键Ctrl+G快速定位到call函数上一条指令地址,快捷键F2对00401693下断点,快捷键F9让调试直接运行到此处代码。 同时也可以按F4运行于此!

在这里插入图片描述
F8步过程序,留意右下角栈区调用情况。
调用CALL函数:
1.将CALL下一个地址压入栈(00401694)
2.jmp CALL

在这里插入图片描述
由上图: 压入栈区为地址(00401694)返回地址。重要关键地方
笔者在右下角栈区设置转换为ASCII数据 方便观察

在这里插入图片描述
新手可以忽略之前栈平衡以及栈区开辟空间指令,由地址00401030可知,此时与C语言代码对应开始,将ASCII压入栈区,并进行strcpy赋值操作。

对汇编认识可以初步认识此步骤,重点在于调用完CALL之后返回到初始地址下一条

来到call函数调用返回所在位置:

在这里插入图片描述
可以看出retn返回的地方栈区栈顶指向的地址为:00401699 call函数调用完下一指令

OK,到此为止我们了解了一个CALL函数调用的基本过程,直接进入text2.exe分析,当堆栈溢出栈区会发生什么呢?

对text2.exe进行逆向分析。

步骤不多累赘与text1.exe完全一摸一样,唯一不一样在于栈区返回地址被溢出(占用)
在这里插入图片描述
由上图可知:
1.原本改返回值:00401699地址被占用 且指向错误的地址(或不应该的地址)

缓冲区溢出漏洞原理总结

至此,大家应该已经了解了缓冲区溢出漏洞的原理,它就是因为我们输入了过长的字符,而缓冲区本身又没有有效的验证机制,导致过长的字符将返回地址覆盖掉了,当我们的函数需要返回的时候,由于此时的返回地址是一个无效地址,因此导致程序出错。
那么依据这个原理,假设我们所覆盖的返回地址是一个有效地址,而在该地址处又包含着有效的指令,那么我们的系统就会毫不犹豫地跳到该地址处去执行指令。因此,如果想利用缓冲区溢出的漏洞,我们就可以构造出一个有效地址出来,然后将我们想让计算机执行的代码写入该地址,这样一来,我们就通过程序的漏洞,让计算机执行了我们自己编写的程序。

本文其中例子与实例深受i春秋启发,并进行归纳总结,笔者才学疏浅,若有错误之处欢迎指出

免费评分

参与人数 11威望 +2 吾爱币 +14 热心值 +10 收起 理由
零零大人 + 1 谢谢@Thanks!
wakawaka_0 + 1 用心讨论,共获提升!
Hmily + 2 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
q59541511 + 1 + 1 终于知道啥是缓冲区溢出漏洞
skrboy + 1 谢谢@Thanks!
qaz003 + 1 + 1 谢谢分享,麻烦移步13楼
sunnylds7 + 1 + 1 热心回复!
yns + 1 + 1 我很赞同!
天空藍 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
s_qiu + 1 + 1 用心讨论,共获提升!
snatch2null + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 折木穆 发表于 2019-10-4 09:41
CalvinMcCain 发表于 2019-10-4 05:20
楼主能否提供test1.exe test2.exe资源链接,想自己动手实践学习一下

相应的代码都在文章中,可以自己下载个C语言的编译器自己动手操作一下,效果会好很多
 楼主| 折木穆 发表于 2019-10-4 14:15
qaz003 发表于 2019-10-4 12:39
谢谢分享,辛苦了。。。
感觉上面的地方有点笔误。。
复制粘贴惹的祸

  感谢纠正

免费评分

参与人数 1热心值 +1 收起 理由
qaz003 + 1 热心回复!

查看全部评分

xixicoco 发表于 2019-10-2 19:13
baolei1988 发表于 2019-10-2 19:38
原理很重要
感谢讲解
死循环 发表于 2019-10-2 20:20
感觉可以
a1545515 发表于 2019-10-3 14:54
学习一下菜鸟路过
SherryMefum 发表于 2019-10-3 15:17
据说高手都用VC6。
隐与匿 发表于 2019-10-3 16:00

谢谢分享啦
yns 发表于 2019-10-3 16:00
很详细,多谢楼主了
CalvinMcCain 发表于 2019-10-4 05:20
楼主能否提供test1.exe test2.exe资源链接,想自己动手实践学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 23:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表