• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 101,  comments - 57,  trackbacks - 0

            在來看看C++的虛函數和繼承

            1.C++代碼

            #include "iostream"
            using namespace std;

            class C
            {
            public:
                
            int c;
                
            virtual void display(int s);
            }
            ;

            void C::display(int s)
            {
                c 
            = 3;
                cout
            <<"this is in C:"<<s<<" "<<c<<endl;
            }

            class D : public C
            {
            public:
                
            int d;
                
            void display(int s);
            }
            ;

            void D::display(int s)
            {
                d 
            = 4;
                cout
            <<"this is in d:"<<s<<" "<<d<<endl;
            }


            void main()
            {
                C c;
                c.display(
            sizeof(c));
                
                C 
            *= (C *)new D;
                d
            ->display(sizeof(d));
            }

            2.匯編代碼
               1.debug編譯
            .text:00401830 main            proc near               ; CODE XREF: _mainj
            .text:00401830
            .text:00401830 var_54          = dword ptr -54h
            .text:00401830 var_14          = dword ptr -14h
            .text:00401830 var_8           = dword ptr -8
            .text:00401830
            .text:00401830                 push    ebp
            .text:00401831                 mov     ebp, esp
            .text:00401833                 sub     esp, 54h
            .text:00401836                 push    ebx
            .text:00401837                 push    esi
            .text:00401838                 push    edi
            .text:00401839                 lea     edi, [ebp+var_54]
            .text:0040183C                 mov     ecx, 15h
            .text:00401841                 mov     eax, 0CCCCCCCCh
            .text:00401846                 rep stosd
            .text:00401848                 lea     ecx, [ebp+var_8]
            .text:0040184B                 call    j_C__C
            .text:00401850                 push    8
            .text:00401852                 lea     ecx, [ebp+var_8]
            .text:00401855                 call    j_C__display
            .text:0040185A                 lea     ecx, [ebp+var_14]
            .text:0040185D                 call    j_D__D
            .text:00401862                 push    0Ch
            .text:00401864                 lea     ecx, [ebp+var_14]
            .text:00401867                 call    j_D__display
            .text:0040186C                 pop     edi
            .text:0040186D                 pop     esi
            .text:0040186E                 pop     ebx
            .text:0040186F                 add     esp, 54h
            .text:00401872                 cmp     ebp, esp
            .text:00401874                 call    __chkesp
            .text:00401879                 mov     esp, ebp
            .text:0040187B                 pop     ebp
            .text:0040187C                 retn
            .text:0040187C main            endp



                在call真正的函數之前有一個call    j_C__C,看看它的代碼
            .text:00401890 ; Attributes: bp-based frame
            .text:
            00401890
            .text:
            00401890 C__C            proc near               ; CODE XREF: j_C__Cj
            .text:
            00401890
            .text:
            00401890 var_44          = dword ptr -44h
            .text:
            00401890 var_4           = dword ptr -4
            .text:
            00401890
            .text:
            00401890                 push    ebp
            .text:
            00401891                 mov     ebp, esp
            .text:
            00401893                 sub     esp, 44h
            .text:
            00401896                 push    ebx
            .text:
            00401897                 push    esi
            .text:
            00401898                 push    edi
            .text:
            00401899                 push    ecx
            .text:0040189A                 lea     edi, [ebp
            +var_44]
            .text:0040189D                 mov     ecx, 11h
            .text:004018A2                 mov     eax, 0CCCCCCCCh
            .text:004018A7                 rep stosd
            .text:004018A9                 pop     ecx
            .text:004018AA                 mov     [ebp
            +var_4], ecx
            .text:004018AD                 mov     eax, [ebp
            +var_4]
            .text:004018B0                 mov     dword ptr [eax], offset 
            ??_7C@@6B@ ; const C::`vftable'
            .text:004018B6                 mov     eax, [ebp+var_4]
            .text:004018B9                 pop     edi
            .text:004018BA                 pop     esi
            .text:004018BB                 pop     ebx
            .text:004018BC                 mov     esp, ebp
            .text:004018BE                 pop     ebp
            .text:004018BF                 retn
            .text:004018BF C__C            endp
            原來是獲取,虛函數表的(*^__^*)...嘻嘻

               2.release編譯
            .text:00401140 ; int __cdecl main(int argc,const char **argv,const char *envp)
            .text:00401140 _main           proc near               ; CODE XREF: start+AFp
            .text:00401140
            .text:00401140 var_14          = dword ptr -14h
            .text:00401140 var_C           = dword ptr -0Ch
            .text:00401140 argc            = dword ptr  4
            .text:00401140 argv            = dword ptr  8
            .text:00401140 envp            = dword ptr  0Ch
            .text:00401140
            .text:00401140                 sub     esp, 14h
            .text:00401143                 push    8
            .text:00401145                 lea     ecx, [esp+18h+var_14]
            .text:00401149                 mov     [esp+18h+var_14], offset off_4120EC
            .text:00401151                 call    sub_401000
            .text:00401156                 push    0Ch
            .text:00401158                 lea     ecx, [esp+18h+var_C]
            .text:0040115C                 mov     [esp+18h+var_C], offset off_4120E8
            .text:00401164                 call    sub_4010A0
            .text:00401169                 add     esp, 14h
            .text:0040116C                 retn
            .text:0040116C _main           endp

             release就直接把虛函數表給解釋出來了

            3.輸出結果

            this is in C:8 3
            this is in d:12 4

            4.結論
            1.虛基類除了變量還有4字節的vftable(在變量前面)
            2.debug要用函數解釋vftable,release直接給出
            3.經常說的所謂虛函數被覆蓋過程,可以看看class D解釋vftable代碼
            .text:004018E9                 pop     ecx
            .text:004018EA                 mov     [ebp
            +var_4], ecx
            .text:004018ED                 mov     ecx, [ebp
            +var_4]
            .text:004018F0                 call    j_C__C                                                          //初始化父類
            .text:004018F5                 mov     eax, [ebp
            +var_4]
            .text:004018F8                 mov     dword ptr [eax], offset 
            ??_7D@@6B@ ; const D::`vftable'
            .text:004018FE                 mov     eax, [ebp+var_4]                                      // 將寫自己的表
               從而可見,VC的編譯器在編譯的時候,沒有覆蓋的概念,只是編譯的時候根據有需要的將虛函數表生成不同的幾個而已。是哪個就用哪個表。

            note:
              雖然new出來的是一個子類對象,但是由于它付給了一個父類的類型,所以只能引用父類的成員。這就出現了一個奇怪的現象,在繼承的時候已經將父類的成員繼承到了子類的對象里面,而用vc查看的時候會發現這一點,奇怪的是由于上面的原因他將把子類的成員忽略掉。即在本來應該是子類成員的地方,還是父類成員的名稱。雖然查看內存,已經發現子類的成員確實存在。而我們可以把這個看作是類型被沒有warning的縮小了!
            posted on 2008-03-02 22:12 margin 閱讀(793) 評論(3)  編輯 收藏 引用 所屬分類: C/C++逆向工程

            FeedBack:
            # re: C++逆向程序(2)
            2008-07-25 04:35 | kxj
            我在windows and Linux 得到和你不同的output

            this is in C:8 3
            this is in d:4 4  回復  更多評論
              
            # compile option different
            2008-07-25 05:03 | kxj
            d->display(sizeof(d)); //print the pointer size, not object

            d->display(sizeof(*d)); //size still is 8  回復  更多評論
              
            # re: C++逆向程序(2)
            2008-07-25 22:06 | Lenus
            請問你用的是什么編譯器,可能我沒有說清楚,應該用VC6進行編譯才得到這些結果  回復  更多評論
              
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿

            隨筆檔案

            文章分類

            文章檔案

            收藏夾

            常去的壇子

            • CVC電腦病毒論壇
            • 很多人說我是AV,我告訴他們:別瞧不起人,我們也能創造價值
            • 安全焦點
            • 黑客聚集的地方,一般是好酒最多的地方...
            • 看雪論壇
            • 國內最強的加密解密論壇,成醉其中經常夜不歸宿
            • 驅動開發論壇
            • 厭倦了啤的朋友們,來我們來整點白的...痛痛快快的BSOD也好過隔鞋瘙癢!

            我的朋友

            • Sen的blog
            • IDE方面資深的受害者...經常為一個變量的定義找不著北的痛苦程序員(深表同情)
            • 老羅的blog
            • 良師益友,千年水牛,引擎猛男,分析怪獸,墨鏡酷哥,臺球高手....

            搜索

            •  

            最新評論

            男女久久久国产一区二区三区| 香蕉久久AⅤ一区二区三区| 国产69精品久久久久9999APGF | 77777亚洲午夜久久多喷| 久久天堂电影网| 青青青青久久精品国产h久久精品五福影院1421 | 久久亚洲高清综合| 伊人久久大香线蕉av不变影院| 国产精品对白刺激久久久| 国产99久久九九精品无码| 伊人久久大香线蕉AV色婷婷色| 久久综合久久综合九色| 久久精品国产99久久久古代| 狠狠88综合久久久久综合网| 午夜福利91久久福利| 97精品国产91久久久久久| 一本久久免费视频| 国产香蕉97碰碰久久人人| 中文无码久久精品| 亚洲精品tv久久久久| 久久免费线看线看| 久久久久亚洲av无码专区喷水| 久久一区二区免费播放| 国产午夜福利精品久久2021| 久久久久久久综合狠狠综合| 久久久久亚洲AV成人网人人网站 | 久久久久久久91精品免费观看 | 久久国产色AV免费看| 久久午夜无码鲁丝片秋霞| 日韩精品无码久久一区二区三| 99久久无码一区人妻| 国产一久久香蕉国产线看观看| 久久精品国产99久久无毒不卡| 99久久无色码中文字幕人妻| 久久久亚洲欧洲日产国码是AV| 色狠狠久久综合网| 亚洲色大成网站WWW久久九九| 狠狠色丁香久久婷婷综合| 囯产精品久久久久久久久蜜桃| 国产aⅴ激情无码久久| 老色鬼久久亚洲AV综合|