1定义
比如有三个堆,1,2,3
其中1号堆有堆溢出漏洞,那么就可以通过1号堆写入内容将2号堆的size修改为2号堆加3号堆的大小,那么在free2号堆时就会把三号堆一起释放掉,放入bins,那么在下一次申请大小为一号加二号堆大小的的堆块时就会将这两个作为整体申请出来
2可能的利用方式
1,泄漏地址
2,泄露数据
3,覆盖指针
3 demo1
github上的how2heap,这里就展示一下程序截图吧
然后一行行往下看
首先是这一段创造三个堆空间
内容分别放1,2,3,然后
这里的p2为mem指针,-1就会指向size的位置,将size修改为0x100+0x80的大小,在释放时就会导致将后面的两个一起释放,在第二次申请一个大小为0x180-8大小的堆时就会从bins返还给用户(注意这里要加1的原因是chunk的PREV_INUSE位要占一个大小,判定前一个是否为空),此时修改合并后的堆就可以修改原来的堆,最后的结果就是不论对任意一个堆进行改写都能影响另一个堆的内容
4 demo2
然后还是一点点往下看吧
p1 = malloc(1000);
p2 = malloc(1000);
p3 = malloc(1000);
p4 = malloc(1000);
p5 = malloc(1000);
real_size_p1 = malloc_usable_size(p1);
real_size_p2 = malloc_usable_size(p2);
real_size_p3 = malloc_usable_size(p3);
real_size_p4 = malloc_usable_size(p4);
real_size_p5 = malloc_usable_size(p5);
fprintf(stderr, "\nchunk p1 浠?%p 鍒?%p", p1, (unsigned char *)p1+malloc_usable_size(p1));
fprintf(stderr, "\nchunk p2 浠?%p 鍒?%p", p2, (unsigned char *)p2+malloc_usable_size(p2));
fprintf(stderr, "\nchunk p3 浠?%p 鍒?%p", p3, (unsigned char *)p3+malloc_usable_size(p3));
fprintf(stderr, "\nchunk p4 浠?%p 鍒?%p", p4, (unsigned char *)p4+malloc_usable_size(p4));
fprintf(stderr, "\nchunk p5 浠?%p 鍒?%p\n", p5, (unsigned char *)p5+malloc_usable_size(p5));
memset(p1,'A',real_size_p1);
memset(p2,'B',real_size_p2);
memset(p3,'C',real_size_p3);
memset(p4,'D',real_size_p4);
memset(p5,'E',real_size_p5);
然后这段还是申请内存,中文可以看上面的图片,大概就申请了这几个堆块
free(p4);
*(unsigned int *)((unsigned char *)p1 + real_size_p1 ) = real_size_p2 + real_size_p3 + prev_in_use + sizeof(size_t) * 2;
这段话将p2的堆的size改成了2017(1000*2+1(标志位)+8(两个size,pre size)*2)
free(p2);
此时p2,p3被一起放入bins
p6 = malloc(2000);
real_size_p6 = malloc_usable_size(p6);
这里申请2000的原因是一个堆对齐要与16进行对齐然后还是对这个堆的修改会影响原来堆的内容