如果你多次释放一块内存,它可能会破坏分配器的数据并打开攻击的门。事情是这样的:当你释放一块内存时,它会返回到一个空闲块的列表中(例如“快速 bin”)。如果你连续两次释放同一块内存,分配器会检测到这一点并抛出错误。但如果你在两次释放之间释放了另一块内存,双重释放检查就会被绕过 ,导致数据损坏。
Copy #include <stdio.h>
#include <stdlib.h>
int main () {
// Allocate memory for three chunks
char * a = ( char * ) malloc( 10 ) ;
char * b = ( char * ) malloc( 10 ) ;
char * c = ( char * ) malloc( 10 ) ;
char * d = ( char * ) malloc( 10 ) ;
char * e = ( char * ) malloc( 10 ) ;
char * f = ( char * ) malloc( 10 ) ;
char * g = ( char * ) malloc( 10 ) ;
char * h = ( char * ) malloc( 10 ) ;
char * i = ( char * ) malloc( 10 ) ;
// Print initial memory addresses
printf( "Initial allocations:\n" ) ;
printf( "a: %p \n" , ( void * )a) ;
printf( "b: %p \n" , ( void * )b) ;
printf( "c: %p \n" , ( void * )c) ;
printf( "d: %p \n" , ( void * )d) ;
printf( "e: %p \n" , ( void * )e) ;
printf( "f: %p \n" , ( void * )f) ;
printf( "g: %p \n" , ( void * )g) ;
printf( "h: %p \n" , ( void * )h) ;
printf( "i: %p \n" , ( void * )i) ;
// Fill tcache
free(a) ;
free(b) ;
free(c) ;
free(d) ;
free(e) ;
free(f) ;
free(g) ;
// Introduce double-free vulnerability in fast bin
free(h) ;
free(i) ;
free(h) ;
// Reallocate memory and print the addresses
char * a1 = ( char * ) malloc( 10 ) ;
char * b1 = ( char * ) malloc( 10 ) ;
char * c1 = ( char * ) malloc( 10 ) ;
char * d1 = ( char * ) malloc( 10 ) ;
char * e1 = ( char * ) malloc( 10 ) ;
char * f1 = ( char * ) malloc( 10 ) ;
char * g1 = ( char * ) malloc( 10 ) ;
char * h1 = ( char * ) malloc( 10 ) ;
char * i1 = ( char * ) malloc( 10 ) ;
char * i2 = ( char * ) malloc( 10 ) ;
// Print initial memory addresses
printf( "After reallocations:\n" ) ;
printf( "a1: %p \n" , ( void * )a1) ;
printf( "b1: %p \n" , ( void * )b1) ;
printf( "c1: %p \n" , ( void * )c1) ;
printf( "d1: %p \n" , ( void * )d1) ;
printf( "e1: %p \n" , ( void * )e1) ;
printf( "f1: %p \n" , ( void * )f1) ;
printf( "g1: %p \n" , ( void * )g1) ;
printf( "h1: %p \n" , ( void * )h1) ;
printf( "i1: %p \n" , ( void * )i1) ;
printf( "i2: %p \n" , ( void * )i2) ;
return 0 ;
}
Copy 初始分配:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
重新分配后:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
d1: 0xaaab0f0c2300
e1: 0xaaab0f0c22e0
f1: 0xaaab0f0c22c0
g1: 0xaaab0f0c22a0
h1: 0xaaab0f0c2380
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0