Windwos堆管理体系以及溢出利用
《0day安全》学习笔记,主要讨论WIndows2000~WIndowsSP1平台的堆管理策略。
0X01 堆与栈的区别
栈空间是在程序设计时已经规定好怎么使用,使用多少内存空间。典型的栈变量包括函数内部的普通变量、数组等。栈变量在使用的时候不需要额外的申请操作,系统栈会根据函数中的变量声明自动在函数栈中给其预留空间。栈空间由系统维护,它的分配和回收都由系统来完成,最终达到栈平衡。所有这些对程序员都是透明的。
堆具备以下特性:
1.堆是程序运行时动态分配的内存。所谓动态是指所需内存的大小在程序设计时不能预先决定的,需要在程序运行时参考用户的反馈。
2.堆在使用时需要程序员使用专用的函数进行申请,如C语言中的malloc等函数、C++中的new函数等都是最常见的分配堆内存的函数。堆内存申请有可能成功,也有可能失败,这与申请内存的大小、机器性能和当前运行环境有关。
3.一般用一个堆指针来使用申请的内存,读、写、释放都是通过这个指针来完成。
4.使用完毕后要通过堆释放函数进行回收这片内存,否则会造成内存泄漏。如free,delete等。
0X02堆的数据结构与管理策略
对于管理系统来说,响应程序的内存使用申请就意味着要在“杂乱”的堆区中辨别哪些内存是正在被使用的,哪些内存是空闲的,并最终“寻找”到一片“恰当”的空闲内存区域,以指针形式返回给程序。
堆块:堆区额内存按不同大小组织成块,以堆块为单位进行标识,而不是传统的按字节标识。一个堆块包括两个部分:块首和块身。块首是一个堆块头部的几个字节,用来标识这个块首自身的信息,例如,大小、空闲或占用。块身是紧跟在块首后面的部分,也是最终分配给用户使用的数据区。
注意:块管理系统返回的指针一般是块身的起始位置,连续申请内存就是发现返回的内存之间存在“空隙”,那就是块首。
堆表:堆表一般位于堆区的起始位置,用于检索堆区中所有堆块的总要信息,包括堆块的位置、堆块的大小、空闲或占用等。 堆表的数据结构决定了整个堆区的组织方式。堆表往往不知一种数据结构:如平衡二叉树等。
堆的内存组织如图所示:

在Windows中占用态的堆被使用它的程序管理,堆表只是管理空闲态的堆块。
其中最重要的堆表有两种:空闲双向链表Freelist(空表)以及快速单项链表Lookaside(快表)
空表:
空闲堆块块首包含一对指针,这对指针把空闲堆块组织成双向链表。按照堆块大小的不同,空表总共被分成128条。
堆区一开始的堆表区中有一个128项的指针数组,被称作空表索引。该数组每一项包含两个指针,用于标识一条空表。
比如空表的第二项free[1]标识了项中所有大小为8字节的空闲堆块,之后每隔索引指示的空闲堆块递增8字节,free[2]标识16字节,free[3]标识24字节空闲堆块,free[127]标识1016字节空闲堆块。
空闲堆块大小 = 索引项 * 8字节
把空闲堆块链入不同的空表,可以方便管理。空表第一项free[0]链入所有大于等于1024字节的堆块(小于512K)。这些堆块按照各自的大小在零号空表中升序排列。

快表
快表是Windows用来加速分配而采用的一种堆表。这类单向链表中不会发生堆块合并(其中空闲堆块块首置为占用态)。
快表也有128条,组织结构与空表类似,只是堆块按单链表组织,而且每条快表最多只有4个节点。

0X03 堆的操作
堆得操作分为:堆的分配、堆得释放、堆得合并。分配与释放是由程序执行的,堆的合并是由堆管理系统自动完成的。
1.堆的分配
堆分配分三类:快表分配,普通表分配,零号空表(free[0])分配。
从快表分配:寻找大小到大小匹配的空闲堆块、将其状态修改为占用态、把它从堆表中卸下,最后返回一个指向堆块块身的指针给程序使用。
普通表分配:首先寻找最优的空闲块分配,若失败,则寻找次优的空闲块分配。
零号空表分配:按照大小升序链着大小不同的空闲块,找最优结果。
注意:当空表中找不到最优的堆块时,会发生次优分配,即从大块按照请求的大小精确割出一块进行分配,然后给剩下部分重新标注块首,链入空表。
2.堆块释放
将堆块状态改为空闲,链入相应的堆表。所有的释放块都链入堆表的末尾。
3.堆块合并
经过反复的申请与释放,堆区产生很多内存碎片。堆管理系统发现两个空闲堆块彼此相邻,就会进行堆块合并。 包括将两个块从空闲链表中卸下、合并堆块、调整合并后大块的块首信息、将新块重新链入空闲链表。
几个注意点:
1.快表空闲块被置为占用态,所以不会发生堆块合并操作。
2.快表只有精确分配时才会分配。
3.分配与失败有限使用快表,失败用空表。
0X04 DWORD SHOOT 堆溢出利用原理
堆溢出的利用的精髓就是精心构造的数据溢出下一个堆块的块首,改写块首的前向指针和后向指针,然后在分配、释放、合并等操作发生时获得一次向内存任意地址读写任意数据的机会。
原理:
Int remove(ListNode * node)
{
node->blink->flink = node -> flink;
Node->flink->blink= node ->blink;
Return0;
}

那么四个字节的利用我们可以做什么呢?
1.内存变量:修改能影响程序执行的重要标志变量,例如更改身份验证函数的返回值。
2.代码逻辑:修改代码段重要函数关键逻辑,如程序分支处的判断逻辑。
3.函数返回地址:堆溢出也可以利用DWORD SHOOT更改函数返回地址。
4.攻击异常处理:程序产生异常,Windows转入异常处理机制,包括SEH等。
5.函数指针:如C++的虚函数调用。改写这些指针后,函数调用往往就可以劫持进程。
6.PEB中线程同步函数入口地址:每个进程PEB存放着一对同步指针,指向RtlEnterCriticalSection()和RtlLeaveCriticalSection(),并且被ExitProcess()函数调用。
Windwos堆管理体系以及溢出利用的更多相关文章
- 旧书重温:0day2【10】第五章 堆溢出利用2
好久没有发帖子啦!最近一直很忙!但是还是抽空学习啦下! 前段时间匆匆忙忙的把0day2上的堆溢出实验做啦! 可能当时太浮躁啦,很多细节没注意!结果:实验结果很不满意!所以就有啦这一篇!! 上一篇是发布 ...
- 实用算法系列之RT-Thread链表堆管理器
[导读] 前文描述了栈的基本概念,本文来聊聊堆是怎么会事儿.RT-Thread 在社区广受欢迎,阅读了其内核代码,实现了堆的管理,代码设计很清晰,可读性很好.故一方面了解RT-Thread内核实现,一 ...
- Windows编程中的堆管理(过于底层,一般不用关心)
摘要: 本文主要对Windows内存管理中的堆管理技术进行讨论,并简要介绍了堆的创建.内存块的分配与再分配.堆的撤销以及new和delete操作符的使用等内容. 关键词: 堆:堆管理 1 引言 在大多 ...
- windows 堆管理
windows堆管理是建立在虚拟内存管理的基础之上的,每个进程都有独立的4GB的虚拟地址空间,其中有2GB的属于用户区,保存的是用户程序的数据和代码,而系统在装载程序时会将这部分内存划分为4个段从低地 ...
- 面对 to B 业务该如何构建研发管理体系?
未来离我们越来越近,而过去并未走远,我们发现科技公司2B业务兴起,腾讯认为互联网下半场属于产业互联网,需要进行一次重要的战略升级.它们在国庆节最后一天进行新一轮组织架构调整,最亮眼的就是新成立云与智慧 ...
- C++内存管理4-Windows编程中的堆管理(转)
1 引言 在大多数Windows应用程序设计中,都几乎不可避免的要对内存进行操作和管理.在进行大尺寸内存的动态分配时尤其显的重要.本文即主要对内存管理中的堆管理技术进行论述. 堆(Heap)实际是位于 ...
- linux 系统磁盘管理体系
目录 linux 系统磁盘管理体系 一.磁盘的基本概念 二.磁盘的内部结构 三.磁盘的外部结构 四.磁盘的接口及类型 五.fdisk磁盘分区实践 六.gdisk 分区 七.parted 高级分区工具. ...
- ITIL的考核管理体系
是的,我们ITIL的考核管理体系,大概是从几个方面进行考核的.阿里巴巴作为一个上市公司,是全球的B2B电子商务的领先者,那么作为我们的运维部,保证完整的可用性是首当其冲的.我们的ITIL考核体系里面, ...
- ISO/IEC 27001 信息安全管理体系认证
一. 信息安全管理体系标准业务介绍 1. 背景介绍 信息作为组织的重要资产,需要得到妥善保护.但随着信息技术的高速发展,特别是Internet的问世及网上交易的启用,许多信息安全的问题也纷纷出现:系统 ...
随机推荐
- [atARC122F]Domination
如果一个红石头在另一个红石头的左下方(包括左和下),那么在后者的限制满足时,前者也一定满足,因此可以删去前者,再将其按照$rx_{i}$排序,即有$rx_{1}<rx_{2}<...< ...
- [cf643G]Choosing Ads
首先对于$p>50$,有经典的做法,即不断删去区间中不同的两数,最终剩下的即为出现次数超过一半的数(或没有),用线段树维护即可 那么对于$p\le 50$,类似的,即删去区间中不同的$\lflo ...
- char数据可以放入int[]中会自动转换
int[] ary ={'b','c','a','d','e','f'};System.out.println(ary[0]);//98String str = new String(ary, 2, ...
- springboot 配置多数据源实例代码(分包方式)
目录 1.数据库 2.pom与yml 2.1.pom中的依赖部分 2.2.yml数据库配置部分 3.数据源配置类 DataSourceConfig 3.1.DataSourceConfig1.java ...
- CF1511E Colorings and Dominoes
考虑计数拆开贡献. 因为在一个方案中一个格子最多只会贡献一次,那么不妨反过来求这个格子贡献了多少次. 然后发现,行列独立,那么我们单独计算红蓝色,即可. 一个偶数块贡献当且仅当前面也是偶数块. 然后显 ...
- Codeforces 1276D - Tree Elimination(树形 dp)
Codeforces 题面传送门 & 洛谷题面传送门 繁琐的简单树形 dp(大雾),要是现场肯定弃了去做 F 题 做了我一中午,写篇题解纪念下. 提供一种不太一样的思路. 首先碰到这样的题肯定 ...
- 对 SAM 和 PAM 的一点理解
感觉自己学 SAM 的时候总有一种似懂非懂.云里雾里.囫囵吞枣.不求甚解的感觉,是时候来加深一下对确定性有限状态自动机的理解了. 从 SAM 的定义上理解:SAM 可以看作一种加强版的 Trie,它可 ...
- 【MetDNA】基于代谢反应网络的大规模代谢物结构鉴定新算法
代谢是生命体内化学反应的总称,其所包含的代谢物变化规律可直接反映生命体的健康状态.非靶向代谢组学(untargeted metabolomics)可以在系统水平测量生命体内生理或病理状态下所有代谢物的 ...
- C语言 字符串指针和字符串数组使用区别
字符串指针和字符串数组使用区别 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 ...
- Oracle-创建新表,创建备份表,对表中插入多条数据
一.创建新表 0.基本语法 create table 表名称(id varchar2(50) primary key ,name char(200) not null,phone number(11) ...