c++ 反汇编 结构体和类

在C++中,结构体和类都具有构造函数、析构函数和成员函数,两者只有一个区别:结构体的访问控制默认为public,而类的默认访问控制是private。

对于C++中的结构体而言,public、private、protected的访问控制都是在编译期进行检查,当越权访问时,编译过程中会检查出此类错误并给予提示。

编译成功后,程序在执行的过程中不会在访问控制方面做任何检查和限制。因此,在反汇编中,C++中的结构体与类没有分别,两者的原理相同,只是类型名称不同,

  • 静态数据成员和普通数据成员

// 含有静态数据成员的类

class CStatic

{

public:

void ShowNumber()

{

printf("m_nInt = %d , m_snInt = %d", m_nInt, m_snInt);

}

static int m_snInt;

int m_nInt;

};

int CStatic::m_snInt = 5;

208:     CStatic Static;
   209:      int nSize = sizeof(Static);
01083646 C7 45 B4 04 00 00 00 mov         dword ptr [nSize],4  
   210:      printf("CStatic : %drn", nSize);
0108364D 8B 45 B4             mov         eax,dword ptr [nSize]  
01083650 50                   push        eax  
01083651 68 78 3E 11 01       push        offset string "CStatic : %drn" (01113E78h)  
01083656 E8 6A DD FE FF       call        _printf (010713C5h)  
0108365B 83 C4 08             add         esp,8  
   211:  
   212:      printf("0x%08xrn", &Static.m_snInt);
0108365E 68 00 80 13 01       push        offset CStatic::m_snInt (01138000h)  //静态成员变量,与全局变量相似
01083663 68 B4 3E 11 01       push        offset string "0x%08xrn" (01113EB4h)  
01083668 E8 58 DD FE FF       call        _printf (010713C5h)  
0108366D 83 C4 08             add         esp,8  
   213:      printf("0x%08xrn", &Static.m_nInt);
01083670 8D 45 C0             lea         eax,[Static]  //普通成员变量,
01083673 50                   push        eax  
01083674 68 B4 3E 11 01       push        offset string "0x%08xrn" (01113EB4h)  
01083679 E8 47 DD FE FF       call        _printf (010713C5h)  
0108367E 83 C4 08             add         esp,8  
   214: 
   215:      Static.m_nInt = 1;
01083681 C7 45 C0 01 00 00 00 mov         dword ptr [Static],1  //普通成员变量赋值
   216:      Static.m_snInt = 2;
01083688 C7 05 00 80 13 01 02 00 00 00 mov         dword ptr [CStatic::m_snInt (01138000h)],2  //静态成员函数赋值
   217:     Static.ShowNumber();
01083692 8D 4D C0             lea         ecx,[Static]  
01083695 E8 30 F6 FE FF       call        CStatic::ShowNumber (01072CCAh)

  • 对象作为函数参数

class CFunTest

{

public:

void ShowNumber()

{

printf("%d %d %srn", m_nOne, m_nTwo, m_szName);

}

int m_nOne;

int m_nTwo;

char m_szName[32];

};

void ShowFunTest(CFunTest FunTest)

{

//FunTest.ShowNumber();

printf("%d %d %srn",

FunTest .m_nOne, FunTest.m_nTwo, FunTest .m_szName);

}

219:      //对象作为函数参数
   220:      CFunTest FunTest;
   221:      FunTest.m_nOne = 1;
0108369A C7 45 84 01 00 00 00 mov         dword ptr [FunTest],1  
   222:      FunTest.m_nTwo = 2;
010836A1 C7 45 88 02 00 00 00 mov         dword ptr [ebp-78h],2  
   223:      strcpy(FunTest.m_szName, "Name");
010836A8 68 A0 3E 11 01       push        offset string "Name" (01113EA0h)  
010836AD 8D 45 8C             lea         eax,[ebp-74h]  
010836B0 50                   push        eax  
010836B1 E8 FB FA FE FF       call        _strcpy (010731B1h)  
010836B6 83 C4 08             add         esp,8  
   224:     ShowFunTest(FunTest);
010836B9 83 EC 28             sub         esp,28h  //CFunTest类大小为40字节,开辟栈空间,存储参数对象(相当于形参)
010836BC B9 0A 00 00 00       mov         ecx,0Ah  
010836C1 8D 75 84             lea         esi,[FunTest]  
010836C4 8B FC                mov         edi,esp  
010836C6 F3 A5                rep movs    dword ptr es:[edi],dword ptr [esi]  //浅拷贝,将参数对象拷贝到局部栈空间中;(如果有拷贝构造的话,此处调用)
010836C8 E8 4B 02 FF FF       call        ShowFunTest (01073918h)  
010836CD 83 C4 28             add         esp,28h

对象中存在资源释放时,做为函数参数

// 带有资源申请与释放的类

class CMyString

{

public:

CMyString(){

m_pString = new char[10];

if (m_pString == NULL){

return;

}

strcpy(m_pString, "Hello");

}

~CMyString(){

if (m_pString != NULL){

delete m_pString;

m_pString = NULL;

}

}

char * GetString(){

return m_pString;

}

void SetString(char * pString)

{

int nLen = strlen(pString);

if (m_pString != NULL)

{

delete [] m_pString;

m_pString = NULL;

}

m_pString = new char[nLen + sizeof(char)];

strcpy(m_pString, pString);

}

private:

char * m_pString;

};

227:      //对象中存在资源释放时,做为函数参数
   228:      CMyString MyString;
010836D0 8D 8D 78 FF FF FF    lea         ecx,[MyString]  
010836D6 E8 28 E5 FE FF       call        CMyString::CMyString (01071C03h)  
010836DB C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  //当前作用域对象数量
   229:      ShowMyString(MyString);
010836E2 8B 85 78 FF FF FF    mov         eax,dword ptr [MyString] //类CMyString大小为4字节,只有一项数据成员m_pString 
010836E8 50                   push        eax  //相当于对象参数浅拷贝到局部空间中
010836E9 E8 5C 07 FF FF       call        ShowMyString (01073E4Ah)  
010836EE 83 C4 04             add         esp,4  
   230:     ShowMyString(MyString);
010836F1 8B 85 78 FF FF FF    mov         eax,dword ptr [MyString]  
010836F7 50                   push        eax  
010836F8 E8 4D 07 FF FF       call        ShowMyString (01073E4Ah)  //再次调用,函数内调用了析构函数,其中使用delete将资源释放,程序发生异常
010836FD 83 C4 04             add         esp,4

c++ 反汇编 结构体和类

…………main函数退出时

0108379B C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  //对象计数
010837A2 8D 8D 78 FF FF FF    lea         ecx,[MyString]  
010837A8 E8 5B F3 FE FF       call        CMyString::~CMyString (01072B08h)  //析构
010837AD 33 C0                xor         eax,eax  
010837AF 52                   push        edx  
010837B0 8B CD                mov         ecx,ebp  
010837B2 50                   push        eax  
010837B3 8D 15 EC 37 08 01    lea         edx,ds:[10837ECh]  
010837B9 E8 86 F8 FE FF       call        @_RTC_CheckStackVars@8 (01073044h)  
010837BE 58                   pop         eax  
010837BF 5A                   pop         edx  
010837C0 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
010837C3 64 89 0D 00 00 00 00 mov         dword ptr fs:[0],ecx  
010837CA 59                   pop         ecx  
010837CB 5F                   pop         edi  
010837CC 5E                   pop         esi  
010837CD 5B                   pop         ebx  
010837CE 8B 4D F0             mov         ecx,dword ptr [ebp-10h]  
010837D1 33 CD                xor         ecx,ebp  
010837D3 E8 85 F3 FE FF       call        @__security_check_cookie@4 (01072B5Dh)  
010837D8 81 C4 10 02 00 00    add         esp,210h  
010837DE 3B EC                cmp         ebp,esp  
010837E0 E8 F7 F6 FE FF       call        __RTC_CheckEsp (01072EDCh)  
010837E5 8B E5                mov         esp,ebp  
010837E7 5D                   pop         ebp  
010837E8 C3                   ret
void ShowMyString(CMyString MyStringCpy)
151: void ShowMyString(CMyString MyStringCpy)
   152: {
010773E0 55                   push        ebp  
010773E1 8B EC                mov         ebp,esp  
010773E3 6A FF                push        0FFFFFFFFh  
010773E5 68 08 15 11 01       push        1111508h  
010773EA 64 A1 00 00 00 00    mov         eax,dword ptr fs:[00000000h]  
010773F0 50                   push        eax  
010773F1 81 EC C0 00 00 00    sub         esp,0C0h  
010773F7 53                   push        ebx  
010773F8 56                   push        esi  
010773F9 57                   push        edi  
010773FA 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
01077400 B9 30 00 00 00       mov         ecx,30h  
01077405 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0107740A F3 AB                rep stos    dword ptr es:[edi]  
0107740C A1 08 80 13 01       mov         eax,dword ptr [__security_cookie (01138008h)]  
01077411 33 C5                xor         eax,ebp  
01077413 50                   push        eax  
01077414 8D 45 F4             lea         eax,[ebp-0Ch]  
01077417 64 A3 00 00 00 00    mov         dword ptr fs:[00000000h],eax  
0107741D C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  //当前域对象计数
   153:     printf(MyStringCpy.GetString());
01077424 8D 4D 08             lea         ecx,[MyStringCpy]  //取对象参数的地址,   [ecx](ecx所指内存中数据)是对象参数的成员数据m_pString,由于只是简单的复制,所以与原对象中的值相同。
01077427 E8 06 A1 FF FF       call        CMyString::GetString (01071532h)  
   153:     printf(MyStringCpy.GetString());
0107742C 50                   push        eax  
0107742D E8 93 9F FF FF       call        _printf (010713C5h)  
01077432 83 C4 04             add         esp,4  
   154: }
01077435 C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  //对象计数
0107743C 8D 4D 08             lea         ecx,[MyStringCpy]  
0107743F E8 C4 B6 FF FF       call        CMyString::~CMyString (01072B08h)  
01077444 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
01077447 64 89 0D 00 00 00 00 mov         dword ptr fs:[0],ecx  
0107744E 59                   pop         ecx  
0107744F 5F                   pop         edi  
01077450 5E                   pop         esi  
01077451 5B                   pop         ebx  
01077452 81 C4 CC 00 00 00    add         esp,0CCh  
01077458 3B EC                cmp         ebp,esp  
0107745A E8 7D BA FF FF       call        __RTC_CheckEsp (01072EDCh)  
0107745F 8B E5                mov         esp,ebp  
01077461 5D                   pop         ebp  
01077462 C3                   ret

  • 对象作为返回值

class CReturn

{

public:

int m_nNumber;

int m_nArry[10];

};

// 对象作为返回值

CReturn GetCReturn()

{

CReturn Return ;

Return.m_nNumber = 0;

for (int i = 0; i < 10; i++)

{

Return.m_nArry[i] = i+1;

}

return Return;

}

233:      //返回值为对象
   234:      CReturn Return;
   235:      Return = GetCReturn();
012136F1 8D 85 F4 FD FF FF    lea         eax,[ebp-20Ch] //开辟的返回对象空间地址 
012136F7 50                   push        eax  
012136F8 E8 F3 FC FE FF       call        GetCReturn (012033F0h)  
012136FD 83 C4 04             add         esp,4  
01213700 B9 0B 00 00 00       mov         ecx,0Bh  
01213705 8B F0                mov         esi,eax  
01213707 8D BD 28 FE FF FF    lea         edi,[ebp-1D8h]  //临时对象地址
0121370D F3 A5                rep movs    dword ptr es:[edi],dword ptr [esi] //返回对象浅复制到临时对象 
0121370F B9 0B 00 00 00       mov         ecx,0Bh  
01213714 8D B5 28 FE FF FF    lea         esi,[ebp-1D8h]  
0121371A 8D BD 44 FF FF FF    lea         edi,[Return]  
01213720 F3 A5                rep movs    dword ptr es:[edi],dword ptr [esi]  //临时对象浅复制到Return
   236:     printf("%d %d %d", Return.m_nNumber, Return.m_nArry[0], Return.m_nArry[9]);
01213722 B8 04 00 00 00       mov         eax,4  
01213727 6B C8 09             imul        ecx,eax,9  
0121372A 8B 94 0D 48 FF FF FF mov         edx,dword ptr [ebp+ecx-0B8h] //m_nArry[9] 
01213731 52                   push        edx  
01213732 B8 04 00 00 00       mov         eax,4  
01213737 6B C8 00             imul        ecx,eax,0  
0121373A 8B 94 0D 48 FF FF FF mov         edx,dword ptr [ebp+ecx-0B8h] //m_nArry[0] 
01213741 52                   push        edx  
01213742 8B 85 44 FF FF FF    mov         eax,dword ptr [Return]  
01213748 50                   push        eax  
   236:     printf("%d %d %d", Return.m_nNumber, Return.m_nArry[0], Return.m_nArry[9]);
01213749 68 D4 3E 2A 01       push        offset string "%d %d %d" (012A3ED4h)  
0121374E E8 72 DC FE FF       call        _printf (012013C5h)  
01213753 83 C4 10             add         esp,10h
GetCReturn
164: // 对象作为返回值
   165: 
   166: CReturn GetCReturn()
   167: {
012078A0 55                   push        ebp  
012078A1 8B EC                mov         ebp,esp  
012078A3 81 EC 04 01 00 00    sub         esp,104h  
012078A9 53                   push        ebx  
012078AA 56                   push        esi  
012078AB 57                   push        edi  
012078AC 8D BD FC FE FF FF    lea         edi,[ebp-104h]  
012078B2 B9 41 00 00 00       mov         ecx,41h  
012078B7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
012078BC F3 AB                rep stos    dword ptr es:[edi]  
012078BE A1 08 80 2C 01       mov         eax,dword ptr [__security_cookie (012C8008h)]  
012078C3 33 C5                xor         eax,ebp  
012078C5 89 45 FC             mov         dword ptr [ebp-4],eax //当前域对象计数 
   168:     CReturn Return ;
   169:     Return.m_nNumber = 0;
012078C8 C7 45 CC 00 00 00 00 mov         dword ptr [Return],0  
   170:     for (int i = 0; i < 10; i++)
012078CF C7 45 C0 00 00 00 00 mov         dword ptr [ebp-40h],0  
012078D6 EB 09                jmp         GetCReturn+41h (012078E1h)  
012078D8 8B 45 C0             mov         eax,dword ptr [ebp-40h]  
012078DB 83 C0 01             add         eax,1  
012078DE 89 45 C0             mov         dword ptr [ebp-40h],eax  
012078E1 83 7D C0 0A          cmp         dword ptr [ebp-40h],0Ah  
012078E5 7D 0F                jge         GetCReturn+56h (012078F6h)  
   171:     {
   172:         Return.m_nArry[i] = i+1;
012078E7 8B 45 C0             mov         eax,dword ptr [ebp-40h]  
   171:     {
   172:         Return.m_nArry[i] = i+1;
012078EA 83 C0 01             add         eax,1  
012078ED 8B 4D C0             mov         ecx,dword ptr [ebp-40h]  
012078F0 89 44 8D D0          mov         dword ptr [ebp+ecx*4-30h],eax  
   173:     }
012078F4 EB E2                jmp         GetCReturn+38h (012078D8h)  
   174:     return Return;
012078F6 B9 0B 00 00 00       mov         ecx,0Bh  
012078FB 8D 75 CC             lea         esi,[Return]  
012078FE 8B 7D 08             mov         edi,dword ptr [ebp+8]  
01207901 F3 A5                rep movs    dword ptr es:[edi],dword ptr [esi] //将局部对象Return 复制到返回对象中 (如果有拷贝构造函数,此处调用)
01207903 8B 45 08             mov         eax,dword ptr [ebp+8]  
   175: }

原文链接: https://www.cnblogs.com/DirWang/p/12173837.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/191721

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午5:48
下一篇 2023年2月12日 下午5:48

相关推荐