Playing with the virtual table

In fact, this article is not really about a killer feature and this is also not very complicated.I decided to write this post to share with you the fun I had playing with the C++ dark internal mechanism. Or maybe this is not even fun anyway …

Some time ago, while I was reading articles about the C++ memory layout of data structures to achieve a reflection system to introspect memory at runtime, I asked me a question. I was wondering if the first member attribute of a class was always placed at the beginning of the memory layout.

For a given instance of the Foo class, I was wondering if the address of the instance is equivalent to the address of its first member. For this particular case, the answer is yes. We can represent this situation as follow :

Foo memory layout
Memory layout of an instance of Foo

I tried many different situations, with inheritance, with complex data structures, with template etc. I encountered one case that breaks my hypothesis, virtual methods. Having only inheritance is not sufficient, we also need at least one virtual method to get a different memory layout. But what happened ? It was a very good question but I knew it has something to do with the well-known virtual table.

Disclaimer 

The following code and assumptions are compiler implementation dependent even if it will run with Visual C++ and g++.

After some tests with virtual methods, I figured out that there are always 4 or 8 bytes (depending if the compiler is 32 or 64 bits) before the other members. It was the virtual table pointer called also the vpointer. In fact, the virtual table is one of the possible way to have the virtual method mechanism. In C++, this is most of the time a pointer to an array of function pointers, and this vpointer will be the first member of the class.

Representation of the vpointer

Let’s define our scenario.

We simply have a class Behavior with some virtual methods and a derived class GameScript that overrides these methods. The method Behavior::Hack() is for further use.

Without any surprise, this code displays “GameScript Update”, not really interesting. And our vpointer ? There it is :

But… wh… ? As we previously said, the vpointer is a pointer to an array of function pointers. A same object can have multiple vpointers in case of multiple inheritance.

This code works fine with g++ because the result memory layout of the derived class is the addition of the base classes memory layouts (in the right order). The base classes have no attributes expect their vpointers, this is pretty straight forward to compute the vpointer addresses.The cast to char* is necessary to use the right pointer arithmetic. Moreover static_cast is avoided here to bypass some limitation and for readability too (always prefer using static_cast in C++).

Now we know how to get the vpointer but we don’t know how to use it. Back to our example with the GameScript and the Behavior classes, we will write one method to “hack” the vtable of our class.

If we run this code, it will actually crash because the vtable is located in a read-only memory chunk. We can get rid of this protection with a single call to the windows c++ api :

And that’s it. You can run this code :

output :

All the entries of the vtable are now pointing to the same user defined method.

Is this dark magic ?

You should have a better comprehension of how virtual methods work under the hood but the goal of this kind of code is experimentation. This is not intended to be used somewhere else than experimental code and it may result into an unstable application since the implementation of virtual methods is compiler dependent. Keep it in mind.

You can find the complete source code here on my GitHub in the repository Articles.

Thanks for reading !

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2018 Vincent STEHLY--CALISTO. All Rights Reserved.

Up ↑