How to get each index of a virtual function, how does the compiler do it?

Is there any plugin or tool that can read the .h file (or just modify Intellisense) and spit out every function and index of the virtual function table? There is a pattern that I haven’t understood yet related to polymorphism, and it becomes 5 times more complicated when you start to have 5 classes or more originating from each other. Despite this, the MSVC ++ compiler always sets the correct virtual function table index when compiling a virtual function call from C ++ to Assembly. There should be a better way to get this index without loading, breaking, reading offsets, and rewriting code, right?

Thanks!

+4
source share
3 answers

Use the hidden Microsoft C / C ++ compiler option "/ d1 reportAllClassLayout". This will print the memory layout and vtables of all your classes.

+7
source

You can try writing a hack that defines it for you - this is a specific implementation, but usually you can find a pointer to a table of virtual functions at the beginning of the class memory. If you follow this table, a list of function pointers will appear in memory (but you don't know how many). However, by searching for functions that you know about in the table of function pointers, you can determine its index.

0
source

In MSVC, you cannot view vtable at runtime and compare equality with the given pointer of a member function, since they do not match. One of them is a real pointer, the other is a pointer that indirectly refers to the real.

However, with this compiler, you can do this at runtime with another hack that I discovered.

Create a class (for example, IndexFinder) within which you declare as many instance methods as the maximum virtual methods that you can have in the class. Each of these methods should return a unique integer value, starting from 0 to the maximum.

Create a table of fake virtual methods and store the pointers to the methods so that the returned integer matches the index where you store them (the method that returns 0 will be the first in your fake vtable). When you want to find the index of any virtual method, you need to do some dirty tint on the pointer of the method element to the index of the IndexFinder method.

The principle is simple: for virtual methods, the compiler will generate code that indirectly relates to the real method using a vtable with a good index. When you replace the vtable created by the compiler with a false one, it will jump to yours and not to the intended one. Since your method returns the index within which it is stored, you just need to get the return, and you have your own index.

Here is the code that is more explicit (I repeat it depending on the hack compiler, the one who doesn't like this doesn't read it ^^). But I tried, it works fine, as it is just a redirect (I am looking for a trick with GCC, but I haven't found it yet).

Perhaps this depends on the calling agreement, I have not tried it in all cases. One of the advantages of this trick is that you do not need to instantiate your class to find the index of one of its virtual methods.

// In the header .h class IndexFinder { typedef int (IndexFinder::*method_pointer)(); public: template<typename _MethodPtr> int getIndexOf(_MethodPtr ptr) { return (reinterpret_cast<IndexFinder*>(&fake_vtable_ptr)->**((IndexFinder::method_pointer*)(&ptr)))() } protected: int method0() { return 0; } int method1() { return 1; } int method2() { return 2; } int method3() { return 3; } protected: typedef method_pointer fake_vtable_t [4]; static fake_vtable_t fake_vtable; void* fake_vtable_ptr; }; // In the cpp file IndexFinder::fake_vtable_t IndexFinder::fake_vtable = { &IndexFinder::method0 , &IndexFinder::method1 , &IndexFinder::method2 , &IndexFinder::method3 }; void* IndexFinder::fake_vtable_ptr = &IndexFinder::fake_vtable; // to use it : int index = IndexFinder::getIndexOf(&YourClass::yourVirtualMethod); 
0
source

Source: https://habr.com/ru/post/1313086/


All Articles