how2heap-2.23-03-fastbin_dup_consolidate

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

int main() {
  void* p1 = malloc(0x10);
  strcpy(p1, "AAAAAAAA");
  void* p2 = malloc(0x10);
  strcpy(p2, "BBBBBBBB");
  fprintf(stderr, "申请两个 fastbin 范围内的 chunk: p1=%p p2=%p\n", p1, p2);
  fprintf(stderr, "先 free p1\n");
  free(p1);
  void* p3 = malloc(0x400);
  fprintf(stderr, "去申请 largebin 大小的 chunk,触发 malloc_consolidate(): p3=%p\n", p3);
  fprintf(stderr, "因为 malloc_consolidate(), p1 会被放到 unsorted bin 中\n");
  free(p1);
  fprintf(stderr, "这时候 p1 不在 fastbin 链表的头部了,所以可以再次 free p1 造成 double free\n");
  void* p4 = malloc(0x10);
  strcpy(p4, "CCCCCCC");
  void* p5 = malloc(0x10);
  strcpy(p5, "DDDDDDDD");
  fprintf(stderr, "现在 fastbin 和 unsortedbin 中都放着 p1 的指针,所以我们可以 malloc 两次都到 p1: %p %p\n", p4, p5);
}

先分配两个chunk

在这里插入图片描述
第一个chunk用于演示malloc_consolidate后的double-free
第二个chunk用于观察prev_inuse,防止与top chunk合并

释放第一个chunk a

在这里插入图片描述
现在第一个chunk被放置到fastbin中

稍等一下,先看一下main_arean->bins初始化数据的含义

在这里插入图片描述

申请一个large chunk

为了分配这个large chunk。因为large chunk需要的空间较大,会尝试将fastbin中的chunk合并转移到unsortedbin,并将相邻下一chunk的pre_in_use置0。后面遍历unsortedbin得不到使用,就会放到smallbin中

  else
    {
      idx = largebin_index (nb);
      if (have_fastchunks (av))
        malloc_consolidate (av);
    }

第一个chunk malloc(10)已不在fastbin头部了,同时chunk a链入了small bin中
在这里插入图片描述

再次释放第一个chunk a

因为这个chunk的大小属于fastbin,且已不在fastbin头部,可以被释放。
被释放到fastbin中,第一个chunk fd数据被清理掉(这里不影响small bin的链接)。
在这里插入图片描述
现在small bin和fastbin都存储了chunk a,可以申请申请两次。

利用场景

在通过申请large chunk时,会触发malloc_consolidate,会将chunk a放入到unsorted bin->small bin,此时下一个chunk b的prev_inuse清零
之后将chunk a进行double-free,再申请回来,由于不是从small bin申请回来的,所以下一个chunk b的prev_inuse还是零
现在就可以在chunk a中伪造chunk,释放下一个chunk b,从而产生unlink,通过unlink进行利用

源码分析可以看这里:https://www.lazenca.net/display/TEC/fastbin_dup_consolidate%5BKorean%5D±+Restoring
相关pwn题:
https://blog.csdn.net/seaaseesa/article/details/105856878
https://blog.csdn.net/weixin_44309300/article/details/131027082

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值