堆的系統(tǒng)調(diào)用
實例代碼
/* sbrk and brk example */
#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) gives current program break location */
tmp_brk = curr_brk = sbrk(0);
printf("Program Break Location1:%p\n", curr_brk);
getchar();
/* brk(addr) increments/decrements program break location */
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;
}
編譯運行之后, 在第一次調(diào)用brk之前
查看內(nèi)存映射
堆的分析
這是每個chunk的布局
prev_size: 如果當(dāng)前chunk的相鄰前一chunk未被使用贾节,prev_size為此前一chunk的大小
size: 當(dāng)前chunk的大小汁汗。由于chunk大小是8的整數(shù)倍,所以此size的后3 bit被用于存儲其他信息知牌。我們需要記住的便是最低bit祈争,即圖中P的位置角寸,用于指示前一chunk是否已被使用(PREV_INUSE)菩混。
如果當(dāng)前chunk未被使用扁藕, 則
fd: 下一個未被使用的chunk的地址
bk: 上一個未被使用的chunk的地址
所以我們可以通過當(dāng)前的chunk去定位前一個chunk和后一個chunk
也就是拿當(dāng)前chunk的地址減去前一個chunk的大小
或者拿當(dāng)前chunk的地址加上當(dāng)前chunk的大小
那些未被使用的chunks通過fd, bk組成了鏈表。事實上亿柑,malloc確實維護了一系列鏈表用于內(nèi)存的分配和回收邢疙,這些鏈表被成為"bins"。
bin分為fastbin, unsorted bin, small bin, large bin疟游。我們這里要研究的就是fastbin呼畸。
看了這篇文章之后覺得fastbin似乎也不是很難颁虐, 當(dāng)然最難的地方在于如何構(gòu)造payload淺析Linux堆溢出之fastbin
再好好分析一下malloc()這個神奇的函數(shù)
在glibc中蛮原,malloc_chunk以 2*sizeof(size_t)對齊另绩,在32位系統(tǒng)中以8字節(jié)對齊儒陨,在64位系統(tǒng)中一般以16字節(jié)對齊板熊。Malloc_chunk的定義如下:
既然malloc_chunk以2sizeof(size_t)對齊框全,那么malloc返回給用戶的指針數(shù)值也是以2sizeof(size_t)對齊干签。
最小的chunk是多大呢
最小的chunk需要保證能放下prev_size津辩、size容劳、fd以及bk字段并保證對齊喘沿。在32位系統(tǒng)中竭贩,即16字節(jié)蚜印,在64位系統(tǒng)中留量,一般為32字節(jié)窄赋。在64位系統(tǒng)中也可能定義INTERNAL_SIZE_T也即size_t為4字節(jié),這種情況下最小的chunk位24字節(jié)
fastbin中有10個bin
在32位系統(tǒng)中忆绰,fastbin里相鄰的兩個bin大小差距8個字節(jié);在64位系統(tǒng)中可岂,則是差距16個字節(jié)。
32位系統(tǒng)中缕粹,fastbin里chunk的大小范圍從16到64稚茅;
怎么根據(jù)p=malloc(m)里的m來判斷分配多大的chunk呢?
將申請的內(nèi)存大小加上每個chunk的overhead平斩,也就是chunk結(jié)構(gòu)體里的size字段。然后對齊绘面,就是需要分配的chunk的大小欺税。
在實戰(zhàn)之前先把wp好好看一下
接下來就是實戰(zhàn)了
貌似不能在32位平臺上運行
腳本執(zhí)行報錯怎么辦。峭竣。
這個錯誤貌似是struct這個包在pack的時候出的問題?
struct.pack
在stackoverflow上找到了這樣一個例子皆撩, 說是把q改成Q就行了
和我想的相差不多, 就是那個libc_case的地址小于0x3a55ed