glibc2.23 ptmalloc 原理概述
发表于看雪论坛
linux用户态下的堆溢出利用即是对ptmalloc2安全机制的绕过,只有深入的了解ptmalloc,才能进行精准的堆溢出攻击
malloc __libc_malloc(传入参数:size) 判断 是否定义hook函数 ,如果存在则调用hook函数,否则跳到2 void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook); if (__builtin_expect (hook != NULL, 0)) return (*hook)(bytes, RETURN_ADDRESS (0)); 执行arena_get得到空闲分配区 arena_get (ar_ptr, bytes); 调用_int_malloc()获得内存地址 victim = _int_malloc (ar_ptr, bytes); 如果分配失败,ptmalloc会尝试再去寻找一个可用的arena并进行内存分配 if (!victim && ar_ptr != NULL) { LIBC_PROBE (memory_malloc_retry, 1, bytes); ar_ptr = arena_get_retry (ar_ptr, bytes); victim = _int_malloc (ar_ptr, bytes); } 得到内存地址后解锁分配区 if (ar_ptr != NULL) (void) mutex_unlock (&ar_ptr->mutex); 如果在上面的步骤中获得非mmap得到的chunk,但是chunk对应的分配区与实际的分配区不相符,则程序终止 assert (!victim || chunk_is_mmapped (mem2chunk (victim)) || ar_ptr == arena_for_chunk (mem2chunk (victim))); _int_malloc errout: 打印错误字符串并 return 判断 size是否大于(unsigned long)(-2*MINSIZE) MINSIZE=chunk的最小大小 ,如果是则return,否则将size转换为chunk_size #define checked_request2size(req, sz) \ if (REQUEST_OUT_OF_RANGE (req)) { \ __set_errno (ENOMEM); \ return 0; \ } \ (sz) = request2size (req); 判断 前面是否没有获得空闲分配区 如果是则跳到3,否则跳到4 if (__glibc_unlikely (av == NULL)) 调用sysmalloc尝试获得chunk地址,如果得到则调用alloc_perturb 将清理空间数据,return chunk地址 if (__glibc_unlikely (av == NULL)) { void *p = sysmalloc (nb, av); if (p !