• 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 : %d ", nSize); 0108364D 8B 45 B4 mov eax,dword ptr [nSize] 01083650 50 push eax 01083651 68 78 3E 11 01 push offset string "CStatic : %d " (01113E78h) 01083656 E8 6A DD FE FF call _printf (010713C5h) 0108365B 83 C4 08 add esp,8 211: 212: printf("0x%08x ", &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%08x " (01113EB4h) 01083668 E8 58 DD FE FF call _printf (010713C5h) 0108366D 83 C4 08 add esp,8 213: printf("0x%08x ", &Static.m_nInt); 01083670 8D 45 C0 lea eax,[Static] //普通成员变量, 01083673 50 push eax 01083674 68 B4 3E 11 01 push offset string "0x%08x " (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 %s ", 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 %s ",
    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

    …………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: }
  • 相关阅读:
    mysql关联查询
    文本框,下拉框,单选框只读状态属性
    sql索引实例
    sql视图实例
    SQL触发器实例
    存储过程实例
    sql 、linq、lambda 查询语句的区别
    LINQ中的一些查询语句格式
    面试宝典
    SQL常用语句
  • 原文地址:https://www.cnblogs.com/DirWang/p/12173837.html
Copyright © 2020-2023  润新知