glibc中free函数详解

__libc_free详解(tcache 略)

1. 检查是否存在 hook函数,如果有就执行

void
__libc_free (void *mem)
{
   
  mstate ar_ptr;
  mchunkptr p;                          /* chunk corresponding to mem */
/*
	1. 关于__free_hook,释放时会检查其会否为NULL,否的话就执行相应的函数
	2. __free_hook指向的函数,其调用的参数,为chunk中的内容
	3. 将__free_hook,改为system时,需要在chunk中写入 /bin/sh
	4. 将__free_hook,改为onegadget时,有时需要调整rsp
	5. 貌似是在__malloc_hook下面的realloc_hook,通过push调整

*/
  void (*hook) (void *, const void *)
    = atomic_forced_read (__free_hook);
  if (__builtin_expect (hook != NULL, 0)) //hook函数不是null,就执行__free_hook对应的函数并返回
    {
   
      (*hook)(mem, RETURN_ADDRESS (0));
      return;
    }

  if (mem == 0)                              /* free(0) has no effect */
    return;
	/*
		1. 用户指向的空间在chunk头下方0x10处,chunk头对用户是不可见的,free处理的就是chunk头
		2. 因此,需要获得chunk头的指针
	*/
  p = mem2chunk (mem); //将指向user data 的指针转化为指向 chunk的指针

  /*
  	1. 一般使用 mmap分配的chunk都非常的大,且chunk的地址在libc_base的上方固定偏移,因此可以用来泄漏libc的地址
  	2. 一般在没有size检查时使用
  */
  if (chunk_is_mmapped (p)) //如果chunk是mmap分配的,就用munmap_chunk()函数释放                /* release mmapped memory. */
    {
   
      /* See if the dynamic brk/mmap threshold needs adjusting.
	 Dumped fake mmapped chunks do not affect the threshold.  */
      if (!mp_.no_dyn_threshold
          && chunksize_nomask (p) > mp_.mmap_threshold
          && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX
	  && !DUMPED_MAIN_ARENA_CHUNK (p))
        {
   
          mp_.mmap_threshold = chunksize (p);
          mp_.trim_threshold = 2 * mp_.mmap_threshold;
          LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
                      mp_.mmap_threshold, mp_.trim_threshold);
        }
      munmap_chunk (p);
      return;
    }

  MAYBE_INIT_TCACHE ();
	/*
		1. ar_ptr实际上不在heap数据段中,在libc中,是一个全局的变量
		2. 当释放small chunk是,ustored bin中指向的是main_area + 88
		3. 在ubuntu 16.04中,libc_base = main_area - 88 - 0x3c4b20
	*/
  ar_ptr = arena_for_chunk (p); //获得指向arena的指针
  _int_free (ar_ptr, p, 0); //调用init函数进行释放
    
}

2. _int_free()函数,对chunk进行检查

static void
_int_free (mstate av, mchunkptr p, int have_lock)
{
   
  INTERNAL_SIZE_T size;        /* its size */
  mfastbinptr *fb;             /* associated fastbin */
  mchunkptr nextchunk;         /* next contiguous chunk */
  INTERNAL_SIZE_T nextsize;    /* its size */
  int nextinuse;               /* true if nextchunk is used */
  INTERNAL_SIZE_T prevsize;    /* size of previous contiguous chunk */
  mchunkptr bck;               /* misc temp for linking */
  mchunkptr fwd;               /* misc temp for linking */

  size = chunksize (p);

  /* Little security check which won't hurt performance: the
     allocator never wrapps around at the end of the address space.
     Therefore we can exclude some size values which might appear
     here by accident or by "design" from some intruder.  */
    
    //第一个条件筛选掉一些特别大的size,第二个条件检查chunk是否对齐
  if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值