Virtual Functions are a fundamental aspect of OOP programming features such as polymorphism. Any Virtual Functions are stored within a dispatch table called a VTable or Virtual Method Table. The VTable is essentially a array of virtual function pointers. It is possible to find the VTable using WinDbg, and I will demonstrate this within this blog post.
Virtual Functions and Virtual Function Table Pointers
I’ve written a very simple program using C++ to demonstrate the syntax of Virtual Functions.
As you can see, there are two classes called A and B. A is the base class in which Class B will inherit any members or member functions from. By using the virtual keyword on the function in Class A called Function, it specifies that the function is a Virtual Function and not a standard function.
When Class B inherits Class A’s properties, then the Function is redefined within Class B which can be seen on Line 14. Please note this is not function overloading, since the function still retains the same type and the same of number parameters, which wouldn’t be the case for function overloading. The redefinition of a function within a class is called overriding, therefore Class B is overriding the definition stated originally within Class A.
By looking at the main function of our program, we can see two objects called of Class A and Class B respectively, and then a base pointer for Class A. We will use the base pointer to access any derived Classes from the base class of A. Note how we can access the Function in Class B using the base class pointer, this a demonstration of supporting polymorphism.
Each Class will actually have a pointer into the Vtable corresponding to that Class. For Example, Class B will have it’s own VTable, and each entry within the VTable will correspond to the number of virtual functions which can be called by the object belonging to that class.
These VTable pointers will be set up by the compiler, and the corresponding object pointers or this pointers will be used to as a function parameter to be used by the compiler to find the entries within the VTables. It’s important to remember that the pointer for Class A’s VTable can’t access the members for Class B’s VTable, although, Class B is able to access Class A’s table members. Another key point to consider is that the function pointers within VTable for a inherited class, will point to the overridden version of that function.
For example, Class B’s Function() will not point to Class A’s version of Function. Here’s a good illustration to demonstrate this concept:
In real terms, you can use the same kind of prototype or interface of a function, and then make it specific to your needs or that particular object.
VTables and WinDbg
Please bear in mind, that the following extensions only apply to processes which were written with the .NET Framework, I created a similar program with C# to demonstrate these debugging extensions. There is another method but I’ve heard it’s very tedious.
To use the following extensions you will need .NET Framework 4 or .NET Framework 4.5. The .NET Framework is required due to the DLLs we need to load into WinDbg. Some people have found this difficult to set up and therefore I will show some basic steps.
1) Load the executable into WinDbg using CTRL + E.
2) Load the following DLLs with the !load extension, you must specify the full file path, otherwise WinDbg will show a can’t find file error:
3) Now, hopefully you inserted a Console.ReadLine function into your code, so the program pauses while in WinDbg. If so, then enter the g command into WinDbg and press Enter. This should enable the process to continue running and will load the CLR.dll.
4) Use the .loadby command with sos clr, and then enter the desired .NET debugging extensions.
If you followed the steps correctly, then the !dumpheap extension should work correctly. If not, then please make sure you have followed the instructions or leave a comment in the comments section.
I’ve named the namespace of my program VirtualTable, so that’s the reasoning for the VirtualTable name appearing. The MT column contains the address of the Method Table or the Function Table (in terms of C/C++).
We can then use the !dumpmt extension to show some information about the Method Table for that particular class or class object.
A listing of the debugging extensions associated with SOS.dll can found in the Additional Reading section.
As a result of the possible exploits related to the VTable, some compilers have introduced some security features which help combat against these exploits. Some of these protections include VtGuard for Microsoft Visual Studio and Virtual Table Verification for GCC compilers.
The exploit I have read, is related to changing the VTable pointer to a different VTable and then executing the virtual functions from that VTable which would allow the injection of shellcode.
VtGuard uses a combination ASLR and then adding a extra entry to the VTable for a given class. The extra member is called _vtguard, and is hidden from the attacker with the use of ASLR. The method uses the cmp instruction to compare the address of the VTable Entry against the VTable Guard, and will terminate the process if these two addresses do not match.
Virtual Table Verification works by verifying that VTable pointers point to the base class and are valid for that class. Place any important data structures in protected areas of memory. The Base Class Virtual Table Pointers will be gathered at runtime, and then assigned to a _vtable map variable which can be used for comparison between the mapped _vtable map pointer and the _vptr gathered from the class object.
C++ Virtual Table
SOS.dll Debugging Extensions
Virtual Table Verification
Recursive !dumpmt – WinDbg