0

我正在浏览一个简单的 C++ Windows 程序(我没有源代码,只有二进制文件)的 VFT(VMT),它由 Visual Studio 编译并进行了某种优化。

我注意到这是使用继承和多态性。我找到了s_RTTIBaseClassArray程序具有的每个类的 struct 位置。在那个位置有一个指向 struct 的指针数组_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方法的代码相同,所以编译器只是对其进行了优化?

4

1 回答 1

2

这可能是由COMDAT 折叠引起的,这是一种将具有相同机器代码的函数合并为一个的优化。因为它是一个如此简单的功能,所以它的机会很好。

于 2018-11-03T17:53:07.117 回答