Per quanto riguarda perché 0x0C
sembra più comune di 0x08
(è davvero? Non so, e in quali tipi di applicazioni?), questo potrebbe avere a che fare con i puntatori di tabella dei metodi virtuali. Questo è davvero più di un commento (ipotesi di massa selvaggia :), ma è un po 'più grande, quindi ecco qui ... Se hai una classe con metodi virtuali, i suoi campi saranno spostati da 0x04
. Ad esempio, una classe che eredita da un'altra classe virtuale potrebbe avere un layout di memoria come questo:
0x00 - VMT pointer for parent
0x04 - Field 1 in parent
0x08 - VMT pointer for child
0x0C - Field 1 in child
Questo è uno scenario comune o addirittura vicino? Non ne sono sicuro. Tuttavia, tieni presente che in un'applicazione a 64 bit, questo potrebbe essere spostato in modo ancora più interessante verso il valore 0x0C
:
0x00 - VMT parent
0x08 - Field 1 parent
0x0C - VMT child
0x14 - Field 2 child
Quindi in realtà ci sono molti casi in cui le applicazioni potrebbero avere una sovrapposizione significativa negli offset del puntatore nullo. Potrebbe essere il primo campo di una classe figlio o il puntatore della tabella del metodo virtuale, necessario ogni volta che si chiama un metodo virtuale su un'istanza, quindi se si chiama un metodo virtuale su un puntatore null
, si otterrà l'accesso violazione sul suo offset VMT. La prevalenza di questo particolare valore potrebbe quindi avere qualcosa a che fare con alcune API comuni che forniscono una classe che ha un modello di ereditarietà simile o, più probabilmente, un'interfaccia particolare (abbastanza possibile per alcune classi di applicazioni, come i giochi DirectX). Potrebbe essere possibile tracciare alcune semplici cause comuni come questa, ma tendo a liberarmi delle applicazioni che fanno il dereferenziamento nullo abbastanza rapidamente, quindi ...