0

This is something that I found in a lot of constructors that have to do with classes that inherit from other classes. I have a vague idea as to why it's done, but I'd rather have it confirmed before having to re-visit all of my classes.

Say I have a constructor with a known signature e.g. CPalette(). The compiler turn this into a CPalette * __thiscall CPalette::CPalette(CPalette* this), with this being in ecx. Hence, no values need to be retrieved from the stack. However, when the constructor is called, it looks something like this:

// with allocated memory in eax
PUSH   0x01
MOV    ecx, eax
CALL   CPalette::CPalette

Inside the constructor, this value is then used in a test:

// start of constructor
PUSH   -0x01
PUSH   label_1
MOV    eax, fs:[0x00]                  // question for another day
PUSH   eax
MOV    dword ptr fs:[0x00], esp        
SUB    esp ,0x8
MOV    eax, dword ptr [esp + 18]       // Ghidra: ... [esp + Stack[0x04]]
PUSH   esi
MOV    esi, ecx
PUSH   edi
TEST   eax, eax
MOV    dword ptr [esp + 0x08], esi     // Ghidra: ... [esp + local_14]
MOV    dword ptr [esp + 0x18], 0x00    // Ghidra: ... [esp + local_4]
JZ     label_2

I'm also a bit confused about Ghidra's auto-analysis, which I've attached to the end of the respective lines. The decompilation uses the name in_stack_00000004 for the TESTed register.

Why do we push a 1 on the stack and what is the test doing?
My best guess is that this is a way to know if the constructor is called directly or by a child class constructor, since I've seen some PUSH 0x00s before constructor calls inside other constructors. If this is the case, why is this done?

This is from a 32 bit windows DLL.

1
  • Do you have RTTI? Does this class inherit another one?
    – Igor Skochinsky
    Jan 8 at 16:25
1

At a guess, the class participates in a virtual inheritance tree. When constructing a class with virtual bases, the constructor needs to know whether its virtual bases have been already constructed or not. The extra argument is used for that. If you compile a sample program with virtual inheritance and look at its assembly output, you'll see that it's called 'initVBases' (i.e. "initialize virtual bases").

_this$ = -4                                   ; size = 4
_$initVBases$ = 8                                 ; size = 4
button::button(void) PROC                              ; button::button, COMDAT
        push    ebp
        mov     ebp, esp
        push    ecx
        mov     DWORD PTR _this$[ebp], ecx
        cmp     DWORD PTR _$initVBases$[ebp], 0
        je      SHORT $LN2@button
        mov     eax, DWORD PTR _this$[ebp]
        mov     DWORD PTR [eax], OFFSET const button::`vbtable'
        mov     ecx, DWORD PTR _this$[ebp]
        add     ecx, 8
        call    control::control(void)
$LN2@button:
        mov     ecx, DWORD PTR _this$[ebp]
        mov     edx, DWORD PTR [ecx]
        mov     eax, DWORD PTR [edx+4]
        mov     ecx, DWORD PTR _this$[ebp]
        mov     DWORD PTR [ecx+eax], OFFSET const button::`vftable'
        mov     eax, DWORD PTR _this$[ebp]
        mov     esp, ebp
        pop     ebp
        ret     4
button::button(void) ENDP                              ; button::button

In case the binary has RTTI (Run-time Type Information), you should be able to confirm it by inspecting the RTTI structures.

1
  • This confirms what I've been suspecting, thanks! I should have made it more clear that yes, this class is part of an inheritance tree. IIRC the binary has RTTI, I should start looking at that as well. Jan 8 at 22:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.