5

IDA annotates some items as: typeinfo for _classname_.

What is that typeinfo, is it the same as type_info? What information may be extracted from it? (e.g. I'd like to know the object size or virtual function table size).

I am particularly interested in GNU C++ (G++) from Android NDK for ARM.

perror
  • 19,083
  • 29
  • 87
  • 150

2 Answers2

3

These objects are indeed instances of the type_info class (or, more likely, one of its descendants). The structure of those classes is described in the Itanium C++ ABI. You can also inspect the rtti.h file from GCC.

For a trimmed-down, data-only representation of these classes, check my Recon 2012 presentation (start at slide 27 or so).

Igor Skochinsky
  • 36,553
  • 7
  • 65
  • 115
2

To add Igor Skochinsky's answer:

Given VFT address, you can print the mangled class name:

unsigned int* vmtaddr = *(int*)obj_addr;
DLOG("class name: _Z%s",((char***)vmtaddr)[-1][1]);

The class name may be decoded with c++filt.

(The _Z thing is not stored there, but required for c++filt to work.)

You can also print the inheritance chain (the trick is that typeinfo is also an object, and if it is a __cxxabiv1::__si_class_type_info, against whose mangled name we strcmp(), there has been single inheritance and a pointer to the superclass typeinfo follows the pointer to name):

    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("inheritance chain: %s",classchain);
    free(classchain);

where strrealloccat() is defined as:

char* strrealloccat(char* buffer0, char *addition)
{
    char* buffer = realloc(buffer0, (buffer0 ? strlen(buffer0) : 0) + strlen(addition) + sizeof(char));
    if (!buffer) {
    return buffer;
    }
    if(!buffer0) {
    *buffer = 0;
    }
    return strcat(buffer, addition);
}

_Z4hopeN4this5helpsE