La respuesta corta es que el índice 10 está más allá de los límites de la matriz vec
y escribir un doble de 8 bytes en vec[10]
podría sobrescribir el puntero base de la función anterior y la dirección de retorno de la función, dependiendo de cómo el compilador asigne memoria en la pila para variables locales.
Aquí hay un diagrama de la pila de tiempo de ejecución cuando se ha llamado func
(se supone arquitectura x86):
<------------ 4 bytes ----------->
.
.
.
+---------------------------------+
| data2 |
+---------------------------------+ arg 3 (8 bytes)
| data2 |
+---------------------------------+
| data1 |
+---------------------------------+ arg 2 (8 bytes)
| data1 |
+---------------------------------+
| i | arg 1
+---------------------------------+
| return address | < 8 bytes to <--\
+---------------------------------+ < be overwritten |
| previous ebp (old base pointer) | <-- "vec[10]" < by data1 |
+---------------------------------+ | stack
| vec[9] | | frame
+---------------------------------+ | for
| vec[8] | | "func"
+---------------------------------+ |
. |
. |
. |
+---------------------------------+ |
| vec[1] | |
+---------------------------------+ |
| vec[0] | <--/
+---------------------------------+
Tenga en cuenta que el compilador determina la disposición de la memoria asignada para las variables locales en un marco de pila. Esto significa que la alineación de la pila puede dar como resultado un "espacio de holgura" que elimina el cálculo del desplazamiento del búfer, por ejemplo. Además, si el compilador asigna memoria para la variable p
entre ebp
guardada y la memoria asignada para la matriz vec
, p
se sobrescribirá en lugar de la antigua ebp
y la dirección de retorno de func
.
Para obtener más información sobre el diseño del marco de pila, consulte: