Cread Dotson
Cread Dotson

Reputation: 1092

getting virtual table pointer c++

I have a class such as

class Stuff
{
private:
int x;
virtual int buisness()
{
  return 42;
}
public:
 Stuff(){
  x = 5;
}

Given a pointer to an instance of this class

Stuff stuff;
void* thing = &stuff;

How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?

Edit: to clarify this was a challenge sent to me and I have been assured that it is not a trick question.

Upvotes: 1

Views: 2644

Answers (3)

Cread Dotson
Cread Dotson

Reputation: 1092

This may be compiler dependant. I just made a char array from the pointer "thing"

char *array;
array = (char*)thing;

Then traverse that array until I found the private variables

int x = array[8];

Upvotes: 0

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?

You can't without casting thing back to the original type:

Stuff* stuff2 = reinterpret_cast<Stuff*>(thing);

and at least that doesn't redeem you from privacy policies of that class, and how you could access class member pointers publicly.

The actual layout is implementation defined, and trying to use offsets from thing and size assumptions is beyond standard c++ mechanisms.


It sounds like you want to circumvent the private member access policies of a class with known layout of these members. Here's an extremely dirty hack:
Disclamer: Don't do that in production code!!

#include <iostream>

class Stuff {
private:
    int x;
    virtual int business() {
        std::cout << "Have that 42 ... " << std::endl;
        return 42;
    }
public:
    Stuff() {
      x = 5;
    }
};

struct StuffProxy {
    // Make the layout public:
    int x;
    virtual int business();
};

int main() {
    Stuff stuff;
    void* thing = &stuff;

    // Here's the nasty stuff
    StuffProxy* stuffProxy = reinterpret_cast<StuffProxy*>(thing);
    int* addrX = &(stuffProxy->x); // Get the address of x
    std::cout << "x = " << *addrX << std::endl;

    typedef int (Stuff::*StuffFunc)();
    StuffFunc stuffFunc = (StuffFunc)(&StuffProxy::business);
    std::cout << "business() = " << (stuff.*stuffFunc)() << std::endl;
}

Output:

x = 5
Have that 42 ... 
business() = 42

Live Demo

The above works because it's guaranteed that class and struct will have the same layout in a c++ compilers implementation, with the only difference of the members visibility during compilation.

So if you have the layout of a class (e.g. from a header), and you are willing to maintain that over the lifetime of your project, you can provide such proxy like above to access the private stuff from a class.

Upvotes: 8

Thomas Matthews
Thomas Matthews

Reputation: 57708

To access the private member x:

1) Declare the function, that needs to access x, as a friend of the class.

2) Change access to public.

3) Write public getter or setter functions.

4) Change your design; Other classes should not know about member variables.

Upvotes: 2

Related Questions