Virtual table layout on MSVC- where's the type info?
Asked Answered
A

2

5

I have the following C++ code illustrating virtual methods:

class X{
    O a;
    H b;
    virtual void c() = 0;
    virtual void d() = 0;
};

class Y : public X{
    virtual void c();
    virtual void d();
};

which outputs the following vtable layout on MSVC:

1>  class X size(24):
1>      +---
1>   0  | {vfptr}
1>   8  | a
1>  16  | b
1>      +---
1>  
1>  X::$vftable@:
1>      | &X_meta
1>      |  0
1>   0  | &X::c
1>   1  | &X::d
1>  
1>  X::c this adjustor: 0
1>  X::d this adjustor: 0
1>  
1>  
1>  class Y size(24):
1>      +---
1>      | +--- (base class X)
1>   0  | | {vfptr}
1>   8  | | a
1>  16  | | b
1>      | +---
1>      +---
1>  
1>  Y::$vftable@:
1>      | &Y_meta
1>      |  0
1>   0  | &Y::c
1>   1  | &Y::d
1>  
1>  Y::c this adjustor: 0
1>  Y::d this adjustor: 0
1>  
1>  

After reading Inside the C++ object model I was wondering in the above vtable layouts where is the type info?

In the book (I think they use GCC vtable layout) the type info would be in the 0th element of the vtable. For MSVC this is not the case as its a virtual function- so where is the type info stored?? Is that what "_meta" is??

Acie answered 8/3, 2014 at 1:40 Comment(0)
A
6

Is that what "_meta" is??

Yes. What did you think that meant, other than polymorphic metadata?

Asp answered 8/3, 2014 at 1:50 Comment(3)
I thought it meant something which if it doesn't have an array index (as in the above diagram)- it isn't going to be retrievable, hence my question.... So how is it retrieved if its not array element 0 or 1? Would it be a special non-array access?Acie
@user997112: Indeed, it's not an entry in the virtual function table; it's a separate field in the metadata structure, but just as accessible.Asp
I've noticed that there's one case where the _meta entry doesn't appear to be listed in the vftable: If the class declares no new virtual functions, and reuses a vtable from a virtual base class. For example, if you have struct NoMBase { virtual void x() {} };, and define the child class struct No_Meta : virtual NoMBase {};, then No_Meta::$vftable@ won't list a &No_Meta_meta entry, and the number above the actual entries, will be -4 or -8 instead of 0 (presumably to account for {vbptr}). I'm curious as to whether this has any significance.Funda
S
4

For MSC you will find it useful to search more information on RTTICompleteObjectLocator, which isn't quite documented but looks roughly like this:

struct RTTICompleteObjectLocator
{
    DWORD signature;
    DWORD offset;
    DWORD cdOffset;
    struct TypeDescriptor*;
    struct RTTIClassHierarchyDescriptor*;
};

It is indeed located adjacent to the vtable, so it can be easily located by pointer adjustment in the generated assembly.

This is the source I've kept in my bookmarks for a couple of years: P. Sabanal, M.Yason. Reversing C++, Black Hat DC 2007

Soapberry answered 8/3, 2014 at 1:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.