Запись таблицы виртуальных функций из класса, который не связан
Я просматриваю VFT (VMT) простой программы на C++ для Windows (у меня нет исходного кода, только бинарный), скомпилированной Visual Studio с некоторой оптимизацией.
Я заметил, что использует наследование и полиморфизм. Я нашел расположение структуры s_RTTIBaseClassArray
для каждого класса, который есть в программе. В этом месте есть массив указателей на структуру _s_RTTIBaseClassDescriptor
, Массив дескрипторов базовых классов должен предоставлять вам информацию обо всех классах, из которых получен текущий класс.
Таблица виртуальных функций (метод) - это таблица, которая содержит указатели на все виртуальные функции текущего класса. Однако в VFT нескольких классов я нашел указатель на виртуальный метод, который на самом деле принадлежит другому классу, который (согласно массиву базового класса) не связан с текущим классом. Пример ниже:
ClassA_BaseClassArray:
dd offset ClassA_BaseClassDescriptor
dd offset ClassB_BaseClassDescriptor ; ClassA inherits from ClassB
ClassB_BaseClassArray:
dd offset ClassB_BaseClassDescriptor
ClassC_BaseClassArray:
dd offset ClassC_BaseClassDescriptor
ClassA_VMT:
dd offset ClassA_VM1 ; virtual method of ClassA
dd offset ClassA_VM2
dd offset ClassB_VM2 ; virtual method of ClassB - override
dd offset ClassC_VM3 ; virtual method of ClassC - NOTHING TO DO HERE
dd offset ClassA_VM3
Пример короткий, в реальных классах гораздо больше виртуальных методов.
После осмотра ClassC_VM3
Я заметил, что он состоит всего из двух инструкций:
mov eax, [ecx+10h]
retn
До сих пор я нашел около 3 VMT, похожих на этот пример, несвязанный метод всегда такой короткий.
Мой вопрос: что это вызывает? Может ли код ClassC_VM3
быть идентичным коду некоторых ClassA
метод, так что компилятор просто оптимизировал его?
1 ответ
Это может быть вызвано свертыванием COMDAT, оптимизацией, которая объединяет функции с одинаковым точным машинным кодом в одну. Поскольку это такая простая функция, шансы на это хорошие.