反汇编-C/C++中类的反汇编-2-构造函数和析构函数
构造函数
正向代码
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
printf("Base::Base()\n");
}
};
class Child : public Base
{
public:
Child()
{
printf("Child::Child()\n");
}
};
int main()
{
Child Childtest1;
return 0;
}
逆向代码
int main()
{
00AC1A10 push ebp
00AC1A11 mov ebp,esp
00AC1A13 sub esp,0D0h
00AC1A19 push ebx
00AC1A1A push esi
00AC1A1B push edi
00AC1A1C lea edi,[ebp-0D0h]
00AC1A22 mov ecx,34h
00AC1A27 mov eax,0CCCCCCCCh
00AC1A2C rep stos dword ptr es:[edi]
00AC1A2E mov eax,dword ptr [__security_cookie (0ACA004h)]
00AC1A33 xor eax,ebp
00AC1A35 mov dword ptr [ebp-4],eax
00AC1A38 mov ecx,offset _42C85800_main@cpp (0ACC029h)
00AC1A3D call @__CheckForDebuggerJustMyCode@4 (0AC1325h)
Child Childtest1;
00AC1A42 lea ecx,[Childtest1]
00AC1A45 call Child::Child (0AC1258h)
return 0;
00AC1A4A xor eax,eax
}
class Child : public Base
{
public:
Child()
00AC1800 push ebp
00AC1801 mov ebp,esp
00AC1803 sub esp,0CCh
00AC1809 push ebx
00AC180A push esi
00AC180B push edi
00AC180C push ecx
00AC180D lea edi,[ebp-0CCh]
00AC1813 mov ecx,33h
00AC1818 mov eax,0CCCCCCCCh
00AC181D rep stos dword ptr es:[edi]
00AC181F pop ecx
00AC1820 mov dword ptr [this],ecx
00AC1823 mov ecx,offset _42C85800_main@cpp (0ACC029h)
00AC1828 call @__CheckForDebuggerJustMyCode@4 (0AC1325h)
00AC182D mov ecx,dword ptr [this]
00AC1830 call Base::Base (0AC1253h)
{
printf("Child::Child()\n");
00AC1835 push offset string "Child::Child()\n" (0AC7B40h)
00AC183A call _printf (0AC10CDh)
00AC183F add esp,4
}
00AC1842 mov eax,dword ptr [this]
00AC1845 pop edi
00AC1846 pop esi
00AC1847 pop ebx
00AC1848 add esp,0CCh
00AC184E cmp ebp,esp
00AC1850 call __RTC_CheckEsp (0AC1244h)
00AC1855 mov esp,ebp
00AC1857 pop ebp
00AC1858 ret
结论:
通过代码可以看到,最先其实先是调用调用类的构造函数,在该构造函数中先执行上一个父类的构造函数,然后再继续构造该类,当编译器认为构造函数不必要的时候,不会创建
析构函数
正向代码
#include<iostream>
using namespace std;
class Base
{
public:
~Base()
{
printf("Delete Base::~Base()\n");
}
};
class Child : public Base
{
public:
~Child()
{
printf("Delete Child::~Child()\n");
}
};
int main()
{
Child Childtest1;
return 0;
}
逆向代码
int main()
{
00631A10 push ebp
00631A11 mov ebp,esp
00631A13 sub esp,0D8h
00631A19 push ebx
00631A1A push esi
00631A1B push edi
00631A1C lea edi,[ebp-0D8h]
00631A22 mov ecx,36h
00631A27 mov eax,0CCCCCCCCh
00631A2C rep stos dword ptr es:[edi]
00631A2E mov ecx,offset _42CAFE56_源@cpp (063C029h)
00631A33 call @__CheckForDebuggerJustMyCode@4 (0631325h)
Child Childtest1;
return 0;
00631A38 mov dword ptr [ebp-0D4h],0
00631A42 lea ecx,[Childtest1]
00631A45 call Child::~Child (06312A3h)
00631A4A mov eax,dword ptr [ebp-0D4h]
}
class Child : public Base
{
public:
~Child()
{
00631800 push ebp
00631801 mov ebp,esp
00631803 sub esp,0CCh
00631809 push ebx
0063180A push esi
0063180B push edi
0063180C push ecx
0063180D lea edi,[ebp-0CCh]
00631813 mov ecx,33h
00631818 mov eax,0CCCCCCCCh
0063181D rep stos dword ptr es:[edi]
0063181F pop ecx
00631820 mov dword ptr [this],ecx
00631823 mov ecx,offset _42CAFE56_源@cpp (063C029h)
00631828 call @__CheckForDebuggerJustMyCode@4 (0631325h)
printf("Delete Child::~Child()\n");
0063182D push offset string "Delete Child::~Child()\n" (0637B4Ch)
00631832 call _printf (06310CDh)
00631837 add esp,4
}
0063183A mov ecx,dword ptr [this]
0063183D call Base::~Base (0631168h)
00631842 pop edi
00631843 pop esi
00631844 pop ebx
00631845 add esp,0CCh
0063184B cmp ebp,esp
0063184D call __RTC_CheckEsp (0631249h)
00631852 mov esp,ebp
00631854 pop ebp
00631855 ret
结论