Запись таблицы виртуальных функций из класса, который не связан - PullRequest
0 голосов
/ 03 ноября 2018

Я просматриваю 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 Ответ

0 голосов
/ 03 ноября 2018

Это может быть вызвано свертыванием COMDAT , оптимизацией, которая объединяет функции с одинаковым точным машинным кодом в одну. Поскольку это такая простая функция, шансы на это хорошие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...