新聞中心
既然你正在看這篇文章,那么你就應(yīng)該知道m(xù)alloc函數(shù)是通過(guò)syscall調(diào)用從操作系統(tǒng)獲取內(nèi)存的。 如下圖所示,malloc是通過(guò)調(diào)用brk或mmap這兩種syscall之一來(lái)獲取內(nèi)存的。

創(chuàng)新互聯(lián)公司基于成都重慶香港及美國(guó)等地區(qū)分布式IDC機(jī)房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動(dòng)大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)服務(wù)器托管報(bào)價(jià),主機(jī)托管價(jià)格性價(jià)比高,為金融證券行業(yè)西信服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨(dú)享,G口帶寬及機(jī)柜租用的專業(yè)成都idc公司。
1.brk方式
brk:brk是通過(guò)增設(shè)程序斷點(diǎn)來(lái)從內(nèi)核獲取內(nèi)存(非清零)的。最初堆段的起點(diǎn)(start_brk)和堆段終點(diǎn)(brk)是指向相同的位置的。當(dāng)ASLR關(guān)閉時(shí),start_brk和brk將指向data/bss段(end_data)的末尾。當(dāng)ASLR打開(kāi)時(shí),start_brk和brk的值將等于data/bss段(end_data)的結(jié)尾加上一個(gè)隨機(jī)的brk偏移。
正如上面的“進(jìn)程虛擬內(nèi)存布局”圖展示的,start_brk是堆段的開(kāi)始,brk(程序中斷)是堆段的結(jié)尾。
例程如下:
- /* 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)返回此進(jìn)程的斷點(diǎn)位置*/
- tmp_brk = curr_brk = sbrk(0);
- printf("Program Break Location1:%p\n", curr_brk);
- getchar();
- /* brk(addr)遞增/遞減程序的斷點(diǎn)位置*/
- 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;
- }
輸出分析:在增設(shè)程序中斷之前,通過(guò)下面的輸出,我們可以看到并沒(méi)有堆段。
因此:? 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$
在增設(shè)了程序斷點(diǎn)后:在下面的輸出我們可以觀察到有堆段。
因此:? 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(可讀,可寫,不可執(zhí)行,私有)
00000000是文件偏移 – 由于不存在文件映射,所以這里為零
00:00是主要/次要設(shè)備號(hào) – 由于不存在文件映射,所以這里為零
0是Inode編號(hào) – 由于不存在文件映射,所以這里為零
[heap]表示是堆段
2.mmap方式
mmap:malloc使用mmap去創(chuàng)建一個(gè)私有的匿名映射段。映射這個(gè)私有匿名段的主要目的是為了分配新的內(nèi)存(已清零),并且這個(gè)新的內(nèi)存將被調(diào)用進(jìn)程獨(dú)占使用。
例程:
- /* 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調(diào)用前:在下面的輸出中,我們只能看到屬于共享庫(kù)libc.so和ld-linux.so的內(nèi)存映射段
- 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調(diào)用后:在下面的輸出中,我們可以看到我們的內(nèi)存映射段(b7e00000 – b7e21000,大小為132KB)與已映射的內(nèi)存映射段(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(可讀,可寫,不可執(zhí)行,私有)
00000000是文件偏移 – 由于不存在文件映射,所以這里為零
00:00是主要/次要設(shè)備號(hào) – 由于不存在文件映射,所以這里為零
0是Inode編號(hào) – 由于不存在文件映射,所以這里為零
munmap調(diào)用后:在下面的輸出中,我們可以看到我們的內(nèi)存映射段是未映射的,就是說(shuō)其相應(yīng)的內(nèi)存已經(jīng)釋放到操作系統(tǒng)了。
- 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是關(guān)閉的。
本文題目:Malloc兩種內(nèi)存獲取方式的區(qū)別
網(wǎng)站網(wǎng)址:http://m.fisionsoft.com.cn/article/djhedhe.html


咨詢
建站咨詢
