2018 10 24. pwn的學習堆的學習,堆塊,堆表的概念,堆當中的操作,什麼是雙向連結串列,堆分配函式,fgets函式能造成溢位嗎?
堆的學習 堆,動態增長的連結串列, 申請方式:常用函式申請,通過返回的指標使用,malloc() 釋放方式:通過free進行釋放 管理方式:需要程式設計師處理申請和釋放 增長方向:記憶體從低地址向高地址 特點: 雜亂:堆區經過反覆的申請,釋放操作之後,原本大片連續的空閒區呈現出大小不同且空閒塊和佔用塊交錯的區域 給出一些概念: 什麼是堆塊: 堆區的記憶體按不同大小組織成的塊,結構當中有塊首和塊身 塊首:堆塊頭部的幾個位元組,標誌堆塊自身的資訊(本塊的大小,本塊的空閒或者佔用) 塊身:儲存的區域 什麼是堆表: 位於是在堆區的起始位置,索引堆區中所有堆塊的重要訊息(包括堆塊中的位置,堆塊的大小,空閒還是佔用) 在Windows當中,被佔用的堆塊由程式進行索引,而空閒的堆塊由堆表進行索引 堆表分為兩種: 空表(空閒雙向連結串列Freelist) 空閒堆塊的塊首包含一對重要的指標,用於將空閒堆塊組織成雙向連結串列 裡面有128個指標陣列,成為空表索引,陣列的每一項包含兩個指標,用於標誌一條空表 free[0]儲存的是堆的大小為1k-512k的堆塊 free[1]...[n]之後的儲存的是堆的大小為n*8位元組大小 快速單向連結串列(Lookaside) Windows加快堆塊分配而採用的一種堆表,不會發生堆塊合併(空閒塊的塊首被設定成為佔用態,防止合併) 結構和空表類似但是按照單鏈表進行組織,塊表總是初始化為空,每個塊表當中4個結點,很容易就填滿 堆當中的操作 堆塊分配: 快表分配:尋找大小匹配的塊,將其狀態改為佔用態,然後返回一個執行堆塊塊身的指標給程式使用 普通空表分配:最優,次優 零號空表分配:反向能否滿足要求,能的話正想 找零錢:如果空表中無法匹配到最優的堆塊,一個比較大的堆塊就會用於分配,會按照請求割一部分,將剩下的注入塊首,鏈入空表 注意:塊表精確匹配的時候才會分配(所以不存在找零錢現象) 堆塊釋放: 改為空閒,鏈入 堆塊合併: 卸下 合併 調整合並的塊首資訊 什麼是雙向連結串列? 雙向連結串列也叫雙鏈表,是連結串列的一種,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅。 所以,從雙向連結串列中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向迴圈連結串列。 fgets函式能造成緩衝區溢位嗎? 能夠造成緩衝區的溢位 堆分配函式: 在windows函式下面使用nrdll.dll中的RtlAllocateHeap()函式進行分配,這個函式也是在使用者態能夠看到的堆分配函式