缓冲区溢出笔记(2.0)
来源:互联网 发布:新网域名别名解析 编辑:程序博客网 时间:2024/05/08 15:41
首先得会内存、寄存器还有程序运行的规则。
存储知识:
文件地址(File Offset):数据在PE文件中的地址,文件在磁盘上存放时相对于文件开头的偏移;
虚拟内存地址:用户程序看到的存储空间,每个进程都有4G虚拟空间,以下说的内存、所有的存储空间都是虚拟内存;
物理内存地址:操作系统才能看到,用户程序不能接触;
这三个地址要层层映射
内存:
代码区:存放二进制代码
数据区:存储全局变量
堆区:动态内存空间(由程序员分配)
栈区:存放函数调用关系(缓冲区溢出就在这里发生)(由编译器分配)
重点研究栈的结构:
栈帧:每个函数有自己的栈帧,只有被调用的函数才会在系统栈开辟栈帧,调用完毕将弹出栈帧
两个寄存器(用于标示当前正在执行的函数的栈帧):
ebp:指向栈顶的底部
esp:指向栈顶的顶部
发生函数调用时栈帧的创建过程:
参数入栈
返回地址入栈
保存当前栈帧状态,也就是主调函数栈帧的ebp和esp,一般情况下只要ebp就行
把esp寄存器内容装入ebp寄存器,即创建被调用函数的栈帧作为当前栈帧
根据被调用函数需要的变量情况开辟一定大小的空间,用esp减去空间就得到当前栈帧的栈顶(从栈底到栈顶内存地址从高到底)
注意:返回地址是被调函数被调用指令的下一条指令地址,是代码区的地址。
被调函数执行结束之后弹出栈的过程是这样的:
1.esp加上局部变量占用的空间
2.弹出ebp,ebp指向调用者函数
3.返回地址存入指令寄存器eip
4.esp加上两个内存单元的大小也就是之前ebp和返回地址占用的空间
5.esp加上参数占用的空间。这样就完成了被调函数和调用者函数栈帧的转换。
明白了这些就可以开始缓冲区溢出小实验了:
#include<stdio.h>void hack(){printf("hello");//_exit(0);return;}int main(){int a[0]; a[3]=0x004016b6;return 0;}
看了下图就明白了
我们知道数组是从a[0]的位置开始向后移动的,那么a[3]的位置(如图的话应该是a[2]才对,但这里a[3]才行,这是视具体的机器而定的因为还有编译优化的问题)正好是返回地址,但是给a[3]赋值为hack()函数的起始地址那么main函数就会跳转到hack()的地址执行hack函数。注意main函数也有返回地址。另外这里为什么输出两个“hello world”我还不清楚原因,如果把hack()函数的“return”改为"_exit(0)"就只输出一个"hello world",这是为什么呢,如果有大神知道原因还请赐教。
hack()函数的地址先通过正常调用一次然后用IDA工具很容易就找到了。反汇编软件爆破就要用到上面的三个存储地址的映射关系。
没想到写得这么累。
大概先这样。
- 缓冲区溢出笔记(2.0)
- 缓冲区溢出(笔记)
- 缓冲区溢出学习笔记
- 缓冲区溢出学习笔记
- 缓冲区溢出学习笔记
- 【学习笔记】缓冲区溢出
- 求职笔记-操作系统-缓冲区溢出
- 缓冲区溢出笔记之---STACK溢出
- 缓冲区溢出笔记之---STACK溢出
- 缓冲区溢出笔记之---STACK溢出
- (未完)缓冲区溢出
- 缓冲区溢出(1)
- 安全漏洞(缓冲区溢出)
- 缓冲区溢出笔记(2006年6月8日)
- 缓冲区溢出笔记(2006年6月9日)
- 缓冲区溢出笔记(2006年6月12日)
- 缓冲区溢出笔记(2006年6月13日)
- OWASP WebGoat---安全测试学习笔记(五)---缓冲区溢出
- 第三章 16题
- Linux下安装Mysql
- 简单的对话框
- HihoCoder第七周:完全背包问题
- 序列帧动画 TOM猫
- 缓冲区溢出笔记(2.0)
- HDOJ 圆桌会议 1214
- SQL多表连接查询(详细实例)
- 关于数据挖掘其中的一些基本概念的理解
- SD卡驱动程序解析
- 【leetcode】Triangle
- Blogの始め
- linux下find 命令的使用
- 震惊的事实--数组与指针不相同?