堆的入门

堆的系统调用

实例代码

/* sbrk and brk example */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
        void *curr_brk, *tmp_brk = NULL;

        printf("Welcome to sbrk example:%d\n", getpid());

        /* sbrk(0) gives current program break location */
        tmp_brk = curr_brk = sbrk(0);
        printf("Program Break Location1:%p\n", curr_brk);
        getchar();

        /* brk(addr) increments/decrements program break location */
        brk(curr_brk+4096);

        curr_brk = sbrk(0);
        printf("Program break Location2:%p\n", curr_brk);
        getchar();

        brk(tmp_brk);

        curr_brk = sbrk(0);
        printf("Program Break Location3:%p\n", curr_brk);
        getchar();

        return 0;
}

编译运行之后, 在第一次调用brk之前


10651191-f8ca927f64c21368.png

查看内存映射

10651191-79f2f16d0c4077f8.png

堆的分析

这是每个chunk的布局

prev_size: 如果当前chunk的相邻前一chunk未被使用,prev_size为此前一chunk的大小
size: 当前chunk的大小。由于chunk大小是8的整数倍,所以此size的后3 bit被用于存储其他信息。我们需要记住的便是最低bit,即图中P的位置,用于指示前一chunk是否已被使用(PREV_INUSE)。

10651191-737d4f958ff2715b.png!web

如果当前chunk未被使用, 则

fd: 下一个未被使用的chunk的地址
bk: 上一个未被使用的chunk的地址

所以我们可以通过当前的chunk去定位前一个chunk和后一个chunk
也就是拿当前chunk的地址减去前一个chunk的大小
或者拿当前chunk的地址加上当前chunk的大小

那些未被使用的chunks通过fd, bk组成了链表。事实上,malloc确实维护了一系列链表用于内存的分配和回收,这些链表被成为"bins"。

bin分为fastbin, unsorted bin, small bin, large bin。我们这里要研究的就是fastbin。

看了这篇文章之后觉得fastbin似乎也不是很难, 当然最难的地方在于如何构造payload浅析Linux堆溢出之fastbin

再好好分析一下malloc()这个神奇的函数

在glibc中,malloc_chunk以 2*sizeof(size_t)对齐,在32位系统中以8字节对齐,在64位系统中一般以16字节对齐。Malloc_chunk的定义如下:

10651191-662cd5131f4a17b1.png

既然malloc_chunk以2sizeof(size_t)对齐,那么malloc返回给用户的指针数值也是以2sizeof(size_t)对齐。

最小的chunk是多大呢

最小的chunk需要保证能放下prev_size、size、fd以及bk字段并保证对齐。在32位系统中,即16字节,在64位系统中,一般为32字节。在64位系统中也可能定义INTERNAL_SIZE_T也即size_t为4字节,这种情况下最小的chunk位24字节

fastbin中有10个bin
在32位系统中,fastbin里相邻的两个bin大小差距8个字节;在64位系统中,则是差距16个字节。

32位系统中,fastbin里chunk的大小范围从16到64;

怎么根据p=malloc(m)里的m来判断分配多大的chunk呢?

将申请的内存大小加上每个chunk的overhead,也就是chunk结构体里的size字段。然后对齐,就是需要分配的chunk的大小。

在实战之前先把wp好好看一下

接下来就是实战了

10651191-1db5132624bcd91c.png
程序的大致流程
10651191-69d0d87b2e9957af.png
相关的字符串

貌似不能在32位平台上运行

10651191-764eca89c907c342.png

脚本执行报错怎么办。。

10651191-136d6a2b67018293.png

这个错误貌似是struct这个包在pack的时候出的问题?


10651191-b0d64e359ac83e34.png

struct.pack

在stackoverflow上找到了这样一个例子, 说是把q改成Q就行了

10651191-ea5a526f6e827be7.png

和我想的相差不多, 就是那个libc_case的地址小于0x3a55ed

10651191-058b043107df9751.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值