这题暴露了个人几个知识盲区:
1.tcache_bins,指针指向chunk + 0x10(fd),主要由以下代码确定,用fd与 bk指向 key和next
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
/* Mark this chunk as "in the tcache" so the test in _int_free will
detect a double free. */
e->key = tcache;
e->next = tcache->entries[tc_idx];
其他像fastbins,unsortbins,smallbins,largebins均指向chunk。开始天真的以为bins[fd,bk]两个指针分别指向chunk fd/bk。应该分开理解
bin->fd====================>前向列表
bin->bk====================>反向列表
如bin->fd=>2=>0 =>bin
bin->bk=>0=>2 =>bin
这题最难的是理解
stack_var[3] = (unsigned long)(&stack_var[2]);
当时smallbin 0xa0现场是这样的
0xa0 [corrupted]
FD: 0x5555555593d0 —▸ 0x555555559290 —▸ 0x7ffff7fa0c70 (main_arena+240) ◂— 0x5555555593d0
BK: 0x555555559290 —▸ 0x5555555593d0 —▸ 0x7fffffffde20 —▸ 0x7fffffffde30 ◂— 0x0
要跳过bck->fk == bin检查
就得构造如下stack
--------------
--------------stack_var[4]
--------------stack_var[3]
--------------stack_var[2] 0x7fffffffde30
--------------stack_var[1]
--------------stack_var[0] 0x7fffffffde20
victim= stack_var[0] bck=stack_var[0]->bk 为stack_var[3]=stack_var[2]
当victim 从smallbin移出去时,bck->fd=bin,即stack_var[2] -》fd=bin,也就是stack_var[2]+0x10即stack_var[4]=bin。 stack_var[4]为bck(stack_var[3])的fd,可以满足限制,巧妙计算。
过程如下:
1。stack上构建fack_chunk,如上
2。构造9个chunk,3-8进tcache ,size为(0x90)
3。chunk1进tcache,chunk0-2进unsort bin(0与1,1与2不能同时进unsort bin,会发生memory consolidate)
4。malloc 0xa0(需>0x90),使得 unsort bin上的chunk 0与chunk 2进small bin
5。malloc(0x90)两次,释放tcache top2 slot
6。small bin head chunk (chunk2) bk设置为stack_var,
(bin:0xa0->bk) ->chunk0->chunk2->stack_var[0]->stack_var[2]
7。malloc(0x90),使得chunk0返回,由于第5步,tcache还有连个slot,chun2,fake_chunk(stack_var[0]),进tache,也就是这一步stack_var[4]值写为&oxa0 bin
tache: fake_chunk(stack_var[0])->chunk2->其他5个chunk
8。malloc(0x90),返回fake_chunk
网友评论