在之前的文章中,我們探討了與 Stack 相關的攻擊手法及其對應的保護機制。接下來的幾篇文章,將會把焦點轉向程式的另一個記憶體區域—Heap。
Heap 的運作是基於程式需要動態分配的記憶體需求,這與 Stack 的固定大小分配不同。當程式需要大量記憶體且無法預知具體大小時,就會使用 Heap 進行管理。Heap 記憶體分配由系統中的動態記憶體管理器負責,在 glibc 上實現的 heap 的機制為 ptmalloc2,後續將會介紹此機制。
Heap 在記憶體中位於下方圖中這塊黃色的區域
它是由低地址到高地址生長的,只有當使用者向作業系統申請記憶體時,個個空間才會被分配出來,並且為了效能考量,一次會分一塊很大塊的連續記憶體空間。若開啟 ASLR 就會像圖上一樣,有隨機的偏移偏移量才是 Heap 的空間。
Heap 的大小是由 brk() 與 sbrk() 所控制的,當 Heap 尚未初始化時,有一個指標 program_break 會指向 Bss Segment 的最尾處。
不論使用 brk() 還是 sbrk(),分配 Heap 後記憶體如下:
黃色的這片連續記憶體區塊即為 Heap,我們也會稱呼它為 main_arena。
下一篇文章將會說明如何向 Heap 申請空間。