英文文章源地址:Syscalls used by malloc
看本文章之前,你应该知道malloc
使用系统调用获取内存。正如下图中所展示的,malloc
调用brk
或mmap
系统调用去获取内存。
brk:
brk
通过增加程brk
的位置从内核中获取内存(没有被0初始化)。开始的时候,堆的初始位置(start_brk
)和结束位置(brk
)指向相同的位置。
当ASLR
关闭时,start_brk
和brk
将指向data/bss
段(end_data)的结尾。
当ASLR
打开时,start_brk
和brk
将等于data/bss
段(end_data)的结尾加上随机brk偏移。
上面的进程虚拟地址布局
-图片展示了start_brk
就是堆(heap)段的开始处,brk
(program break)就是堆结束处。
实例:
/* sbrk 和 brk 例子 */ #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)给出了程序的break位置 */ tmp_brk = curr_brk = sbrk(0); printf("Program Break Location1:%p\n", curr_brk); getchar(); /* brk(addr) 增加/减少程序的break位置 */ 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; }
输出分析:
在增加程序break
之前,通过下面的观察我们可以看到没有heap
段,因而,start_brk = brk = end_data = 0x804b000
.
[email protected]:~/ptmalloc.ppt/syscalls$ ./sbrk Welcome to sbrk example:6141 Program Break Location1:0x804b000 ... [email protected]:~/ptmalloc.ppt/syscalls$ cat /proc/6141/maps ... 0804a000-0804b000 rw-p 00001000 08:01 539624 /home/sploitfun/ptmalloc.ppt/syscalls/sbrk b7e21000-b7e22000 rw-p 00000000 00:00 0 ... [email protected]:~/ptmalloc.ppt/syscalls$
增加之后,通过下面的输出我们可以看到heap
已经有了,因而,start_brk = end_data = 0x804b000
和brk = 0x804c000
.
[email protected]:~/ptmalloc.ppt/syscalls$ ./sbrk Welcome to sbrk example:6141 Program Break Location1:0x804b000 Program Break Location2:0x804c000 ... [email protected]:~/ptmalloc.ppt/syscalls$ cat /proc/6141/maps ... 0804a000-0804b000 rw-p 00001000 08:01 539624 /home/sploitfun/ptmalloc.ppt/syscalls/sbrk 0804b000-0804c000 rw-p 00000000 00:00 0 [heap] b7e21000-b7e22000 rw-p 00000000 00:00 0 ... [email protected]:~/ptmalloc.ppt/syscalls$
在这里,
mmap:
malloc
使用mmap
创建私有映射内存段。目的就是申请一段新内存(0填充),这段内存将由调用的进程专用。
示例:
/* 使用mmap系统调用创建私有内存 */ #include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> void static inline errExit(const char* msg) { printf("%s failed. Exiting the process\n", msg); exit(-1); } int main() { int ret = -1; printf("Welcome to private anonymous mapping example::PID:%d\n", getpid()); printf("Before mmap\n"); getchar(); char* addr = NULL; addr = mmap(NULL, (size_t)132*1024, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) errExit("mmap"); printf("After mmap\n"); getchar(); /* Unmap mapped region. */ ret = munmap(addr, (size_t)132*1024); if(ret == -1) errExit("munmap"); printf("After munmap\n"); getchar(); return 0; }
输出分析:
在mmap之前,通过下面的输出,我们只能看到属于共享库libc.so
和ld-linux.so
的内存映射:
[email protected]:~/ptmalloc.ppt/syscalls$ cat /proc/6067/maps 08048000-08049000 r-xp 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 08049000-0804a000 r--p 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 0804a000-0804b000 rw-p 00001000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap b7e21000-b7e22000 rw-p 00000000 00:00 0 ... [email protected]x:~/ptmalloc.ppt/syscalls$
在mmap之后,通过观察我们可以看到内存映射段(b7e00000-b7e22000,大小为我们设置的132k)和本就已经存在的内存映射(b7e21000-b7e22000)组合起来了:
[email protected]:~/ptmalloc.ppt/syscalls$ cat /proc/6067/maps 08048000-08049000 r-xp 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 08049000-0804a000 r--p 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 0804a000-0804b000 rw-p 00001000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap b7e00000-b7e22000 rw-p 00000000 00:00 0 ... [email protected]:~/ptmalloc.ppt/syscalls$
在这儿,
在munmap之后,通过下面的输出,我们的内存映射段已经被返回给操作系统了。
[email protected]:~/ptmalloc.ppt/syscalls$ cat /proc/6067/maps 08048000-08049000 r-xp 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 08049000-0804a000 r--p 00000000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap 0804a000-0804b000 rw-p 00001000 08:01 539691 /home/sploitfun/ptmalloc.ppt/syscalls/mmap b7e21000-b7e22000 rw-p 00000000 00:00 0 ... [email protected]:~/ptmalloc.ppt/syscalls$
注意,在我们的程序中ASLR
被关闭。