如何查找C++虚拟表?

问题描述

一个简单的示例代码如下:

#include <iostream>

class Base
{
public:
    virtual void func0() { std::cout << "Base::func0" << std::endl; };
    virtual void func1() { std::cout << "Base::func1" << std::endl; };
};


int main()
{
    auto instance = Base();
    uint64_t* vtableAddr = reinterpret_cast<uint64_t*>(&instance);
    uint64_t* pVtable = reinterpret_cast<uint64_t*>(*vtableAddr);
    auto func0 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 0));
    auto func1 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 1));
    func0(&instance);
    func1(&instance);

    auto func2 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 2)); // exceed the limitation
    func2(&instance); // core dump
}

我可以通过读取类首先 8 个字节(64 位编译器)来获取虚拟表地址。但是不知道有没有办法在运行时获取pVtable的最大合法偏移量。
如上例,如果我设置pVtable的offset为2,调用转换后的函数,会导致coredump。
每个类的虚拟表“大小”是否存储在任何位置?

解决方法

不能保证 vtable 存在,一旦您处理更复杂的继承(多个/虚拟和多个/虚拟的组合),您将非常失望。来自@Stephen Newell