设为首页 加入收藏

TOP

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

  有这么一段C++(www.cppentry.com)代码:

  [cpp] view plaincopyprint

  01.#include <cstdio>

  02.

  03.class CExample {

  04.  int x, y;

  05.

  06.public:

  07.  CExample(int va, int vb) {

  08.    x = va;

  09.    y = vb;

  10.  }

  11.  CExample(const CExample& C) {

  12.    x = C.x;

  13.    y = C.y;

  14.  }

  15.  ~CExample() {

  16.    printf("~CExample()\n");

  17.  }

  18.

  19.  void Show () {

  20.    printf("%d, %d\n", x, y);

  21.    return ;

  22.  }

  23.};

  24.

  25.void fun(CExample E) {

  26.  printf("In F(CExample)\n");

  27.  return ;

  28.}

  29.

  30.int main() {

  31.  CExample A(100, 200);

  32.  CExample B = A;

  33.  B.Show();

  34.  fun(A);

  35.  return 0;

  36.}

  #include <cstdio>

  class CExample {

  int x, y;

  public:

  CExample(int va, int vb) {

  x = va;

  y = vb;

  }

  CExample(const CExample& C) {

  x = C.x;

  y = C.y;

  }

  ~CExample() {

  printf("~CExample()\n");

  }

  void Show () {

  printf("%d, %d\n", x, y);

  return ;

  }

  };

  void fun(CExample E) {

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

  return ;

  }

  int main() {

  CExample A(100, 200);

  CExample B = A;

  B.Show();

  fun(A);

  return 0;

  }

  运行结果:

 

  编译调试的环境是 VC 6.0,注释如下:

  main 函数:

  [plain] view plaincopyprint

  01.30:   int main() {

  02.00401130   push        ebp

  03.00401131   mov         ebp,esp

  04.00401133   push        0FFh

  05.00401135   push        offset __ehhandler$_main (00413422)

  06.0040113A   mov         eax,fs:[00000000]

  07.00401140   push        eax

  08.00401141   mov         dword ptr fs:[0],esp

  09.00401148   sub         esp,5Ch

  10.0040114B   push        ebx

  11.0040114C   push        esi

  12.0040114D   push        edi

  13.0040114E   lea         edi,[ebp-68h]

  14.00401151   mov         ecx,17h

  15.00401156   mov         eax,0CCCCCCCCh

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

  17.31:     CExample A(100, 200);

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

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

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

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

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

  23.32:     CExample B = A;

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

  25.00401176   push        eax                  ; 将 EAX 压入堆栈中

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

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

  28.

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

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

  31.33:     B.Show();

  32.00401183   lea         ecx,[ebp-1Ch]

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

  34.34:     fun(A);

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

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

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

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

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

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

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

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

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

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

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

  46.35:     return 0;

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

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

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

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

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

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

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

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

  55.36:   }

  30:   int main() {

  00401130   push        ebp

  00401131   mov         ebp,esp

  00401133   push        0FFh

  00401135   push        offset __ehhandler$_main (00413422)

  0040113A   mov         eax,fs:[00000000]

  00401140   push        eax

  00401141   mov         dword ptr fs:[0],esp

  00401148   sub         esp,5Ch

  0040114B   push        ebx

  0040114C   push        esi

  0040114D   push        edi

  0040114E   lea         edi,[ebp-68h]

  00401151   mov         ecx,17h

  00401156   mov         eax,0CCCCCCCCh

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

  31:     CExample A(100, 200);

     

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

评论

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