学习 fastbin_dup_consolidate

借着 how2heap 这个专题,我们来研究一下 glibc2.25 中的 malloc_consolidate

0X00 例子

#include 
#include 
#include 

int main() {
  void* p1 = malloc(0x40);
  void* p2 = malloc(0x40);
  fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
  fprintf(stderr, "Now free p1!\n");
  free(p1);

  void* p3 = malloc(0x400);
  fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
  fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
  free(p1);
  fprintf(stderr, "Trigger the double free vulnerability!\n");
  fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
  fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", malloc(0x40), malloc(0x40));
}

这个例子就是告诉我们,在分配 large bin chunk 的时候,会调用 malloc_consolidate(),这个函数会遍历所有的 fastbin 把里面的 chunk 该合并合并,该清楚使用就标志清楚使用标志,然后全部插入 unsorted bin 中。

在下一次 free 的时候,判断是不是 double free 仅仅根据从同一个大小的 fastbin 中拿出第一个 bin,比较地址是不是相同

而我们的 chunk 早到 unsorted bin 中去了。所以为 0。所以现在 fastbin 和 unsorted bin 中都有同一个 chunk

也就是我们可以把它 malloc() 出来两次

0X01 动手调试

调试一下,做个纪念

直接进入 malloc(400) 中:

学习 fastbin_dup_consolidate_第1张图片

进入 _int_malloc 中:

学习 fastbin_dup_consolidate_第2张图片

重点来了,进入 malloc_consolidate 中:

学习 fastbin_dup_consolidate_第3张图片

maxfb 是最大 size 的 fastbin 的地址,fb 是最小 size 的 fastbin 的地址,下面那个循环正是开始遍历,所有的 fastbin

学习 fastbin_dup_consolidate_第4张图片

由于现在就一个 fastbin 中间很多的代码都没有执行

大致意思就是把 fastbin 中所有的 chunk 拿了出来,该合并合并,该消除标记就消除标记。然后插入 unsorted bin 中

最后从 top_chunk 中分配一个 large bin chunk

我们再来看看 double free:重点都在这里

学习 fastbin_dup_consolidate_第5张图片

从相同大小的 fastbin 中拿出上一个被释放的 chunk,但是显然这里的 chunk 已经不存在了,在 unsorted bin 中了。所以 double free 被绕过了。

学习 fastbin_dup_consolidate_第6张图片

所以就会有一个 chunk 既在 unsorted bin 中又在 fastbin 中。

完结撒花。

你可能感兴趣的:(学习 fastbin_dup_consolidate)