设为首页 加入收藏

TOP

逆向角度看C++的析构函数(二)
2013-04-10 11:53:50 来源: 作者: 【 】 浏览:1093
Tags:逆向 角度 函数

 

  0040115D   push        0C8h; 将 200 压入堆栈中

  00401162   push        64h; 将 100 压入堆栈中

  00401164   lea         ecx,[ebp-14h]; EBP-14h 是 A 的内存地址,占 8 个字节,将该地址保存到 ECX 寄存器中

  00401167   call        @ILT+0(CExample::CExample) (00401005); 调用构造函数 CExample(int, int)

  0040116C   mov         dword ptr [ebp-4],0

  32:     CExample B = A;

  00401173   lea         eax,[ebp-14h]; 将 A 的内存地址保存到 EAX 寄存器中

  00401176   push        eax; 将 EAX 压入堆栈中

  00401177   lea         ecx,[ebp-1Ch]; EBP-1Ch 是 B 的内存地址,占 8 个字节,将该地址保存到 ECX 寄存器中

  0040117A   call        @ILT+20(CExample::CExample) (00401019); 调用拷贝构造函数,将A中的值复制到 B 的内存空间中,

  ; 细心观察一下栈地址就能明白

  0040117F   mov         byte ptr [ebp-4],1

  33:     B.Show();

  00401183   lea         ecx,[ebp-1Ch]

  00401186   call        @ILT+25(CExample::Show) (0040101e)

  34:     fun(A);

  0040118B   sub         esp,8; ESP = 1244884, ESP - 8 = 1244876;ESP-8 是开辟的一块内存,

  ; 在调用fun之前,先调用拷贝构造函数对 A 进行拷贝,拷贝的内容就

  ; 存放在这块内存空间中(一个CExample对象,记为Temp)

  0040118E   mov         ecx,esp; ECX 寄存器保存 Temp 对象的内存地址

  00401190   mov         dword ptr [ebp-20h],esp; EBP-20h 这块空间保存 Temp 对象的内存地址

  00401193   lea         edx,[ebp-14h]; EDX 寄存器保存 A 对象的内存地址

  00401196   push        edx; ESP = 1244872,将 A 的内存地址压入栈

  00401197   call        @ILT+20(CExample::CExample) (00401019); ESP = 1244868,函数返回地址压入栈,调用拷贝构造函数

  0040119C   mov         dword ptr [ebp-28h],eax; ESP = 1244876, EBP - 28h = 1244876,保存 Temp 的内存地址

  0040119F   call        @ILT+15(fun) (00401014); ESP = 1244872,函数返回地址压入栈,调用fun函数

  004011A4   add         esp,8; __cdecl 规则,恢复堆栈段,EBP = 1245000

  35:     return 0;

  004011A7   mov         dword ptr [ebp-24h],0

  004011AE   mov         byte ptr [ebp-4],0

  004011B2   lea         ecx,[ebp-1Ch]; EBP - 1Ch 是 B 的内存地址,保存到 ECX 中

  004011B5   call        @ILT+5(CExample::~CExample) (0040100a); 调用析构函数,销毁对象 B

  004011BA   mov         dword ptr [ebp-4],0FFFFFFFFh

  004011C1   lea         ecx,[ebp-14h]; EBP - 14h 是 A 的内存地址,保存到 ECX 中

  004011C4   call        @ILT+5(CExample::~CExample) (0040100a); 调用析构函数,销毁对象 A

  004011C9   mov         eax,dword ptr [ebp-24h]

  36:   }

  拷贝构造函数 CExample(const CExample& C):

  [plain] view plaincopyprint

  01.11:     CExample(const CExample& C) {

  02.00401270   push        ebp

  03.00401271   mov         ebp,esp

  04.00401273   sub         esp,44h

  05.00401276   push        ebx

  06.00401277   push        esi

  07.00401278   push        edi

  08.00401279   push        ecx

  09.0040127A   lea         edi,[ebp-44h]

  10.0040127D   mov         ecx,11h

  11.00401282   mov         eax,0CCCCCCCCh

  12.00401287   rep stos    dword ptr [edi]          ; 以上为建立堆栈代码,EBP = 1244864

  13.00401289   pop         ecx              ; 恢复 ECX 寄存器的内容,即为 Temp 的内存地址

  14.0040128A   mov         dword ptr [ebp-4],ecx        ; EBP - 4 = 1244860,这块栈内存保存 Temp 的内存地址

  15.12:       x = C.x;

  16.0040128D   mov         eax,dword ptr [ebp-4]        ; EBP - 4 = 1244860,EAX 获得 Temp 的内存地址(EAX 指向 Temp)

  17.00401290   mov         ecx,dword ptr [ebp+8]        ; EBP + 8 = 1244872,ECX 获得 A 的内存地址(ECX 指向 A)

  18.00401293   mov         edx,dword ptr [ecx]      ; EDX = 100(A 的首地址是 100,100 后于 200 进栈)

  19.00401295   mov         dword ptr [eax],edx      ; Temp.x = 100

  20.13:       y = C.y;

  21.00401297   mov         eax,dword ptr [ebp-4]

  22.0040129A   mov         ecx,dword ptr [ebp+8]

  23.0040129D   mov         edx,dword ptr [ecx+4]        ; EDX = 200

  24.004012A0   mov         dword ptr [eax+4],edx        ; 同理,Temp.y = 200

  25.14:     }

  26.004012A3   mov         eax,dword ptr [ebp-4]        ; EAX 寄存器保存 Temp 的内存空间

  27.004012A6   pop         edi

  28.004012A7   pop         esi

  29.004012A8   pop         ebx

  30.004012A9   mov         esp,ebp

  31.004012AB   pop         ebp              ; 恢复EBP,EBP = 1245000

  32.004012AC   ret         4                ; 恢复这一函数的堆栈段

  11:     CExample(const CExample& C) {

  00401270   push        ebp

  00401271   mov         ebp,esp

  00401273   sub         esp,44h

  00401276   push        ebx

  00401277   push        esi

  00401278   push        edi

  00401279   push        ecx

  0040127A   lea         edi,[ebp-44h]

  0040127D   mov         ecx,11h

  00401282   mov         eax,0CCCCCCCCh

  00401287   rep stos    dword ptr [edi]; 以上为建立堆栈代码,EBP = 1244864

  00401289   pop         ecx; 恢复 ECX 寄存器的内容,即为 Temp 的内存地址

  0040128A   mov         dword ptr [ebp-4],ecx; EBP - 4 = 1244860,这块栈内存保存 Temp 的内存地址

  12:       x = C.x;

  0040128D   mov         eax,dword ptr [ebp-4]; EBP - 4 = 1244860,EAX 获得 Temp 的内存地址(EAX 指向 Temp)

  00401290   mov         ecx,dword ptr [ebp+8]; EBP + 8 = 1244872,ECX 获得 A 的内存地址(ECX 指向 A)

  00401293   mov         edx,dword ptr [ecx]; EDX = 100(A 的首地址是 100,100 后于 200 进栈)

  00401295   mov         dword ptr [eax],edx; Temp.x = 100

  13:       y = C.y;

  00401297   mov         eax,dword ptr [ebp-4]

  0040129A   mov         ecx,dword ptr [ebp+8]

  0040129D   mov         edx,dword ptr [ecx+4]; EDX = 200

  004012A0   mov         dword ptr [eax+4],edx; 同理,Temp.y = 200

  14:     }

  004012A3   mov         eax,dword ptr [ebp-4]; EAX 寄存器保存 Temp 的内存空间

  004012A6   pop         edi

  004012A7   pop         esi

  004012A8   pop         ebx

  004012A9   mov         esp,ebp

  004012AB   pop         ebp; 恢复EBP,EBP = 1245000

  004012AC   ret         4; 恢复这一函数的堆栈段

  fun 函数:

  [plain] view plaincopyprint

  01.25:   void fun(CExample E) {

  02.00401050   push        ebp

  03.00401051   mov         ebp,esp

  04.00401053   push        0FFh

  05.00401055   push        offset __ehhandler$ fun@@YAXVCExample@@@Z (004133f9)

  06.0040105A   mov         eax,fs:[00000000]

  07.00401060   push        eax

  08.00401061   mov         dword ptr fs:[0],esp

  09.00401068   sub         esp,40h

  10.0040106B   push        ebx

  11.0040106C   push        esi

  12.0040106D   push        edi

  13.0040106E   lea         edi,[ebp-4Ch]

  14.00401071   mov         ecx,10h

  15.00401076   mov         eax,0CCCCCCCCh

  16.0040107B   rep stos    dword ptr [edi]

  17.0040107D   mov         dword ptr [ebp-4],0              ; EBP = 1244868,以上为建立堆栈代码

  18.26:     printf("In F(CExample)\n");

  19.00401084   push        offset string "In F(CExample)\n" (0042501c)

  20.00401089   call        printf (00401320)

  21.0040108E   add         esp,4

  22.27:     return ;

  23.00401091   mov         dword ptr [ebp-4],0FFFFFFFFh

  24.00401098   lea         ecx,[ebp+8]                  ; EBP+8 = 1244876,是 Temp 的内存地址

  25.                                    ; ECX 寄存器保存

  26.0040109B   call        @ILT+5(CExample::~CExample) (0040100a)       ; 调用析构函数,销毁 Temp 对象(生命期结束)

  27.28:   }

  28.004010A0   mov         ecx,dword ptr [ebp-0Ch]

  29.004010A3   mov         dword ptr fs:[0],ecx

  30.004010AA   pop         edi

  31.004010AB   pop         esi

  32.004010AC   pop         ebx

  33.004010AD   add         esp,4Ch

  34.004010B0   cmp         ebp,esp

  35.004010B2   call        __chkesp (00401780)

  36.004010B7   mov         esp,ebp

  37.004010B9   pop         ebp                      ; 恢复EBP,EBP = 1245000

  38.004010BA   ret

  25:   void fun(CExample E) {

        

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++类机制的实现细节 下一篇C++的内联函数应放在哪

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: