Skyrim RE · ground floor
Every confusion between pointers, offsets, vtables and RTTI comes from one slip: mixing up an address with the thing sitting at that address. Fix that once and the rest falls out.
One long row of bytes. Each has a number — its address. What lives there is a separate question entirely. Click a row.
Every row has an address. Only the address column is the address. Everything right of it is contents.
Useless alone. It becomes an address only when added to a base. Drag both and watch the landing spot move.
This is the step that gets collapsed. A direct call is one hop. A virtual call is two, and the second one is only decided at runtime.
Two different structures, always neighbours, and the reason Ghidra could recover MapMenu but never the method name.
symbols-*.txt."MapMenu".dynamic_cast and typeid at runtime.the consequence
Ghidra sees a function in MapMenu's vtable, reads the RTTI string beside it, and names it MapMenu::sub. The class half is real — recovered from bytes actually in the binary. The ::sub half means "unnamed" — a placeholder, not information. Roughly 77% of these functions never got further than that, which is the entire reason CommonLib's hand-curated names matter.
Answer before revealing. A wrong guess here is cheaper than a wrong guess in a hook.
Address = where. Contents = what. Never the same question.
An offset is a distance. It becomes an address only when something supplies the base.
A pointer is a cell whose contents happen to be an address. Following it is a hop, and hops must be counted, never assumed.
A vtable holds addresses and no names. RTTI holds the class name and no addresses. You need both to say what a function is.