我正在反转一个使用ARMCC编译的3ds的应用程序。

我发现了关键类的vtables,并且在弄清楚它们的C ++表示方式时遇到了问题。

第一基类的Vtable:

fBase::dtor
0                     // no dtorFree
fBase::function1
fBase::function2
...
fBase::function13


第二基类的Vtable:

sBase::dtor
0                     // no dtorFree
sBase::function1
fBase::function2
...
sBase::function13


有问题的一个:Actor类的Vtable:

Actor::dtor
0                     // no dtorFree
sBase::function1
fBase::function2
... (3-12)
sBase::function13
0                     // gap in vtable?
Actor::function14
Actor::function15
... (16-19)
Actor::function20
0                     // gap in vtable?
Actor::function21
Actor::function22
... (23-34)
Actor::function35


最初,我假设它们是纯虚函数(Actor :: function20- 1()= 0;),但是任何顶级类都不会“覆盖” vtable中的这些“空白”,因此这些空白也将最终出现在其vtable中。以及C ++表示的外观如何?

#1 楼

我想到了两种可能性:


这些是纯虚方法的插槽。在许多实现中,编译器提供类似__purecall__cxa_pure_virtual之类的功能来捕获意外调用,但是由于无论如何都不会发生意外调用,因此NULL在资源受限的平台上也同样适用。函数表本身的顶部偏移量和typeinfo指针。

在大多数类中,如果不使用RTTI,则顶部偏移量为0,并且typeinfo指针也可以为零,因此通常在vtable之间会看到两个零,所以我强烈怀疑情况#1

关于为什么不覆盖它们的原因,也许是源代码中的错误。从C ++角度AFAIK来看,只要它们没有被实际使用,就完全符合犹太标准。

#2 楼

反转多一点后:

不能是__cxa_pure_virtual。我在二进制文件中找到了实现的方法。移位插槽索引。有趣。