ptmalloc学习笔记

2020-12-07
#ctf #pwn

最近在学习pwn中的堆利用,因此来系统的学习一下ptmalloc的机制。主要看的是Glibc内存管理--ptmalloc2源代码分析。

malloc

这是照着书上画的流程图,可以快速了解malloc的整体逻辑。

malloc流程图

free

同样是流程图: free流程图

unlink

其它漏洞配合上unlink可以达到任意地址写的效果。

这是旧版unlink函数,是宏的形式。

/* Take a chunk off a bin list */
#define unlink(P, BK, FD) { \
 FD = P->fd; \
 BK = P->bk; \
 if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
 malloc_printerr (check_action, "corrupted double-linked list", P); \
 else { \
 FD->bk = BK; \
 BK->fd = FD; \
 if (!in_smallbin_range (P->size) \
 && __builtin_expect (P->fd_nextsize != NULL, 0)) { \
 assert (P->fd_nextsize->bk_nextsize == P); \
 assert (P->bk_nextsize->fd_nextsize == P); \
 if (FD->fd_nextsize == NULL) { \
 if (P->fd_nextsize == P) \
 FD->fd_nextsize = FD->bk_nextsize = FD; \
 else { \
 FD->fd_nextsize = P->fd_nextsize; \
 FD->bk_nextsize = P->bk_nextsize; \
 P->fd_nextsize->bk_nextsize = FD; \
 P->bk_nextsize->fd_nextsize = FD; \
 } \
 } else { \
 P->fd_nextsize->bk_nextsize = P->bk_nextsize; \
 P->bk_nextsize->fd_nextsize = P->fd_nextsize; \
 } \
 } \
 } \
}

这是新版的unlink新增了presize的检查,利用起来更难了。。


/* Take a chunk off a bin list.  */
static void
unlink_chunk (mstate av, mchunkptr p)
{
  if (chunksize (p) != prev_size (next_chunk (p)))
    malloc_printerr ("corrupted size vs. prev_size");

  mchunkptr fd = p->fd;
  mchunkptr bk = p->bk;

  if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
    malloc_printerr ("corrupted double-linked list");

  fd->bk = bk;
  bk->fd = fd;
  if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL)
    {
      if (p->fd_nextsize->bk_nextsize != p
	  || p->bk_nextsize->fd_nextsize != p)
	malloc_printerr ("corrupted double-linked list (not small)");

      if (fd->fd_nextsize == NULL)
	{
	  if (p->fd_nextsize == p)
	    fd->fd_nextsize = fd->bk_nextsize = fd;
	  else
	    {
	      fd->fd_nextsize = p->fd_nextsize;
	      fd->bk_nextsize = p->bk_nextsize;
	      p->fd_nextsize->bk_nextsize = fd;
	      p->bk_nextsize->fd_nextsize = fd;
	    }
	}
      else
	{
	  p->fd_nextsize->bk_nextsize = p->bk_nextsize;
	  p->bk_nextsize->fd_nextsize = p->fd_nextsize;
	}
    }
}

具体的利用方式去ctf-wiki上去看吧,就不再写一遍了。