pwn_heap(未完待续)

早上上信安数基,了解了中国剩余定理,就是求同余方程组的解,找时间,用c++复现以下

pwn_heap


在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。堆其实就是程序虚拟地址空间的一块连续的线性区域,它由低地址向高地址方向增长。我们一般称管理堆的那部分程序为堆管理器。
malloc
malloc 函数返回对应大小字节的内存块的指针。此外,该函数还对一些异常情况进行了处理(指向数据部分)

当 n=0 时,返回当前系统允许的堆的最小内存块。
当 n 为负数时,由于在大多数系统上,size_t 是无符号数(这一点非常重要),所以程序就会申请很大的内存空间,但通常来说都会失败,因为系统没有那么多的内存可以分配。

free

当 p 为空指针时,函数不执行任何操作。
当 p 已经被释放之后,再次释放会出现乱七八糟的效果,这其实就是 double free。
除了被禁用 (mallopt) 的情况下,当释放很大的内存空间时,程序会将这些内存空间还给系统,以便于减小程序所使用的内存空间。

在这里插入图片描述malloc是由brk,mmap来实现的
ctf-wiki上有几个例子,我尝试复现,发现都和它不一样,难道我用的ubuntu20.04改了?
(草,原来是2.31的puts会调用malloc 服了,原来已经申请了。。。)
brk可以建立堆,mmap名段
在主线程释放内存后,而是交由glibc来进行管理。当后面程序再次申请内存时,在 glibc 中管理的内存充足的情况下,glibc 就会根据堆分配的算法来给程序分配相应的内存。
第一个线程malloc后, 我们可以从下面输出看出线程1的堆段被建立了。而且它所在的位置为内存映射段区域,同样大小也是132KB(b7500000-b7521000)。因此这表明该线程申请的堆时,背后对应的函数为mmap函数。(ctf-wiki多线程例子)
堆相关结构
堆的微观结构
malloc_chunk
无论一个 chunk 的大小如何,处于分配状态还是释放状态,它们都使用一个统一的结构。虽然它们使用了同一个数据结构,但是根据是否被释放,它们的表现形式会有所不同

/*

  This struct declaration is misleading (but accurate and necessary).

  It declares a "view" into memory allowing access to necessary

  fields at known offsets from a given base. See explanation below.

*/

struct malloc_chunk {
   



  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */

  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */



  struct malloc_chunk* fd;         /* double links -- used only if free. */

  struct malloc_chunk* bk;



  /* Only used for large blocks: pointer to next larger size.  */

  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */

  struct malloc_chunk* bk_nextsize;

};

prev_size 前一个块闲置,就记录它的大小
否则,记录前一个块的数据
size 当前块的大小 2*size_ez的倍数
它的前三个字节有别的用处
NON_MAIN_ARENA 是否属于主线程 0属于1 不属于
IS_MAPPED是否由mmap分配
PREV_INUSE 记录前一个 chunk 块是否被分配
fd,bk
被分配,放数据,free则放入相应的空闲放置列表。
fd指向下一个chunk
bk指向下一个chunk
通过 fd 和 bk 可以将空闲的 chunk 块加入到空闲的 chunk 块链表进行统一管理
fd_nextsize, bk_nextsize,只被用来当chunk被free了,只被用于大的chunk,

fd_nextsize 指向前一个与当前 chunk 大小不同的第一个空闲块,不包含 bin 的头指针。
bk_nextsize 指向后一个与当前 chunk 大小不同的第一个空闲块,不包含 bin 的头指针。
一般空闲的 large chunk 在 fd 的遍历顺序中,按照由大到小的顺序排列。这样做可以避免在寻找合适 chunk 时挨个遍历。

当一个chunk被用,结构如我们称前两个字段称为 chunk header,后面的部分称为 user data。每次 malloc 申请得到的内存指针,其实指向 user data 的起始处。
当一个 chunk 处于使用状态时,它的下一个 chunk 的 prev_size 域无效,所以下一个 chunk 的该部分也可以被当前 chunk 使用。这就是 chunk 中的空间复用。

chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |             Size of previous chunk, if unallocated (P clear)  |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |             Size of chunk, in bytes                     |A|M|P|
  mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值