3

I am reversing an application for the 3ds which are compiled with ARMCC.

I found the vtables of the key classes and have a problem figuring out how the C++ representation of these was.

Vtable of first base class:

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

Vtable of second base class:

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

Now the problematic one:

Vtable of Actor class:

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

At the beginning I assumed that these are pure virtual function (Actor::function20-1()=0;) but these "gaps" in the vtables are not "overwritten" by any top level classes and thus the gaps also end up in their vtables.

What causes these empty vtable entries and how'd the C++ representation look like?

2 Answers 2

2

Two possibilities come to mind:

  1. These are slots for pure virtual methods. In many implementations the compiler provides something like __purecall or __cxa_pure_virtual to catch accidental calls, but since they are not supposed to happen anyway, a NULL works just as well on resource-constrained platforms.

  2. Itanium C++ ABI reserves two slots preceding the function table itself for the offset to top and typeinfo pointer.

In most classes, offset to top is 0 and the typeinfo pointer can be zero as well if RTTI is not used, so normally you would see two zeroes between vtables, so I strongly suspect you have the case #1.

As for why they're not overridden, maybe it's a bug in the source code. As long as they're not actually called it's all kosher from the C++ point of view AFAIK.

0

After reversing a bit more:

It cannot be __cxa_pure_virtual. I found the implementation for that in my binary.

It looks like the compiler just did some very poor optimizations: The virtual function slot is never called so the corresponding functions were optimized away but it didn't actually shift the slot indices. Interesting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.