• <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
            • 良師益友,千年水牛,引擎猛男,分析怪獸,墨鏡酷哥,臺球高手....

            搜索

            •  

            最新評論

            婷婷久久综合| 蜜臀av性久久久久蜜臀aⅴ| 久久精品嫩草影院| 99久久婷婷国产一区二区| 久久99精品国产麻豆蜜芽| 久久受www免费人成_看片中文| 亚洲精品午夜国产va久久| 久久99国内精品自在现线| 久久精品国产亚洲Aⅴ蜜臀色欲| 中文成人无码精品久久久不卡| 72种姿势欧美久久久久大黄蕉| 日韩欧美亚洲综合久久影院Ds| 久久人人爽人人爽人人AV东京热| 香蕉久久一区二区不卡无毒影院| 亚洲欧美久久久久9999| 国产精品久久成人影院| 国产亚洲精品久久久久秋霞| 精品国产婷婷久久久| 精品久久久久久久| 囯产极品美女高潮无套久久久| 久久91精品综合国产首页| 久久精品无码专区免费东京热| 四虎国产精品成人免费久久| 亚洲成色999久久网站| 99精品国产在热久久无毒不卡| 国内精品伊人久久久久妇| 欧美午夜A∨大片久久 | 免费无码国产欧美久久18| 99热热久久这里只有精品68| 波多野结衣中文字幕久久| 中文字幕久久久久人妻| 久久久久久久久久久| 婷婷久久五月天| 中文字幕无码av激情不卡久久| 久久一本综合| 婷婷久久精品国产| 久久精品亚洲中文字幕无码麻豆| 久久久久久国产a免费观看黄色大片| 久久久久国产一级毛片高清版| 久久久久亚洲AV成人片| 国产精品久久久久免费a∨|