既然你正在看这篇文章,那么你就应该知道malloc函数是通过syscall调用从操作系统获取内存的。 如下图所示,malloc是通过调用brk或mmap这两种syscall之一来获取内存的。

创新互联公司基于成都重庆香港及美国等地区分布式IDC机房数据中心构建的电信大带宽,联通大带宽,移动大带宽,多线BGP大带宽租用,是为众多客户提供专业服务器托管报价,主机托管价格性价比高,为金融证券行业西信服务器托管,ai人工智能服务器托管提供bgp线路100M独享,G口带宽及机柜租用的专业成都idc公司。
1.brk方式
brk:brk是通过增设程序断点来从内核获取内存(非清零)的。最初堆段的起点(start_brk)和堆段终点(brk)是指向相同的位置的。当ASLR关闭时,start_brk和brk将指向data/bss段(end_data)的末尾。当ASLR打开时,start_brk和brk的值将等于data/bss段(end_data)的结尾加上一个随机的brk偏移。
正如上面的“进程虚拟内存布局”图展示的,start_brk是堆段的开始,brk(程序中断)是堆段的结尾。
例程如下:
- /* sbrk and brk example */
 - #include
 - #include
 - #include
 - int main()
 - {
 - void *curr_brk, *tmp_brk = NULL;
 - printf("Welcome to sbrk example:%d\n", getpid());
 - /* sbrk(0)返回此进程的断点位置*/
 - tmp_brk = curr_brk = sbrk(0);
 - printf("Program Break Location1:%p\n", curr_brk);
 - getchar();
 - /* brk(addr)递增/递减程序的断点位置*/
 - 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;
 - }
 
输出分析:在增设程序中断之前,通过下面的输出,我们可以看到并没有堆段。
因此:• start_brk = brk = end_data = 0x804b000
- sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$ ./sbrk
 - Welcome to sbrk example:6141
 - Program Break Location1:0x804b000
 - ...
 - sploitfun@sploitfun-VirtualBox:~/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
 - ...
 - sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$
 
在增设了程序断点后:在下面的输出我们可以观察到有堆段。
因此:• start_brk = end_data = 0x804b000• brk = 0x804c000
- sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$ ./sbrk
 - Welcome to sbrk example:6141
 - Program Break Location1:0x804b000
 - Program Break Location2:0x804c000
 - ...
 - sploitfun@sploitfun-VirtualBox:~/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
 - ...
 - sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$
 
其中0804b000-0804c000是此堆段的虚拟地址范围
rw-p是Flags(可读,可写,不可执行,私有)
00000000是文件偏移 – 由于不存在文件映射,所以这里为零
00:00是主要/次要设备号 – 由于不存在文件映射,所以这里为零
0是Inode编号 – 由于不存在文件映射,所以这里为零
[heap]表示是堆段
2.mmap方式
mmap:malloc使用mmap去创建一个私有的匿名映射段。映射这个私有匿名段的主要目的是为了分配新的内存(已清零),并且这个新的内存将被调用进程独占使用。
例程:
- /* Private anonymous mapping example using mmap syscall */
 - #include
 - #include
 - #include
 - #include
 - #include
 - #include
 - #include
 - 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的内存映射段
- sploitfun@sploitfun-VirtualBox:~/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
 - ...
 - sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$
 
mmap调用后:在下面的输出中,我们可以看到我们的内存映射段(b7e00000 – b7e21000,大小为132KB)与已映射的内存映射段(b7e21000 – b7e22000)拼接在一起了。
- sploitfun@sploitfun-VirtualBox:~/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
 - ...
 - sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$
 
其中b7e00000-b7e22000是此段的虚拟地址范围
rw-p是Flags(可读,可写,不可执行,私有)
00000000是文件偏移 – 由于不存在文件映射,所以这里为零
00:00是主要/次要设备号 – 由于不存在文件映射,所以这里为零
0是Inode编号 – 由于不存在文件映射,所以这里为零
munmap调用后:在下面的输出中,我们可以看到我们的内存映射段是未映射的,就是说其相应的内存已经释放到操作系统了。
- sploitfun@sploitfun-VirtualBox:~/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
 - ...
 - sploitfun@sploitfun-VirtualBox:~/ptmalloc.ppt/syscalls$
 
注意:在我们的示例程序中ASLR是关闭的。
                网页名称:Malloc两种内存获取方式的区别
                
                路径分享:http://www.csdahua.cn/qtweb/news32/153882.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网