Chcete-li přidat odpověď Igora Skochinského:
Vzhledem k adrese VFT můžete vytisknout název změněné třídy:
unsigned int * vmtaddr = * (int *) obj_addr; DLOG ("název třídy: _Z% s", ((char ***) vmtaddr) [- 1] [1]);
Název třídy lze dekódovat pomocí c++filt
.
(Věc _Z
tam není uložena, ale je vyžadována pro c ++ filt
to work.)
Můžete také vytisknout dědický řetězec (trik spočívá v tom, že typeinfo je také objekt, a pokud se jedná o __cxxabiv1 :: __ si_class_type_info
, proti jehož zmanipulované jméno jsme strcmp ()
, došlo k jediné dědičnosti a ukazatel na superclass typeinfo následuje za ukazatelem na název):
char * classchain = strrealloccat ( NULL, "_Z"); char ** ptypeinfo = ((char ***) vmtaddr [-1]); for (; ptypeinfo; ptypeinfo =! strcmp (((char ***) ptypeinfo [0]) [- 1] [1], "N10__cxxabiv120__si_class_type_infoE")? (char **) ptypeinfo [2]: 0) {// DLOG ("tinfo:% p", ptypeinfo); // DLOG ("class: _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 ("dědický řetězec:% s", třída); free (classchain);
kde strrealloccat ()
je definován jako:
char * strrealloccat (char * buffer0, char * dodatek) {char * buffer = realloc (buffer0, (buffer0? strlen (buffer0): 0) + strlen (doplněk) + sizeof (char)); if (! buffer) {return buffer; } if (! buffer0) {* buffer = 0; } return strcat (buffer, addition);}
_Z4hopeN4this5helpsE