《coredump問題原理探究》Linux x86版6.8節多繼承coredump例子

來源:互聯網
上載者:User

標籤:linux   程式崩潰   調試技術   c++   彙編   

下面看一個coredump的例子:

(gdb) bt#0  0x08048662 in xuzhina_dump_c06_s5_ex_child::inheritFrom(char*, int) ()#1  0x08048609 in main ()

先看一下xuzhina_dump_c06_s5_ex_child::inheritFrom的彙編:

(gdb) disassemble 0x08048662Dump of assembler code for function _ZN28xuzhina_dump_c06_s5_ex_child11inheritFromEPci:   0x08048640 <+0>:     push   %ebp   0x08048641 <+1>:     mov    %esp,%ebp   0x08048643 <+3>:     sub    $0x18,%esp   0x08048646 <+6>:     mov    0x8(%ebp),%eax   0x08048649 <+9>:     mov    (%eax),%eax   0x0804864b <+11>:    mov    (%eax),%eax   0x0804864d <+13>:    mov    0x8(%ebp),%edx   0x08048650 <+16>:    mov    0xc(%ebp),%ecx   0x08048653 <+19>:    mov    %ecx,0x4(%esp)   0x08048657 <+23>:    mov    %edx,(%esp)   0x0804865a <+26>:    call   *%eax   0x0804865c <+28>:    mov    0x8(%ebp),%eax   0x0804865f <+31>:    mov    0xc(%eax),%eax=> 0x08048662 <+34>:    mov    (%eax),%eax   0x08048664 <+36>:    mov    0x8(%ebp),%edx   0x08048667 <+39>:    lea    0xc(%edx),%ecx   0x0804866a <+42>:    mov    0x10(%ebp),%edx   0x0804866d <+45>:    mov    %edx,0x4(%esp)   0x08048671 <+49>:    mov    %ecx,(%esp)   0x08048674 <+52>:    call   *%eax   0x08048676 <+54>:    mov    0x8(%ebp),%eax   0x08048679 <+57>:    movl   $0x1,0x14(%eax)   0x08048680 <+64>:    leave     0x08048681 <+65>:    ret    End of assembler dump.

   0x0804865c <+28>:    mov    0x8(%ebp),%eax   0x0804865f <+31>:    mov    0xc(%eax),%eax=> 0x08048662 <+34>:    mov    (%eax),%eax   0x08048664 <+36>:    mov    0x8(%ebp),%edx   0x08048667 <+39>:    lea    0xc(%edx),%ecx   0x0804866a <+42>:    mov    0x10(%ebp),%edx   0x0804866d <+45>:    mov    %edx,0x4(%esp)   0x08048671 <+49>:    mov    %ecx,(%esp)   0x08048674 <+52>:    call   *%eax

可以知道來看,eax是一個虛函數表指標

 

由崩潰指令來看,eax所指向地址非法,而eax是由this加上0xc位移值得到,this放在ebp+0x8

看一下this所指向的內容

(gdb) x /x $ebp+8 0xbff59da0:     0x08c03008(gdb) x /8x 0x08c030080x8c03008:      0x08048798      0x6c6c6548      0x726f576f      0x6854646c0x8c03018:      0x73497369      0x69766544      0x0000006c      0x00020fe1

由於這個地址0x08c03008下一個單元0x08c0300c及後續幾個單元的每個位元組都少於0x80,有可能是ascii碼.

而且還可以由

(gdb) i r eaxeax            0x6854646c       1750361196

看到eax的值放在0x8c03014這個單元。

看一下0x08c0300c開始的是不是字串:

(gdb) x /s 0x08c0300c0x8c0300c:       "HelloWorldThisIsDevil"(gdb) x /s 0x8c030140x8c03014:       "ldThisIsDevil"

可見,確實是有一個字串在裡面,且this+0xc這個虛函數表指標剛好是字串” ldThisIsDevil”.說明剛好是被前面的成員變數覆蓋了.為什麼被覆蓋了?

在xuzhina_dump_c06_s5_ex!xuzhina_dump_c06_s5_ex_child::inheritFrom這個函數裡,有兩處調用.先看一下前一個調用是什麼,有沒有可能把這個虛函數表指標給覆蓋掉,如果沒有,就看一下main函數有沒有調用這個類的其它成員函數了.

由這一段指令

   0x08048646 <+6>:     mov    0x8(%ebp),%eax   0x08048649 <+9>:     mov    (%eax),%eax   0x0804864b <+11>:    mov    (%eax),%eax   0x0804864d <+13>:    mov    0x8(%ebp),%edx   0x08048650 <+16>:    mov    0xc(%ebp),%ecx   0x08048653 <+19>:    mov    %ecx,0x4(%esp)   0x08048657 <+23>:    mov    %edx,(%esp)   0x0804865a <+26>:    call   *%eax

可以知道,這個函數是從第一個虛函數表取出來的第一個函數.

(gdb) x /x $ebp+8 0xbff59da0:     0x08c03008(gdb) x /4x 0x08c030080x8c03008:      0x08048798      0x6c6c6548      0x726f576f      0x6854646c(gdb) x /4x 0x080487980x8048798 <_ZTV28xuzhina_dump_c06_s5_ex_child+8>:       0x08048614      0x08048640      0xfffffff4      0x08048800

從上面可以看到,是調用了setName這個函數,有一個參數.這個參數的值在xuzhina_dump_c06_s5_ex_child::inheritFrom由ebp+c傳入.

看一下ebp+c的內容:

(gdb) x /x $ebp+0xc0xbff59da4:     0xbff5a672(gdb) x /s 0xbff5a6720xbff5a672:      "HelloWorldThisIsDevil"

由這可以推斷,是由xuzhina_dump_c06_s5_ex_father::setName這個函數導致第二個虛函數表指標被改寫的.

看一下xuzhina_dump_c06_s5_ex_father::setName做了什麼事情:

(gdb) disassemble _ZN29xuzhina_dump_c06_s5_ex_father7setNameEPcDump of assembler code for function _ZN29xuzhina_dump_c06_s5_ex_father7setNameEPc:   0x08048614 <+0>:     push   %ebp   0x08048615 <+1>:     mov    %esp,%ebp   0x08048617 <+3>:     sub    $0x18,%esp   0x0804861a <+6>:     mov    0x8(%ebp),%eax   0x0804861d <+9>:     lea    0x4(%eax),%edx   0x08048620 <+12>:    mov    0xc(%ebp),%eax   0x08048623 <+15>:    mov    %eax,0x4(%esp)   0x08048627 <+19>:    mov    %edx,(%esp)   0x0804862a <+22>:    call   0x8048490 <[email protected]>   0x0804862f <+27>:    leave     0x08048630 <+28>:    ret    End of assembler dump.

通過逆向上面的彙編,可以得到這一個函數是參數1的值一個字元一個字元地複製到這個對象的第一個成員變數(this+4)裡.在這個coredump裡,參數1的值是”HelloWorldThisIsDevil”,長度為21,由第一個參數開始,即(+4).而這個對象的第二個虛函數表指標位於+c的位置,剛好被” ldThisIsDevil”來覆蓋.

原始碼如下:

  1 #include <string.h>  2 class xuzhina_dump_c06_s5_ex_father  3 {  4     private:  5         char m_name[8];  6     public:  7         virtual void setName( char* name )  8         {  9             strcpy( m_name, name ); 10         } 11 }; 12  13 class xuzhina_dump_c06_s5_ex_mother 14 { 15     private: 16         int m_nature; 17     public: 18         virtual void setNature( int nature ) 19         { 20             m_nature = nature; 21         } 22 }; 23  24 class xuzhina_dump_c06_s5_ex_child: public xuzhina_dump_c06_s5_ex_father, 25     public xuzhina_dump_c06_s5_ex_mother 26 { 27     private: 28         int m_sweet; 29     public: 30         virtual void inheritFrom( char* lastName, int nature ) 31         { 32             setName( lastName ); 33             setNature( nature ); 34             m_sweet = 1; 35         } 36 }; 3738 int main( int argc, char* argv[] ) 39 { 40     if ( argc < 2 ) 41     { 42         return -1; 43     } 44  45     xuzhina_dump_c06_s5_ex_child* child = new xuzhina_dump_c06_s5_ex_child; 46     child->inheritFrom( argv[1], 1 ); 47  48     return 0; 49 }


《coredump問題原理探究》Linux x86版6.8節多繼承coredump例子

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.