我看到虚拟方法表(VMT,又名 VFT)包含一些奇数,例如:
obj:0x123c1a8 [704] vmt:0x611f77f8
data: 0123c1a8 f8 77 1f 61 00 96 23 01 00 00 00 00 c4 e0 b4 5c 00 00 00 00 00 00 00 00 00 00 00 00 30 f2 76 5e 78 a2 23 01 78 e0 b4 5c 00 00 00 00 14 b1 75 5e 00 00 00 00 f8 7c 1f 61 f0 a2 23 01 00 00 00 00 `w`a``#````````\````````````0`v^x`#`x``\``````u^`````|`a``#`````
vmt: 611f77f8 09 63 98 60 25 63 98 60 95 67 98 60 e5 67 98 60 9d 68 98 60 e1 2f 9f 5c 51 07 9f 5c 45 07 9f 5c 49 07 9f 5c 4d 07 9f 5c 99 a3 69 5e a1 a3 69 5e 31 dd 68 5e a1 dd 68 5e d1 dd 68 5e c1 dd 68 5e `c``%c```g```g```h```/`\Q``\E``\I``\M``\``i^``i^1`h^``h^``h^``h^
(你会在虚函数表的开头看到这些奇怪的 0x60986309 和 60986325。)
虚函数表中存储了什么?
编译器是 GCC,更准确地说,是来自 Android NDK 的用于 ARM 的 G++(GNU C++)。
编辑:我看到 VMT 包含不是函数指针的条目。
这是 Qt 类的反汇编代码QSystemLocale,您会看到成对的行,这些是 IDA 输出行,后跟由以下处理的相同行c++filt:
_ZTV13QSystemLocale DCD 0, _ZTI13QSystemLocale, _ZN13QSystemLocaleD2Ev+1, _ZN13QSystemLocaleD0Ev+1
vtable for QSystemLocale DCD 0, typeinfo for QSystemLocale, QSystemLocale::~QSystemLocale()+1, QSystemLocale::~QSystemLocale()+1
DCD _ZNK13QSystemLocale5queryENS_9QueryTypeE8QVariant+1
DCD QSystemLocale::query(QSystemLocale::QueryType, QVariant) const+1
DCD _ZNK13QSystemLocale14fallbackLocaleEv+1
DCD QSystemLocale::fallbackLocale() const+1
在这里我们看到:
VMT一开始就有一个可疑的0。建议有时它可能不是 0 是合理的,因为它发生在上面的转储中,但它是什么?见这里。
有类型信息。它允许做什么?见这里。
有两个析构函数,
_ZN13QSystemLocaleD2Ev和_ZN13QSystemLocaleD0Ev。看看为什么。最后:
我可以确定 VMT 没有在运行时初始化/修改吗?如果它被写入,写入什么?
该typeinfo是:
EXPORT _ZTI13QSystemLocale
EXPORT typeinfo for QSystemLocale
_ZTI13QSystemLocale DCD _ZTVN10__cxxabiv117__class_type_infoE+8, _ZTS13QSystemLocale
typeinfo for QSystemLocale DCD vtable for __cxxabiv1::__class_type_info+8, typeinfo name for QSystemLocale