No.
Il "tipo di dati" di una variabile è rilevante solo nel codice sorgente (e anche solo in alcune lingue). Indica al compilatore come trattare la variabile.
Questi tipi di dati di alto livello non esistono come tali nel codice compilato (nativo). Possono influire sulle istruzioni generate da un compilatore, ma alle istruzioni stesse non importa se i dati rappresentano un carattere o un numero.
Le variabili non esistono nell'hardware. Nell'hardware, hai posizioni di memoria e le istruzioni che operano su di esse.
Una variabile potrebbe essere vista come una vista dei dati in una posizione di memoria - se strizzi gli occhi e guardi la stessa memoria in modo leggermente diverso (una variabile diversa con tipo diverso che fa riferimento alla stessa posizione), lo stesso valore binario può avere un significato diverso .
Ad esempio, il byte 0x41 potrebbe essere interpretato come carattere codificato UTF-8 A
. Potrebbe anche essere interpretato come intero a byte singolo 65
. Potrebbe anche essere interpretato come un byte in un numero intero a più byte o in virgola mobile o come un byte in una codifica di caratteri multi-byte. Potrebbe essere il bitset 0b1000001
. Tutto dallo stesso byte nella stessa posizione di memoria. Nel linguaggio C, puoi vedere questo effetto lanciando su questi diversi tipi.
Quando hai un "buffer overflow", stai facendo qualcosa al di fuori dei limiti di ciò che il tuo compilatore o linguaggio potrebbe aspettarsi. Ma, per quanto riguarda l'hardware 1 , si stanno scrivendo byte (singoli o multipli) in una posizione di memoria. Una posizione di memoria non ha un "tipo". In effetti, l'hardware non sa nemmeno che un particolare insieme di byte crea un array o un buffer nel codice.
Ovunque accederai successivamente alla posizione di memoria nel tuo codice, le istruzioni verranno eseguite come originariamente definito. ad esempio, se si aspettavano un numero lì, agiranno su qualsiasi byte di dati come se fossero un numero.
Per usare il tuo esempio, supponendo che tu int
sia un intero con segno a 4 byte (32 bit):
+-------------+--------------------------------------------+-----------+
| Source code | char[15] | int |
+-------------+--------------------------------------------------------+
| Memory |61|61|61|62|62|62|63|63|63|64|64|64|65|65|65|EF|BE|AD|DE|
+-------------+--------------------------------------------------------+
int
Ora puoi vedere che la posizione della memoria contiene 0xEFBEADDE
, supponendo un sistema big-endian 2 . Questo è l'int int a 32 bit con segno -272716322
. Ora, se interpreti la stessa memoria di un int ( uint
) senza segno , sarebbe 4022250974
invece. Per esattamente gli stessi dati in memoria, il significato dipende interamente da come li vedi.
1 Esistono alcuni meccanismi che impediscono di scrivere nelle aree protette della memoria e, se si tenta di farlo, si bloccherà il programma.
2 x86 è in realtà little-endian, il che significa che interpreti i byte che compongono un valore più grande al contrario. Quindi su x86 avresti invece 0xDEADBEEF
, dando firmato -559038737
o non firmato 3735928559
.