Ik heb een functie in C waarin ik twee lokale variabelen declareer:
Bij debuggen met gdb gooi ik een breakpoint op de plek die ik heb gemarkeerd. Vervolgens vraag ik de geheugen posities op van zowel password_buffer als auth_flag:
Zoals je kan zien wordt er eerst geheugen gereserveerd voor password_buffer (waar de tekst ABCDEF\x000 inzit) en daarna voor auth_flag (op 0xbffff43c). Op zich logisch en goed te begrijpen, dus nog niets raars hier.
Als ik nu het programma wijzig op onderstaande manier:
Draai ik de volgorde van variabele declaratie om: Eerst auth_flag en daarna password_buffer. Als ik dit compileer (gcc -g -fno-stack-protector -o auth_overflow2 auth_overflow2.c) en daarna gdb er weer op zet, krijg ik dit:
Het rare is dat er wederom eerst geheugen is gereserveerd voor password_buffer en daarna pas voor auth_flag. Ik wilde dat juist andersom.
Vraag: Weet iemand waarom op die manier het geheugen gereserveerd is en met name hoe ik dat kan voorkomen (compiler optie)?
C:
1
2
3
4
5
| int check_authentication(char *password) { char password_buffer[16]; int auth_flag = 0; strcpy(password_buffer, password); /* break here */ |
Bij debuggen met gdb gooi ik een breakpoint op de plek die ik heb gemarkeerd. Vervolgens vraag ik de geheugen posities op van zowel password_buffer als auth_flag:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| (gdb) print password_buffer $10 = "ABCDEF\000\000\364\237\004\bh\364\377\277" (gdb) x/32xw password_buffer 0xbffff42c: 0x44434241 0x00004645 0x08049ff4 0xbffff468 0xbffff43c: 0x00000000 0x0026f304 0x0026eff4 0xbffff468 0xbffff44c: 0x08048555 0xbffff6a3 0x0011dd20 0x080485ab 0xbffff45c: 0x0026eff4 0x080485a0 0x00000000 0xbffff4e8 0xbffff46c: 0x00144b56 0x00000002 0xbffff514 0xbffff520 0xbffff47c: 0xb7fff858 0xbffff4d0 0xffffffff 0x0012bff4 0xbffff48c: 0x080482bc 0x00000001 0xbffff4d0 0x0011d326 0xbffff49c: 0x0012c828 0xb7fffb40 0x0026eff4 0x00000000 (gdb) print &auth_flag $11 = (int *) 0xbffff43c (gdb) |
Zoals je kan zien wordt er eerst geheugen gereserveerd voor password_buffer (waar de tekst ABCDEF\x000 inzit) en daarna voor auth_flag (op 0xbffff43c). Op zich logisch en goed te begrijpen, dus nog niets raars hier.
Als ik nu het programma wijzig op onderstaande manier:
C:
1
2
3
4
5
| int check_authentication(char *password) { int auth_flag = 0; char password_buffer[16]; strcpy(password_buffer, password); |
Draai ik de volgorde van variabele declaratie om: Eerst auth_flag en daarna password_buffer. Als ik dit compileer (gcc -g -fno-stack-protector -o auth_overflow2 auth_overflow2.c) en daarna gdb er weer op zet, krijg ik dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| (gdb) print &password_buffer $2 = (char (*)[16]) 0xbffff42c (gdb) print &auth_flag $3 = (int *) 0xbffff43c (gdb) x/32xw 0xbffff42c 0xbffff42c: 0x08048378 0x0011dd20 0x08049ff4 0xbffff468 0xbffff43c: 0x00000000 0x0026f304 0x0026eff4 0xbffff468 0xbffff44c: 0x08048555 0xbffff6a3 0x0011dd20 0x080485ab 0xbffff45c: 0x0026eff4 0x080485a0 0x00000000 0xbffff4e8 0xbffff46c: 0x00144b56 0x00000002 0xbffff514 0xbffff520 0xbffff47c: 0xb7fff858 0xbffff4d0 0xffffffff 0x0012bff4 0xbffff48c: 0x080482bc 0x00000001 0xbffff4d0 0x0011d326 0xbffff49c: 0x0012c828 0xb7fffb40 0x0026eff4 0x00000000 (gdb) |
Het rare is dat er wederom eerst geheugen is gereserveerd voor password_buffer en daarna pas voor auth_flag. Ik wilde dat juist andersom.
Vraag: Weet iemand waarom op die manier het geheugen gereserveerd is en met name hoe ik dat kan voorkomen (compiler optie)?