堆的学习
堆,动态增长的链表,
申请方式:常用函数申请,通过返回的指针使用,malloc()
释放方式:通过free进行释放
管理方式:需要程序员处理申请和释放
增长方向:内存从低地址向高地址
特点:
杂乱:堆区经过反复的申请,释放操作之后,原本大片连续的空闲区呈现出大小不同且空闲块和占用块交错的区域
给出一些概念:
什么是堆块:
堆区的内存按不同大小组织成的块,结构当中有块首和块身
块首:堆块头部的几个字节,标志堆块自身的信息(本块的大小,本块的空闲或者占用)
块身:存储的区域
什么是堆表:
位于是在堆区的起始位置,索引堆区中所有堆块的重要消息(包括堆块中的位置,堆块的大小,空闲还是占用)
在Windows当中,被占用的堆块由程序进行索引,而空闲的堆块由堆表进行索引
堆表分为两种:
空表(空闲双向链表Freelist)
空闲堆块的块首包含一对重要的指针,用于将空闲堆块组织成双向链表
里面有128个指针数组,成为空表索引,数组的每一项包含两个指针,用于标志一条空表
free[0]存储的是堆的大小为1k-512k的堆块
free[1]...[n]之后的存储的是堆的大小为n*8字节大小
快速单向链表(Lookaside)
Windows加快堆块分配而采用的一种堆表,不会发生堆块合并(空闲块的块首被设置成为占用态,防止合并)
结构和空表类似但是按照单链表进行组织,块表总是初始化为空,每个块表当中4个结点,很容易就填满
堆当中的操作
堆块分配:
快表分配:寻找大小匹配的块,将其状态改为占用态,然后返回一个执行堆块块身的指针给程序使用
普通空表分配:最优,次优
零号空表分配:反向能否满足要求,能的话正想
找零钱:如果空表中无法匹配到最优的堆块,一个比较大的堆块就会用于分配,会按照请求割一部分,将剩下的注入块首,链入空表
注意:块表精确匹配的时候才会分配(所以不存在找零钱现象)
堆块释放:
改为空闲,链入
堆块合并:
卸下 合并 调整合并的块首信息
什么是双向链表?
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。
所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
fgets函数能造成缓冲区溢出吗?
能够造成缓冲区的溢出
堆分配函数:
在windows函数下面使用nrdll.dll中的RtlAllocateHeap()函数进行分配,这个函数也是在用户态能够看到的堆分配函数
2018 10 24. pwn的学习堆的学习,堆块,堆表的概念,堆当中的操作,什么是双向链表,堆分配函数,fgets函数能造成溢出吗?
最新推荐文章于 2023-09-15 22:30:44 发布