Ptmalloc堆概述-Brk系统调用
1 brk
1.1 program break
未初始化数据段末尾后的第一个位置;
等于或超过此地址的地方均不可访问;
增加program break可以为进程分配内存;
减少program break则释放内存;
初始时,堆的起始地址 start_brk 以及堆的当前末尾 brk 指向同一地址。根据是否开启ASLR,两者的具体位置会有所不同
l 不开启 ASLR 保护时,start_brk 以及 brk 会指向 data/bss 段的结尾。
l 开启 ASLR 保护时,start_brk 以及 brk 也会指向同一位置,只是这个位置是在 data/bss 段结尾后的随机偏移处。
1.2 Brk系统调用
32位
#define __NR_brk 45
64位
#define __NR_brk 12
参数:请求的中断点
功能:
映射内存,返回新的中断点;
参数为0时,返回program break;
失败时,返回0;
注意:分配的堆是以页为单位的。如果请求的中断点不是页边界,则实际分配的会到页边界,而系统调用返回的中断点仍然是期望的中断点。
1.3 brk函数
#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);
brk函数
设置中断点;
成功返回0,失败返回-1;
Sbrk函数
设置中断点的增量;
成功返回0;失败返回-1;
参数为0时,返回program break的当前位置
2 C示例
注意:Ubuntu 16.04上好像有问题。使用sbrk函数获取program break时,第一次调用时heap还没有分配,后面的调用才是真正的program break。
[email protected]:~/tmp/sbrk$ gcc -m32 x.c [email protected]:~/tmp/sbrk$ ./a.out ptr=0x804b000
ptr=0x806c000
ptr=0x806c000 [email protected]:~/tmp/sbrk$ gcc x.c [email protected]:~/tmp/sbrk$ ./a.out ptr=0x602000
ptr=0x623000
ptr=0x623000 |
[email protected]:~$ cat /proc/`pgrep a.out`/maps | grep heap 0804b000-0806c000 rw-p 00000000 00:00 0 [heap] |
strace执行发现确实有分配0x1000的系统调用,但不知道为什么被调用
[email protected]:~/tmp$ strace ./a.out brk(NULL) = 0x9c3e000 ...... munmap(0xf76fb000, 109576) = 0 brk(NULL) = 0x9c3e000 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 18), ...}) = 0 brk(0x9c5f000) = 0x9c5f000 write(1, "ptr=0x9c3e000\n", 14ptr=0x9c3e000 ) = 14 |
3 ASM示例
brk.asm
makefile
GDB调试,查看系统调用的返回值;
或者查看/proc/pid/maps
4 参考文章
1. 深入理解程序设计使用Linux汇编语言
2. https://ctf-wiki.github.io/ctf-wiki/pwn/heap/heap_overview/