En cuanto a por qué 0x0C
parece más común que 0x08
(¿es realmente? No lo sé; y ¿en qué tipo de aplicaciones?), Esto podría tener que ver con punteros de tabla de métodos virtuales. Esto es realmente más un comentario (adivinanzas masivas :), pero es algo más grande, así que aquí va ... Si tienes una clase con métodos virtuales, sus propios campos se cambiarán 0x04
. Por ejemplo, una clase que hereda de otra clase virtual podría tener un diseño de memoria como este:
0x00 - VMT pointer for parent
0x04 - Field 1 in parent
0x08 - VMT pointer for child
0x0C - Field 1 in child
¿Es este un escenario común, o incluso cercano? No estoy seguro. Sin embargo, tenga en cuenta que en una aplicación de 64 bits, esto podría cambiar aún más interesantemente hacia el 0x0C
valor:
0x00 - VMT parent
0x08 - Field 1 parent
0x0C - VMT child
0x14 - Field 2 child
Entonces, en realidad, hay muchos casos en los que las aplicaciones pueden tener una superposición significativa en las compensaciones de puntero nulo. Puede ser el primer campo en una clase secundaria, o su puntero de tabla de método virtual, necesario siempre que llame a cualquier método virtual en una instancia, por lo que si llama a un método virtual en un null
puntero, obtendrá una infracción de acceso en su VMT offset. La prevalencia de este valor particular podría tener algo que ver con alguna API común que proporciona una clase que tiene un patrón de herencia similar, o más probablemente, una interfaz particular (bastante posible para algunas clases de aplicaciones, como los juegos de DirectX). Es posible rastrear alguna causa común simple como esta, pero tiendo a deshacerme de las aplicaciones que anulan la referencia nula con bastante rapidez, así que ...
0000000C
es mucho más común que eso00000008
, pero ninguna de las respuestas parece abordar eso en absoluto: /