Glibc-2.23 源码分析——malloc部分下

阅读量    149757 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

前言

终于抽出时间对glibc动态内存管理部分源码进行初略的探究,试着从源码和动调来分析free函数执行过程和一些pwn的攻击技巧,分析的不是很全面,有错误的地方望提出指正,共同进步。ps:欢迎白帽子们关注 涂鸦智能安全响应中心


Malloc的执行流程

情况3:申请mmap

测试代码

#include <stdio.h>
#include <stdlib.h>

int main()
{
    malloc(0x20);
    malloc(0x24000);
    return 0;
}

申请的size 大于 av->top

执行调用链: Malloc -> int_malloc -> sysmalloc

Nb = 0x24010 > mp.mmapthreshold 且 (mp.nmmaps < mp.n_mmaps_max,满足条件进入mmap()的调用。

计算出满足页对齐的size后调用 MMAP()

申请的size大小为 0x24030 满足页对齐的size是 0x25000

执行后申请到的mmap 空间

之后对mmap 空间写入 size头,并在标志位上 打上 Mmap标志 0x2

执行效果

 

calloc执行流程

测试代码

#include<stdio.h>
#include<stdlib.h>

int main(){
    int *p1 = calloc(0x20, 1);
    int *p2 = calloc(0x20, 1);
    free(p1);
    calloc(0x20, 1);
    return 0;
}

堆初始化执行流程

libc_calloc() -> _int_malloc(),和libc_malloc()一样的堆初始化流程,之后通过malloc_hook跳转 malloc_hook_ini(),与malloc()的区别在于会将申请的堆空间全部置零。

之后有关main_arena取chunk的申请也是通过int_malloc(),最后都会置空堆空间

整体上看calloc是一个malloc的调用接口,输出前加上了置空堆空间

 

realloc执行流程

测试代码

#include<stdio.h>
#include<stdlib.h>

int main(){
    int *p1 = malloc(0x10);
    int *p2 = malloc(0x10);
    int *p_realloc = realloc(p1, 0x30);
    return 0;
}

realloc调用流程 realloc->realloc_hook_ini(通过realloc_hook跳转)

清空 malloc_hook,__realloc_hook之后跳转 _libc_realloc()执行

之后进入_int_realloc()
_int_realloc()函数是一个_int_free()和_int_malloc()的结合体,释放剩余旧堆块,若申请新堆块,则复制堆块内容

先对新申请的堆块与原先堆块进行比对

若新申请堆块大于原先堆块

若新申请的size大于原先的size,尝试向top_chunk申请堆块

新申请堆块的话,需要进行数据复制,将原先堆块的数据拷贝到新申请堆块中

之后释放原先堆块

若新申请堆块小于原先堆块

若新申请的堆块小于原先堆块分割原先堆块,并且位于原先堆块中,释放剩余部分,

整体来看realloc是个功能丰富的缝合怪属于是。
realloc可以通过构造制定大小修改,实现free 特定size的remainder_chunk
realloc(0, size) 可以当做malloc(size)使用

realloc(chunk_ptr, 0) 可以当做free(chunk_ptr)使用


本文作者:Jambolt@涂鸦智能安全实验室

漏洞悬赏计划:涂鸦智能安全响应中心(https://src.tuya.com) 欢迎白帽子来探索。

招聘内推计划:涵盖安全开发、安全测试、代码审计、安全合规等所有方面的岗位,简历投递sec@tuya.com,请注明来源。

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多