Cos'è un "memory stomp"?


95

Mi sono appena imbattuto in questo post del blog che menziona "memoria stomping":

un programma C ++ che è facilmente in grado di calpestare la memoria (qualcosa di cui probabilmente non hai mai nemmeno sentito parlare se sei nato in un mondo di codice gestito.)

E infatti non ne ho mai sentito parlare!

Allora, cos'è questo, un ricordo che calpesta, che calpesta la memoria? Quando si verifica?


4
Un buon esempio di memory stomp è questa domanda: stackoverflow.com/questions/31016660/…
Phillip Ngan

Risposte:


117

La memoria viene "calpestata" quando un pezzo di codice manipola la memoria senza rendersi conto che un altro pezzo di codice sta usando quella memoria in un modo che è in conflitto. Ci sono diversi modi comuni in cui la memoria può essere calpestata.

Uno sta allocando, diciamo, 100 byte di memoria, ma poi memorizzando qualcosa oltre il centesimo indirizzo. Questa memoria potrebbe essere usata per contenere qualcosa di completamente diverso. Questo è particolarmente difficile da eseguire il debug perché il problema apparirà quando qualcosa cerca di accedere alla vittima che è stata calpestata e il codice che è stato calpestato potrebbe essere totalmente estraneo.

Un altro è l'accesso alla memoria dopo che è stata liberata. La memoria può essere allocata per un altro oggetto. Anche in questo caso, il codice che mostra il problema potrebbe essere correlato all'oggetto appena allocato che ha ottenuto lo stesso indirizzo e non è correlato al codice che ha causato il problema.


3
Ecco un bell'esempio di memoria che calpesta.
patryk.beza

33

Molto spesso si tratta di un sovraccarico del buffer; ad esempio, questo codice:

char buffer[8];
buffer[8] = 'a';

"calpesterà" qualunque cosa accada nella prossima cosa in memoria dopo buffer. In generale, "calpestare" è quando la memoria viene scritta involontariamente.


9

Altre risposte sono fondamentalmente corrette, ma vorrei fare un esempio.

int a[10], i;       
for (i = 0; i < 11 ; i++)
    a[i] = 0;

int i, a[10];     
for (i = 0; i < 11 ; i++)
    a[i] = 0;

Questi campioni possono portare a un ciclo infinito (o non possono portare), perché è un comportamento indefinito.

Molto probabilmente la variabile iin memoria viene archiviata subito dopo l'array. Quindi l'accesso a[10]potrebbe effettivamente accedere iin altre parole potrebbe resettare il contatore del ciclo.

Penso che sia un buon esempio che dimostra il "calpestio" della memoria.


1
C'è un altro thread, che discute più o meno lo stesso esempio su un sistema operativo diverso ... stackoverflow.com/questions/31016660
Christian

2
@Christian Non ha nulla a che fare con un sistema operativo. Questo è un comportamento indefinito.
ST3
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.