Ho letto il testo di Aleph One su Smashing the Stack for Fun and Profit. Ho annotato example1.c
dal suo lavoro, l'ho modificato un po 'per vedere come appare lo stack sul mio sistema.
Sto utilizzando Ubuntu (64 bit) su una VM su Intel i5 M 480.
Il documento dice che una pila avrà la seguente struttura. Dice anche che la dimensione della parola è di 4 byte. Ho letto le dimensioni delle parole e ho stabilito che su un sistema operativo a 64 bit che non è "abilitato a lungo", la dimensione della parola è ancora di 32 bit o 4 byte.
Tuttavia,quandoeseguoilmiocodicepersonalizzato:
voidfunction(inta,intb,intc){charbuffer1[5];charbuffer2[10];memset(buffer1,"\xaa", sizeof(buffer1));
}
void main() {
function(1, 2, 3);
}
Non ho la stessa struttura di stack della carta. Sì, sono a conoscenza del fatto che il documento è stato pubblicato nel 1998 ma non ho trovato nessun articolo su Internet che affermi che la struttura dello stack sia stata modificata notevolmente. Ecco come appare il mio stack (sto anche caricando screenshot GDB per la verifica, nel caso in cui abbia interpretato erroneamente lo stack):
Lower memory Higher memory
-------------------------------------------------------------------------
| int c | int b | int a | buffer1 | buffer2 | RBP | RET |
| 4 bytes | 4 bytes | 4 bytes | 16 bytes | 16 bytes | 8 bytes | 8 bytes |
-------------------------------------------------------------------------
Ora per le mie domande:
- Perché la struttura dello stack è cambiata?
- Che cos'è lo spazio extra assegnato a buffer1 e buffer2? Secondo la carta dovrebbero avere solo 8 byte e 12 byte assegnati. Tuttavia, buffer2 ottiene 6 byte in più e solo allora inizia il buffer1 e persino il buffer1 è assegnato a 16 byte. Mi sto perdendo qualcosa qui? Ho letto che lo spazio allentato viene dato come meccanismo di protezione, vero?
[EDIT]
L'ABI x64 dice che lo stack è sempre allineato a otto byte (pagina 17, nota a piè di pagina numero 9).
Quindi, se i parametri ei buffer di 2 caratteri vengono inseriti nello stack, lo spazio totale occupato dallo stack è di 48 byte (o 0x30 byte). Dato che è 8 byte per 3 interi che ammontano a un totale e 24 byte e 8 byte per buffer1 e 16 byte per buffer2, arriviamo al nostro totale complessivo di 48 byte che è corroborato dallo screenshot di GDB.
Tuttavia, lo stack GDB mostra anche che gli interi (a, b e c) sono stati assegnati solo 4 byte ciascuno. I buffer occupano anche la dimensione dichiarata nel programma (ovviamente). È per questo che vedo il gioco?
Slack = 48 - (5 + 10 + 4 + 4 + 4) = 21 byte
Ho ragione?