L'overflow del buffer modifica il tipo di dati della variabile che sta sovrascrivendo? [chiuso]


8

Che ho un array di caratteri C char buf[15]. Supponiamo che la variabile int set_me = 0abbia i suoi dati memorizzati in una posizione di memoria subito dopo char buf[15]. Se traboccassi bufdi stringa "aaabbbcccdddeee\xef\xbe\xad\xde", set_meil tipo di dati cambierebbe da un numero intero a un array di caratteri?


3
Dipende da chi sta interpretando i dati. finalmente tutto è binario. Quindi, il modo in cui lo interpreti, può essere un valore intero valido o causare un errore di cast
Ganesh R.

Risposte:


33

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 intsia 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|
+-------------+--------------------------------------------------------+

intOra 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 4022250974invece. 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 -559038737o non firmato 3735928559.


Così 0xdeadbeef, su un'architettura x86, avrebbe preso meno spazio in memoria rispetto al suo omologo decimale, 3735928559?
Darien Springer

2
@DarienSpringer Entrambi occupano 4 byte di memoria - sono la stessa sequenza di 4 byte. Sono identici nella memoria. Potresti considerare tutto come memoria di base 2 (binario), se vuoi. Quindi, quando li visualizzi (converti in una stringa per l'output) puoi scegliere una base da visualizzare: l'esagono è la base 16 e il decimale è la base 10. Le rappresentazioni delle stringhe sono memorizzate in una diversa posizione di memoria e possono usare quantità diverse di memoria (poiché ogni carattere è un byte separato). La stringa 0xDEADBEEF è memorizzata come 0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46.
Bob,

5
@DarienSpringer In altre parole, un numero è lo stesso numero, indipendentemente dalla base in cui si trova. Hex è un modo conveniente (compatto) per visualizzare il file binario. Fisicamente, è binario. Agli umani piace il decimale, quindi più spesso visualizziamo i numeri come decimali. Ma fino a quando non si arriva alla fase di visualizzazione, tutte le operazioni numeriche (aggiunta, sottrazione, moltiplicazione, ecc.) Funzionano sugli stessi dati binari in memoria.
Bob,

1
"Puoi vedere che ora la posizione della memoria di int è 0xEFBEADDE" Nitpick: So che non lo intendevi, ma sembra che tu stia dicendo che int si trova nella posizione della memoria 0xEFBEADDE. Forse riformattalo un po '. Altrimenti questa è una risposta superba - Mi piace particolarmente l'analogia della "vista" e l'idea dello "strabismo" :)
Lightness Races in Orbit

@LightnessRacesinOrbit Un buon punto. Modificato.
Bob,

2

Dal punto di vista C, la risposta sarebbe "Chi lo sa? È un comportamento indefinito".

I tipi sono un concetto C, non hardware. Ma le regole C non si applicano se il tuo programma ha Comportamento indefinito, questo è il significato letterale di Comportamento indefinito nello standard C. E gli overflow del buffer ne sono una forma.

Inizialmente ho scritto "le regole C non si applicano più", ma in realtà il comportamento indefinito è retroattivo. Le regole C non si applicano a un programma che avrà un comportamento indefinito in futuro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.