ptmalloc堆概述-mmap系统调用

ptmalloc堆概述-mmap系统调用

概述

malloc 会使用 mmap来创建独立的匿名映射段。匿名映射的目的主要是可以申请以0填充的内存,并且这块内存仅被调用进程所使用。

Malloc分配大于128KB时,直接使用mmap进行分配。

Mmap

2.1 API

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *addr, size_t length);

 

#define PROT_READ 0x1 /* Page can be read. */

#define PROT_WRITE 0x2 /* Page can be written. */

#define PROT_EXEC 0x4 /* Page can be executed. */

#define PROT_NONE 0x0 /* Page can not be accessed. */

 

#define MAP_SHARED 0x01 /* Share changes. */

#define MAP_PRIVATE 0x02 /* Changes are private. */

#define MAP_ANONYMOUS 0x20 /* Don't use a file. */

#define MAP_ANON MAP_ANONYMOUS

系统调用

#define __NR_mmap 90

#define __NR_mmap2 192

#define __NR_munmap 91

strace显示mmap函数调用的是__NR_mmap2系统调用

2.2 查看内存映射

l cat /proc/<pid>/maps

millionsky@ubuntu-16:~$ cat /proc/`pgrep mmap`/maps

08048000-08049000 r-xp 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

08049000-0804a000 r--p 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

0804a000-0804b000 rw-p 00001000 08:01 11143393                           /home/millionsky/tmp/mmap

09a4c000-09a6d000 rw-p 00000000 00:00 0                                  [heap]

f75c3000-f75c4000 rw-p 00000000 00:00 0

f75c4000-f7771000 r-xp 00000000 08:01 29491224                           /lib32/libc-2.23.so

f7771000-f7772000 ---p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f7772000-f7774000 r--p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f7774000-f7775000 rw-p 001af000 08:01 29491224                           /lib32/libc-2.23.so

f7775000-f7779000 rw-p 00000000 00:00 0

f7794000-f7796000 r--p 00000000 00:00 0                                  [vvar]

f7796000-f7798000 r-xp 00000000 00:00 0                                  [vdso]

f7798000-f77ba000 r-xp 00000000 08:01 29491203                           /lib32/ld-2.23.so

f77ba000-f77bb000 rw-p 00000000 00:00 0

f77bb000-f77bc000 r--p 00022000 08:01 29491203                           /lib32/ld-2.23.so

f77bc000-f77bd000 rw-p 00023000 08:01 29491203                           /lib32/ld-2.23.so

fff85000-fffa6000 rw-p 00000000 00:00 0                                  [stack]

第二列是相关的权限:

PROT_NONE   = Page can not be accessed

PROT_READ r = read

PROT_WRITE w = write

PROT_EXEC x = execute

MAP_SHARED s = shared

MAP_PRIVATE p = private (copy on write)

第三列表示文件偏移,0表示不是从文件中映射得到的;

第四列表示主从(Major/mirror)的设备号,0表示不是从文件中映射得到的;

第五列表示表示着Inode 号,0表示不是从文件中映射得到的;

2.3 实例

Ubuntu 16.04 64上测试

Mmap.c

/* Private anonymous mapping example using mmap syscall */
#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, addr=%p \n ", addr);
getchar();

/* Unmap mapped region. */
ret = munmap(addr, ( size_t) 132* 1024);
if(ret == - 1)
errExit( "munmap");
printf( "After munmap \n ");
getchar();
return 0;
}

 

测试

millionsky@ubuntu-16:~/tmp$ gcc -m32 mmap.c -o mmap

millionsky@ubuntu-16:~/tmp$ ./mmap

Welcome to private anonymous mapping example::PID:9329

Before mmap

After mmap, addr=0xf74f2000

After munmap

Mmap调用之前

可以看到程序、libcld都有mmap的内存块,大小分别为4K16K4K

millionsky@ubuntu-16:~/tmp$ cat /proc/`pgrep mmap`/maps

08048000-08049000 r-xp 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

08049000-0804a000 r--p 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

0804a000-0804b000 rw-p 00001000 08:01 11143393                           /home/millionsky/tmp/mmap

0857a000-0859b000 rw-p 00000000 00:00 0                                  [heap]

f7513000-f7514000 rw-p 00000000 00:00 0

f7514000-f76c1000 r-xp 00000000 08:01 29491224                           /lib32/libc-2.23.so

f76c1000-f76c2000 ---p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c2000-f76c4000 r--p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c4000-f76c5000 rw-p 001af000 08:01 29491224                           /lib32/libc-2.23.so

f76c5000-f76c9000 rw-p 00000000 00:00 0 

f76e4000-f76e6000 r--p 00000000 00:00 0                                  [vvar]

f76e6000-f76e8000 r-xp 00000000 00:00 0                                  [vdso]

f76e8000-f770a000 r-xp 00000000 08:01 29491203                           /lib32/ld-2.23.so

f770a000-f770b000 rw-p 00000000 00:00 0 

f770b000-f770c000 r--p 00022000 08:01 29491203                           /lib32/ld-2.23.so

f770c000-f770d000 rw-p 00023000 08:01 29491203                           /lib32/ld-2.23.so

ffa06000-ffa27000 rw-p 00000000 00:00 0                                  [stack]

Mmap之后

可以看到,新分配的内存和已存在的内存合并了

millionsky@ubuntu-16:~/tmp$ cat /proc/`pgrep mmap`/maps

08048000-08049000 r-xp 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

08049000-0804a000 r--p 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

0804a000-0804b000 rw-p 00001000 08:01 11143393                           /home/millionsky/tmp/mmap

0857a000-0859b000 rw-p 00000000 00:00 0                                  [heap]

f74f2000-f7514000 rw-p 00000000 00:00 0 

f7514000-f76c1000 r-xp 00000000 08:01 29491224                           /lib32/libc-2.23.so

f76c1000-f76c2000 ---p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c2000-f76c4000 r--p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c4000-f76c5000 rw-p 001af000 08:01 29491224                           /lib32/libc-2.23.so

f76c5000-f76c9000 rw-p 00000000 00:00 0

f76e4000-f76e6000 r--p 00000000 00:00 0                                  [vvar]

f76e6000-f76e8000 r-xp 00000000 00:00 0                                  [vdso]

f76e8000-f770a000 r-xp 00000000 08:01 29491203                           /lib32/ld-2.23.so

f770a000-f770b000 rw-p 00000000 00:00 0

f770b000-f770c000 r--p 00022000 08:01 29491203                           /lib32/ld-2.23.so

f770c000-f770d000 rw-p 00023000 08:01 29491203                           /lib32/ld-2.23.so

ffa06000-ffa27000 rw-p 00000000 00:00 0                                  [stack]

unmap之后

申请的内存段已经没有了

millionsky@ubuntu-16:~/tmp$ cat /proc/`pgrep mmap`/maps

08048000-08049000 r-xp 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

08049000-0804a000 r--p 00000000 08:01 11143393                           /home/millionsky/tmp/mmap

0804a000-0804b000 rw-p 00001000 08:01 11143393                           /home/millionsky/tmp/mmap

0857a000-0859b000 rw-p 00000000 00:00 0                                  [heap]

f7513000-f7514000 rw-p 00000000 00:00 0 

f7514000-f76c1000 r-xp 00000000 08:01 29491224                           /lib32/libc-2.23.so

f76c1000-f76c2000 ---p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c2000-f76c4000 r--p 001ad000 08:01 29491224                           /lib32/libc-2.23.so

f76c4000-f76c5000 rw-p 001af000 08:01 29491224                           /lib32/libc-2.23.so

f76c5000-f76c9000 rw-p 00000000 00:00 0

f76e4000-f76e6000 r--p 00000000 00:00 0                                  [vvar]

f76e6000-f76e8000 r-xp 00000000 00:00 0                                  [vdso]

f76e8000-f770a000 r-xp 00000000 08:01 29491203                           /lib32/ld-2.23.so

f770a000-f770b000 rw-p 00000000 00:00 0

f770b000-f770c000 r--p 00022000 08:01 29491203                           /lib32/ld-2.23.so

f770c000-f770d000 rw-p 00023000 08:01 29491203                           /lib32/ld-2.23.so

ffa06000-ffa27000 rw-p 00000000 00:00 0                                  [stack]

附件

参考文档

1. https://ctf-wiki.github.io/ctf-wiki/pwn/heap/heap_overview/

猜你喜欢

转载自blog.csdn.net/luozhaotian/article/details/80267089