Glibc'deki malloc uygulamasının nasıl çalıştığını anlamaya çalışıyorum. Malloc'un kaynak koduna göre (glogc 2.23'te malloc.c) boş bellek parçaları aşağıdaki yapıya sahiptir.Ubuntu 16.04 - malloc uygulaması. Bir sonraki parçaya işaretçi nerede?
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`head:' | Size of chunk, in bytes |P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Forward pointer to next chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Back pointer to previous chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused space (may be 0 bytes long) .
. .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Normalde de gnu hata ayıklayıcı (gdb) bu yapıyı görmek gerekir. Ben de şu programı yazdım. Program, 64 Byte büyüklüğünde 6 bellek parçasını ayırır. Her bir parça memset ile doldurulur, bu yüzden gdb'de daha sonra gelen öbekleri kolayca görebiliriz. 1,3 ve 6 numaralı parçalar serbest bırakıldığı için yukarıda belirtilen yapıya sahip olmalıdır. Arasında serbest bırakılan parçalar bulunduğundan, serbest bırakılan parçalar birleştirilemez ve sonuç olarak her bir dizideki işaretçilerden iki katına bağlı bir listede düzenlenirler.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void to_jump();
int main(int argc, char **argv){
char *b1, *b2, *b3, *b4, *b5, *b6;
//allocate 6 chunks of memory
b1 = malloc(64);
b2 = malloc(64);
b3 = malloc(64);
b4 = malloc(64);
b5 = malloc(64);
b6 = malloc(64);
memset(b1, 'B', 64);
memset(b2, 'C', 64);
memset(b3, 'D', 64);
memset(b5, 'E', 64);
memset(b6, 'F', 64);
//free chunks 1,3 and 6
free(b1);
free(b3);
free(b6);
strcpy(b4, argv[1]); // <-- set breakpoint here
//exploit this line
free(b4);
free(b5);
free(b2);
}
void to_jump(){
printf("Exploited");
}
Ben gdb içinde Programı başlatmak ve serbest parçalar bir çift bağlantılı liste halinde organize olduğunu görmek gerekir hat strcpy(b4, argv[1]);
bir kesme noktası ayarlamak
gdb-peda$ p b1
$11 = 0x602010 ""
gdb-peda$ x/62xg 0x602000
0x602000: 0x0000000000000000 0x0000000000000051
0x602010: 0x0000000000000000 0x4242424242424242 |
0x602020: 0x4242424242424242 0x4242424242424242 | b1 (freed)
0x602030: 0x4242424242424242 0x4242424242424242 |
0x602040: 0x4242424242424242 0x4242424242424242 |
0x602050: 0x0000000000000000 0x0000000000000051
0x602060: 0x4343434343434343 0x4343434343434343 |
0x602070: 0x4343434343434343 0x4343434343434343 | b2 (allocated)
0x602080: 0x4343434343434343 0x4343434343434343 |
0x602090: 0x4343434343434343 0x4343434343434343 |
0x6020a0: 0x0000000000000000 0x0000000000000051
0x6020b0: 0x0000000000602000 0x4444444444444444 | 0x602000 is pointing to b1 (previous freed block)
0x6020c0: 0x4444444444444444 0x4444444444444444 | b3 (freed)
0x6020d0: 0x4444444444444444 0x4444444444444444 |
0x6020e0: 0x4444444444444444 0x4444444444444444 |
0x6020f0: 0x0000000000000000 0x0000000000000051
0x602100: 0x0000000000000000 0x0000000000000000 |
0x602110: 0x0000000000000000 0x0000000000000000 | b4 (will be filled trough strcpy(b4, argv[1]);
0x602120: 0x0000000000000000 0x0000000000000000 |
0x602130: 0x0000000000000000 0x0000000000000000 |
0x602140: 0x0000000000000000 0x0000000000000051
0x602150: 0x4545454545454545 0x4545454545454545 |
0x602160: 0x4545454545454545 0x4545454545454545 | b5 (allocated)
0x602170: 0x4545454545454545 0x4545454545454545 |
0x602180: 0x4545454545454545 0x4545454545454545 |
0x602190: 0x0000000000000000 0x0000000000000051
0x6021a0: 0x00000000006020a0 0x4646464646464646 | 0x6020a0 is pointing to b3 (previous freed block)
0x6021b0: 0x4646464646464646 0x4646464646464646 | b6 (freed)
0x6021c0: 0x4646464646464646 0x4646464646464646 |
0x6021d0: 0x4646464646464646 0x4646464646464646 |
0x6021e0: 0x0000000000000000 0x0000000000020e21
(çıkışından sağ tarafta yorumlar). Ama ileri işaretçiler ve önceki yığınların boyutu nerede?