堆漏洞挖掘:09---chunk的实际大小、最低大小、 mchunk_size成员

struct malloc_chunk {
 
  INTERNAL_SIZE_T      mchunk_prev_size;
  INTERNAL_SIZE_T      mchunk_size;
 
  struct malloc_chunk* fd;
  struct malloc_chunk* bk;
 
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
 
};

一、chunk的实际大小

  • 当用户通过malloc函数申请堆内存时,可以使用的内存的起始地址是从fd成员开始的,所以用户无法访问结构体的前两个成员
  • 当用户申请size大小的堆块时,在glibc中本质上是申请了size+16大小(64位系统中)的内存,因为要加上前两个成员
  • 例如:malloc(0x10);申请了0x10大小的堆内存,本质上在glibc中申请了0x10+0x10=0x20大小的空间
  • 前面文章介绍过chunk的mchunk_prev_size成员的合并操作,所以chunk的实际大小还要配合这个规则:https://blog.csdn.net/qq_41453285/article/details/97158973
  • 总结:chunk的实际大小=malloc的大小+chunk的前两个成员+mchunk_prev_size成员的合并操作+chunk对齐规则

演示案例:

#include 
#include 
#include 

int main()
{
    int size=0x10;
    
    void *p=malloc(size);
    printf("%p\n",p);
    sleep(0);  //只为了打断点使用,无其他用处
    free(p);    
    
    return 0;
}
  • 第一步:在sleep处打断点

  • 第二步:r运行程序,可以看到printf打印的p的地址为0x602010,代表我们可以访问的p的地址是从0x602010开始的,而第三步的图中显示我们申请的堆块是从0x602000开始的,这就验证了我们程序不可以访问struct malloc_chunk结构体的前两个成员(加起来为0x10大小)

  • 第三步:通过heap查看当前程序的所有堆块

0x602430是程序的“top chunk”,0x602020是printf打印时申请的缓冲区堆空间,0x602000才是我们通过malloc申请的堆chunk

可以看到0x602000与0x602020之间相差0x20,说明即使我们malloc了0x10的空间,在glibc中实际上申请了0x10+0x10=0x20的堆chunk

size成员为33(0x20+0x1),因为该chunk的PREV_INUSE位为1

堆漏洞挖掘:09---chunk的实际大小、最低大小、 mchunk_size成员_第1张图片

二、chunk的最低大小

  • 前面介绍过,malloc的堆块大小在glibc中会加上前两个成员的大小(0x10大小),所以当你分配一个堆内存时,堆内存的最小大小一定为0x20(0x10+0x10)。(即使malloc没有指定大小,也要分配fd和bk成员,所以加起来就是malloc_chunk结构体的前4个成员的大小总和)
  • 总结:chunk的最低大小一定为0x20大小

案例:

#include 
#include 
#include 

int main()
{ 
    void *p=malloc(0);
    sleep(0);  //只为了打断点使用,无其他用处
    free(p);    
    
    return 0;
}
  • 我们在这里分配了一个0大小的堆内存,但是可以看到第一个chunk与top chunk的地址差距为0x602020-0x602000=0x20
  • size成员为0x20+0x1=0x21(33),因为其PRECV_INUSE位为1,所以加上1

堆漏洞挖掘:09---chunk的实际大小、最低大小、 mchunk_size成员_第2张图片

三、mchunk_size成员

  • mchunk_size成员显示的是当前chunk的大小加上NON_MAIN_ARENA、IS_MAPPED、PREV_INUSE位的值
  • 这个成员显示的大小并不等价于该chunk在内存中的大小,但是我们可以通过该成员推断出chunk的大小以及NON_MAIN_ARENA、IS_MAPPED、PREV_INUSE位的值

你可能感兴趣的:(堆漏洞挖掘)