c++objectvtablevmt

Completely overriding the VMT (Virtual Method Table)


I'm calling a virtual method on the vmt by dereferencing until I get the pointer to the method.

This is all good however, how would I completely change the pointer to the VM table on the object?

Example:

PP A; // points to its default VM table

PP B; // points to a completely different VM table

A->MethodOne() // calls as mentioned above

B->MethodOne() // calls a completely different method since we override its pointer to the VM table to an alternate table with different method pointers

How would I accomplish this?

My Code:

#include <Windows.h>
#include <iostream>

class PP
{
public:
    PP() { }
    ~PP() { }

    virtual void MethodOne() { std::cout << "1" << std::endl; }
    virtual void MethodTwo() { std::cout << "2" << std::endl; }
};

typedef void (*MyFunc)(void);

int main()
{
    PP* A = new PP();

    //(*(void(**)(void))(*(DWORD*)A + (4*1)))();
                      
    ( *(MyFunc*) ( *(DWORD*)A + (4*0) ) )(); // call index 0 (4bytes*0)
    A->MethodOne();
    A->MethodTwo();
    system("PAUSE");
    delete A;
    return 0;
}

Solution

  • Since the usual method of deriving another class won't work for you, there are three solutions I can think of.

    1. Change the vtable pointer. This is non-portable and has many ways to just go horribly wrong. Assuming the vtable is at the start of the class (which it is for simple classes in the WinAPI), you can replace that pointer with one to a table of your own.

      *(void **)A = newVtable;
      

    with newVtable defined with appropriate pointers-to-member-functions. You'll have to use extreme caution to set this up. It could also mess up deletes and exception handling.

    1. Create your own vtable. Define a class with the required pointer-to-method-functions, then define a pointer in your class to one of these. You can then change the pointer to the table as necessary. This would be a bit more verbose on calling, although you could define other member functions to hide the ugly code.

      class vtable;
      
      class PP {
      public:
          PP();
          ~PP() { }
      
          void MethodOne() { std::cout << "1" << std::endl; }
          void MethodTwo() { std::cout << "2" << std::endl; }
      
          const vtable *pVtable;
      };
      
      class vtable {
      public:
          void (PP::*MethodOne)();
      };
      
      vtable One = {&PP::MethodOne};
      vtable Two = {&PP::MethodTwo};
      
      PP::PP(): pVtable(&One) { }
      
      void main() {
          PP* A = new PP();
      
      
          A->pVtable = &One;
      
          // call with
          (A->*(A->pVtable->MethodOne))();    // calls MethodOne
      
          A->pVtable = &Two;
          (A->*(A->pVtable->MethodOne))();    // calls MethodTwo
      }
      

    (Compiled and tested with VS2015 Community). This would be portable and safe.

    1. Define method pointers within the class, and update them individually.