Pour ajouter la réponse d'Igor Skochinsky:
Étant donné l'adresse VFT, vous pouvez afficher le nom de la classe mutilée:
unsigned int * vmtaddr = * (int *) obj_addr; DLOG ("nom de la classe: _Z% s", ((car ***) vmtaddr) [- 1] [1]);
Le nom de la classe peut être décodé avec c++filt
.
(La chose _Z
n'est pas stockée ici, mais requise pour c ++ filt
pour fonctionner.)
Vous pouvez également imprimer la chaîne d'héritage (l'astuce est que typeinfo est aussi un objet, et s'il s'agit d'un __cxxabiv1 :: __ si_class_type_info
, contre dont le nom mutilé nous strcmp ()
, il y a eu un héritage unique et un pointeur vers la superclasse typeinfo suit le pointeur vers le nom):
char * classchain = strrealloccat ( NULL, "_Z"); char ** ptypeinfo = ((char ***) vmtaddr [-1]); pour (; ptypeinfo; ptypeinfo =! strcmp (((char ***) ptypeinfo [0]) [- 1] [1], "N10__cxxabiv120__si_class_type_infoE")? (char **) ptypeinfo [2]: 0) {// DLOG ("tinfo:% p", ptypeinfo); // DLOG ("classe: _Z% s meta: _Z% s", ptypeinfo [1], ((char ***) ptypeinfo [0]) [- 1] [1]); // DLOG ("meta: _Z% s", ((char ***) ptypeinfo [0]) [- 1] [1]); classchain = strrealloccat (strrealloccat (classchain, ptypeinfo [1]), "_Z"); } DLOG ("chaîne d'héritage:% s", chaîne de classes); free (classchain);
où strrealloccat ()
est défini comme:
char * strrealloccat (char * buffer0, char * addition) {char * buffer = realloc (buffer0, (buffer0? strlen (buffer0): 0) + strlen (addition) + sizeof (char)); if (! buffer) {tampon de retour; } if (! buffer0) {* buffer = 0; } return strcat (buffer, addition);}
_Z4hopeN4this5helpsE