虚表中的纯虚函数会被编译器统一替换成_purecall.
;构造函数
CVirtualBase::CVirtualBase:
0040787F 59 pop ecx
00407880 89 4D F8 mov dword ptr [this],ecx
00407883 8B 45 F8 mov eax,dword ptr [this]
00407886 C7 00 6C 8F 49 00 mov dword ptr [eax],offset CVirtualBase::`vftable' (0498F6Ch)
0040788C 8B 45 F8 mov eax,dword ptr [this]
;虚表首地址 00403B3E
00498F6B ?? ?? ??
00498F6C 3E 3B 40 00 cmp eax,dword ptr ds:[eax]
00498F70 00 00 add byte ptr [eax],al
__purecall:
00403B3E E9 3D 7A 00 00 jmp _purecall (040B580h)
;注意到下面 3个move 3个call 是个不错特征
extern "C" int __cdecl _purecall()
{
0040B580 55 push ebp
0040B581 8B EC mov ebp,esp
0040B583 83 EC 08 sub esp,8
_purecall_handler const purecall_handler = _get_purecall_handler();
0040B586 E8 C5 87 FF FF call __get_purecall_handler (0403D50h)
0040B58B 89 45 FC mov dword ptr [purecall_handler],eax
if (purecall_handler != nullptr)
0040B58E 83 7D FC 00 cmp dword ptr [purecall_handler],0
0040B592 74 11 je _purecall+25h (040B5A5h)
{
purecall_handler();
0040B594 8B 45 FC mov eax,dword ptr [purecall_handler]
0040B597 89 45 F8 mov dword ptr [ebp-8],eax
0040B59A 8B 4D F8 mov ecx,dword ptr [ebp-8]
0040B59D E8 81 82 FF FF call @_guard_check_icall@4 (0403823h)
0040B5A2 FF 55 F8 call dword ptr [ebp-8]
}
abort();
0040B5A5 E8 97 6E FF FF call _abort (0402441h)
}
0040B5AA 8B E5 mov esp,ebp
0040B5AC 5D pop ebp
0040B5AD C3 ret