一 small bin,large bin等的記憶體結構
未分配的chunk
| pre chunk size | size |f|c|p|
| fd | bk |
presize: 前乙個塊的大小(如果前乙個塊是空閒的)
size:當前塊的大小
f標誌位:目前還沒有用
c標誌位:如果當前塊已被分配,置1;否則,置0
p標誌位:如果前乙個塊已被分配,置1,;否則,置0
二、unlink
久經辛苦終於看明白了。還是很精妙的。
unlink是free非fastbin時,會先檢查該chunk前乙個chunk是否為空閒,如果是空,則合併。
利用思路是溢位修改被free的chunk頭部的pre chunk size和size中的p位為0,導致合併空閒chunk。並在相鄰處偽造乙個chunk頭部。最終得到乙個任意位址寫。
例項說明
以how2heap的unsafe_unlink為例子說明,程式的注釋已經去掉
uint64_t *g_fake_chunk; //a
int main()
a unlink時檢查(f -> bk == p && b -> fd == p),需要乙個儲存著堆位址的空間,一般為乙個位址可知的變數
b 此時,記憶體分布如下:
g_fake_chunk-------> chunk0 | 0 | size(0x90) | (addr)low
| 0(fd) | 0(bk) |
| 內容0x80byte |
chunk1 | 0 | size |
| 0(fd) | 0(bk) |
| 內容0x80byte | (addr)high
chunk0和chunk1是相鄰的。此外,g_fake_chunk指向chunk0
c d e三步驟後, chunk0的記憶體分布為
chunk0 | 0 |
| 0x90 |
chunk0內容 | 0 | |---------------> g_fake_chunk-0x18| |
| 8 | | |---> g_fake_chunk-0x10| |
| g_fake_chunk-0x18 |------| | g_fake_chunk-0x8 | |
| g_fake_chunk-0x10 |-----------------| g_fake_chunk | |
此步作用是為了能通過f -> bk == p && b -> fd == p檢查,具體在free中描述
f g步驟後,chunk1的頭部被修改為:
chunk1 | 0x80 | size |p=0 |
| 0(fd) | 0(bk) |
| 0*0x80 |
這個修改表示,前一塊chunk沒有被使用,長度為0x80
h 重點來了,free非fastbin時,檢查前後chunk是否為空閒,如果是,會合併相鄰chunk。並做unlink。
為了清楚,再細畫一次此時的記憶體狀態。
chunk0 | 0 |
| 0x90 |
chunk0內容fake_chunk0 | 0 | |------------> g_fake_chunk-0x18 | |
| 8 | | |---> g_fake_chunk-0x10 | |
| g_fake_chunk-0x18 |-----| | g_fake_chunk-0x8 | |
| g_fake_chunk-0x10 |---------------| g_fake_chunk | |
| 0x60位元組 | 0x60位元組是因為去掉了偽造的chunk頭部0x20剩下的
chunk1 | 0x80 |
| size |p=0 |
| 0(fd) |
| 0(bk) |
| 0*0x80 |
由於f g步驟後,chunk1的p位被竄改為0,認為前一塊為空,大小為0x80。
計算到前一塊的頭為chunk1-0x80,即chunk0內容位置,此塊空間是漏洞利用時可控的,且c d e三步驟時在在這裡偽造了乙個chunk頭。這裡稱呼它為fake_chunk0
此時執行unlink
unlink(p) //p即g_fake_chunk0
f = p -> fd; //f = g_fake_chunk - 12
b = p -> bk; //b = g_fake_chunk - 8
if (f -> bk == p && b -> fd == p)
此時,記憶體結構為
g_fake_chunk-0x18 | |<---|
g_fake_chunk-0x10 | | |
g_fake_chunk-0x8 | | |
g_fake_chunk |g_fake_chunk-12|-----|
i 因為這個位址並不是我們想要的任意位址,要實現任意位址寫,需要把g_fake_chunk覆蓋為任意位址
堆溢位利用
0x1 申請 0x2 使用 0x3 釋放 堆塊包括塊首與塊身 返回的指標指向 塊首是乙個堆塊頭部的幾個位元組,用來標識這個堆塊自身的資訊。未被占用的堆區 被占用的堆區 位於堆區的起始位置,堆表分為兩種空閒雙向鍊錶freelist 空表 128條 和快速單向鍊錶lookaside 快表 最多只有四項 ...
STL應用之大根堆小根堆
定義 priority queue 大根堆 priority queue,greater x 小根堆 訪問最值使用 top 堆自動把最值維護在堆最上層 刪除最值使用 pop 刪除後自動維護出乙個新堆 插入元素使用 push x 插入到元素該在的位置上 並自動維護堆有序 include include...
利用堆之優先佇列
利用上一節的最大堆,中間省略了很多該刪和修改的東西,總是時學習演算法嗎 懶了一些啊,o o include include struct heap int paraent int i int leftchild int i int rightchild int i void max heap int...