題目是jarvisoj的guessbook2叶摄,似乎原題目是0ctf上的
首先進(jìn)入gdb,run一下程序安拟,按照流程創(chuàng)建4個(gè)note之后(在這里我創(chuàng)建的note長度都是1蛤吓,內(nèi)容是a),ctrl+c跳出程序(貌似可以用ctrl+break鍵糠赦,但是我不知道惠普的break鍵是啥啊啊盎岚痢!還有就是想要繼續(xù)調(diào)試就輸入continue
)愉棱,使用 vmmap
查看當(dāng)前內(nèi)存:
gdb-peda$ vmmap
Start End Perm Name
0x00400000 0x00402000 r-xp /home/xiaomoyuan/Desktop/ctf/jarvisOJ/guessbook/guestbook2
0x00601000 0x00602000 r--p /home/xiaomoyuan/Desktop/ctf/jarvisOJ/guessbook/guestbook2
0x00602000 0x00603000 rw-p /home/xiaomoyuan/Desktop/ctf/jarvisOJ/guessbook/guestbook2
0x00603000 0x00625000 rw-p [heap]
......
然后使用x/4gx
查看chunk的內(nèi)容唆铐,至于x/4gx
是什么意思的,具體可以看一下gdb調(diào)試的一些知識 奔滑,在這里就簡要說明一下:x命令就是用來展現(xiàn)內(nèi)存的內(nèi)容艾岂,/
后面跟的就是展現(xiàn)的格式 4gx
就是展現(xiàn)展現(xiàn)64位信息的16進(jìn)制形式,4就是一次展現(xiàn)的個(gè)數(shù)
gdb-peda$ x/4gx 0x604820+0x90
0x6048b0: 0x0000000000000000 0x0000000000000091
0x6048c0: 0x0000000000000061 0x0000000000000000
gdb-peda$ x/3gx 0x604820+0x90
0x6048b0: 0x0000000000000000 0x0000000000000091
0x6048c0: 0x0000000000000061
chunk的內(nèi)容:
gdb-peda$ x/4gx 0x603000
0x603000: 0x0000000000000000 0x0000000000001821
0x603010: 0x0000000000000100 0x0000000000000004
gdb-peda$ x/4gx 0x603000+0x1820
0x604820: 0x0000000000000000 0x0000000000000091
0x604830: 0x0000000000000061 0x0000000000000000
gdb-peda$ x/4gx 0x604820+0x90
0x6048b0: 0x0000000000000000 0x0000000000000091
0x6048c0: 0x0000000000000061 0x0000000000000000
gdb-peda$ x/3gx 0x604820+0x90
0x6048b0: 0x0000000000000000 0x0000000000000091
0x6048c0: 0x0000000000000061
gdb-peda$ x/4gx 0x6048b0+0x90
0x604940: 0x0000000000000000 0x0000000000000091
0x604950: 0x0000000000000061 0x0000000000000000
gdb-peda$ x/4gx 0x604940+0x90
0x6049d0: 0x0000000000000000 0x0000000000000091
0x6049e0: 0x0000000000000061 0x0000000000000000
gdb-peda$ x/4gx 0x6049d0+0x90
0x604a60: 0x0000000000000000 0x00000000000205a1
0x604a70: 0x0000000000000000 0x0000000000000000
gdb-peda$ p main_arena
$1 = {
mutex = 0x0,
flags = 0x1,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, #都是0朋其,因?yàn)閿?shù)據(jù)很小王浴,chunk足夠容納,用不到fastbin
top = 0x604a60, # top chunk的地址
last_remainder = 0x0,
bins = {0x7ffff7dd3b58 <main_arena+88>, 0x7ffff7dd3b58 <main_arena+88>,
0x7ffff7dd3b68 <main_arena+104>, 0x7ffff7dd3b68 <main_arena+104>,
....
free掉note 0后:
gdb-peda$ p main_arena
$2 = {
mutex = 0x0,
flags = 0x1,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x604a60,
last_remainder = 0x0,
bins = {0x604820, 0x604820, 0x7ffff7dd3b68 <main_arena+104>,
可以看到bins頭兩個(gè)地址就是我們note 0的地址梅猿,為什么是兩個(gè)呢氓辣,因?yàn)檫@是個(gè)雙向鏈表。接著袱蚓,當(dāng)我們free掉note 2后钞啸,
gdb-peda$ p main_arena
$2 = {
mutex = 0x0,
flags = 0x1,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x604a60,
last_remainder = 0x0,
bins = {0x604940, 0x604820, 0x7ffff7dd3b68 <main_arena+104>,
note 2 的地址就變成了bins[0],可知后來釋放的內(nèi)存會被放到鏈表的表頭。
這時(shí)候我們具體看看被釋放的內(nèi)存內(nèi)容具體是什么:
gdb-peda$ x/20gx 0x604820 #note 0
0x604820: 0x0000000000000000 0x0000000000000091
0x604830: 0x00007ffff7dd3b58 0x0000000000604940
0x604840: 0x0000000000000000 0x0000000000000000
0x604850: 0x0000000000000000 0x0000000000000000
0x604860: 0x0000000000000000 0x0000000000000000
0x604870: 0x0000000000000000 0x0000000000000000
0x604880: 0x0000000000000000 0x0000000000000000
0x604890: 0x0000000000000000 0x0000000000000000
0x6048a0: 0x0000000000000000 0x0000000000000000 #到這里為止
0x6048b0: 0x0000000000000090 0x0000000000000090 #91變成90
gdb-peda$ x/20gx 0x604940 #note 2
0x604940: 0x0000000000000000 0x0000000000000091
0x604950: 0x0000000000604820 0x00007ffff7dd3b58
0x604960: 0x0000000000000000 0x0000000000000000
0x604970: 0x0000000000000000 0x0000000000000000
0x604980: 0x0000000000000000 0x0000000000000000
0x604990: 0x0000000000000000 0x0000000000000000
0x6049a0: 0x0000000000000000 0x0000000000000000
0x6049b0: 0x0000000000000000 0x0000000000000000
0x6049c0: 0x0000000000000000 0x0000000000000000 #到這里為止
0x6049d0: 0x0000000000000090 0x0000000000000090 #91變成90
可以知道体斩,當(dāng)我們free掉一個(gè)chunk之后第二行用來存儲地址梭稚,前半部分用來存放fd
(forward,前一個(gè)釋放的chunk的地址)絮吵,后半部分用來存放bk
(后一個(gè)釋放的chunk的地址)弧烤。
而且還可以看到,釋放note 0蹬敲,note2前暇昂,note 1, note3第一行的后半部分本來是91的伴嗡,后來變成了90急波,為什么呢,這就涉及到關(guān)于堆內(nèi)存管理的隱式鏈表闹究,注意到在這里我們顯示的是16進(jìn)制幔崖,換句話說其實(shí)91 應(yīng)當(dāng)是 1001 0001,那么最后一個(gè)1就是隱式鏈表中用來標(biāo)記上一個(gè)chunk的狀態(tài)的渣淤,1表示正在使用赏寇,0表示處于釋放狀態(tài),我們之前free了note 0价认、note2嗅定,所以note 1、note 3的標(biāo)記位變成了0.
然后我們再創(chuàng)建note 0用踩,這時(shí)候再看看內(nèi)存:
gdb-peda$ p main_arena
$2 = {
mutex = 0x0,
flags = 0x1,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x604a60,
last_remainder = 0x0,
bins = {0x604940, 0x604940, 0x7ffff7dd3b68 <main_arena+104>,
可以看出渠退,note 0 被分配了原來的地址,也就是說脐彩,bins里面的空閑空間碎乃,是按照先進(jìn)先出的順序存取的,free的時(shí)候把地址放到鏈表頭惠奸,malloc的時(shí)候再把鏈表尾部的地址用來返回梅誓。
下面是胡言亂語,這次動手學(xué)習(xí)后認(rèn)識比較深刻的東西:
bins是FIFO(先進(jìn)先出)
16進(jìn)制中佛南,兩位代表2進(jìn)制的8位梗掰,也就是1 byte,也就是在之前顯示的內(nèi)容中嗅回,如果我們填入8個(gè)字母(8byte)及穗,占用的就是一行的內(nèi)容。
終于懂為什么題目里可以通過list打印出地址了= =