我在 IDA 7 中反编译了一个 VC++ 应用程序,我经常发现 vftables 多次引用同一个函数,就像我在这里称为“Object__pure”的那个,它是Object应用程序中几乎所有其他类都继承的“重基”类的一部分:
seg002:008F4748 const Object::`vftable' dd offset Object__free ; DATA XREF: Object__ctor+12↑o Object__dtor+A↑o Object__copy+16↑o
seg002:008F474C dd offset Object__vsub_7D0990
seg002:008F4750 dd offset Object__vsub_7D09A0
seg002:008F4754 dd offset Object__pure
seg002:008F4758 dd offset Object__pure
seg002:008F475C dd offset Object__pure
seg002:008F4760 dd offset Object__pure
seg002:008F4764 dd offset Object__vsub_47B660
我的可执行文件中继承自的子类Object通常具有自己的自定义函数,而不是它们的 vtable 中的那些“纯”(我如何称呼它们)函数。
不知道那可能是什么,我给它起了个名字“纯”,把它想象成一个虚拟或纯虚拟调用。该函数本身除了调用一个完全空的之外什么都不做Object__vsub_80CD50:
seg000:007E4580 Object__pure proc near ; CODE XREF: <lots!>
seg000:007E4580
seg000:007E4580 a1 = dword ptr -4
seg000:007E4580 arg_0= dword ptr 8
seg000:007E4580
seg000:007E4580 000 push ebp
seg000:007E4581 004 mov ebp, esp
seg000:007E4583 004 push ecx
seg000:007E4584 008 mov [ebp+a1], ecx
seg000:007E4587 008 mov eax, [ebp+arg_0]
seg000:007E458A 008 push eax
seg000:007E458B 00C mov ecx, [ebp+a1] ; this
seg000:007E458E 00C call Object__vsub_80CD50 ; Call Procedure
seg000:007E4593 00C mov esp, ebp
seg000:007E4595 004 pop ebp
seg000:007E4596 000 retn 4 ; Return Near from Procedure
seg000:007E4596 Object__pure endp
...
seg000:0080CD50 Object__vsub_80CD50 proc near ; CODE XREF: <lots again!>
seg000:0080CD50
seg000:0080CD50 var_4= dword ptr -4
seg000:0080CD50
seg000:0080CD50 000 push ebp
seg000:0080CD51 004 mov ebp, esp
seg000:0080CD53 004 push ecx
seg000:0080CD54 008 mov [ebp+var_4], ecx
seg000:0080CD57 008 mov esp, ebp
seg000:0080CD59 004 pop ebp
seg000:0080CD5A 000 retn 4 ; Return Near from Procedure
seg000:0080CD5A Object__vsub_80CD50 endp
为什么这样的函数会被多次引用?是不是因为优化,统一了什么都不做的功能?这些功能通常是虚拟的/纯虚拟的吗?