I was reversing some C++ code and encountered following function.
sub_106C0A0 proc near
var_10= dword ptr -10h
var_C= dword ptr -0Ch
var_4= dword ptr -4
push 0FFFFFFFFh
push offset SEH_106C0A0
mov eax, large fs:0
push eax
mov large fs:0, esp
push ecx
push esi
mov esi, ecx
push edi
lea edi, [esi+4]
push 30h
mov ecx, edi
mov [esp+1Ch+var_10], esi
mov dword ptr [esi], offset off_12C0680
call struc_13_ctor
mov dword ptr [edi], offset off_12C057C ; another vtable init ?
This function passes this pointer of some object (struc_13), which is esi+4, to the struc_13_ctor. Inside the struc_13_ctor function, it initializes the vtable pointer and other member variables.
; int __thiscall struc_13_ctor(struc_13 *this, __int16 a2)
struc_13_ctor proc near
arg_0= word ptr 4
mov dx, [esp+arg_0]
mov eax, ecx
xor ecx, ecx
mov dword ptr [eax], offset struc_13_vtable
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+0Ch], dx
mov [eax+0Eh], cx
mov [eax+14h], ecx
mov [eax+10h], ecx
retn 4
struc_13_ctor endp
However after returning from struc_13_ctor, it overwrites the vtable pointer with the new value, which is off_12C057C in this case.
call struc_13_ctor
mov dword ptr [edi], offset off_12C057C ; another vtable init ?
I have seen this kind of behaviors a lot while looking at ctor functions, but never understood why this happens.
edi
in the main function gets moved toecx
, then moved toeax
in thestruc_13_ctor
function. So themov dword ptr [eax], offset struc_13_vtable
in the called function and themov dword ptr [edi], offset off_12C057C
access the same memory address. The OP's question was, why does the outer function overwrite the vtable?