string顯示問題

前一段時間遇到了一個非常有意思的問題,在控件的頁面上顯示了非法的字符串

接下來大家就一步步根據上次的定位思路來看下這個問題。

 

首先,找到這塊控件的代碼

class CItem
{
****
    std::string input;

****

}

發現這個控件裏有一個默認構造的string對象,由此可以大膽猜測,有沒有可能是string的靜態變量地址被篡改了。

然後,我們運行core來看下string的字符串地址。

 

(gdb) thread apply all bt
發現線程裏沒有頁面的信息,所有隻能從別的地方入手。由標準庫的string實現我們知道,默認構造生成的字符串地址,均指向同一個全局靜態變量。Cpage頁面繼承自Citem,而Citem中有一個string的成員,所有我們查找包含page頁面的線程。查看Cpage的string成員地址即可找到Citem類的string成員地址

class CPage : public CItem

{

***
    std::string    m_t
itle; 

***

}

上面有一個string成員,分別打印他們的值

並且查看符號表可知,m_title是默認構造生成的string

pm_title
 {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x3ddc9b8 <_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4+24> "*******}}
(gdb) info symbol _ZNSs4_Rep20_S_empty_rep_storageE
std::string::_Rep::_S_empty_rep_storage in section .bss of /usr/lib64/libstdc++.so.6

所以我們知道肯定是string的靜態變量內容被覆蓋了。現在有2個思路,一個是靜態變量地址越界,還有一種是靜態變量的內容被其他默認構造生成的字符串篡改。

 

先看第一種思路

(gdb) x /32xg 0x3ddc9b8 - 8*16 
0x3ddc938:      0x0000000000000000      0x0000000000000000
0x3ddc948       0x00000030144ee1b0      0x00000030142bd4e0
0x3ddc958:     0x00000030142bd500      0x00000030142bd430
0x3ddc968:     0x00000030142bd830      0x00000030142bd210
0x3ddc978:     0x00000030142bd840      0x00000030142bd440
0x3ddc988:      0x0000000000000000      0x0000000000000000
0x3ddc998:      0x0000000000000000      0x0000000000000000
0x3ddc9a8 :   0x0000000000000000      0x0000000000000000
0x3ddc9b8 :  ********            *********
0x3ddc9c8 :    0x00000030142c8352      0x0000000000000000
0x3ddc9d8:      0x0000000000000000      0x0000000000000058
0x3ddc9e8 :       0x0000000000000000      0x00000030144ec5e0
0x3ddc9f8 :      0x0000003014299d50      0x000000301429a9d0
0x3ddca08 :      0xffffffffffffffa8      0xffffffffffffffa8
0x3ddca18:      0x00000030144ec5e0      0x0000003014299d40
0x3ddca28:     0x000000301429a9c0      0x0000000000000000
(gdb) 

從內存地址看,之前的內存地址都是0,不太像是被內存越界改掉的。

 

再來看第二種思路,用上面非法的字符串搜索代碼中出現的字符串位置,在代碼中檢索出一段代碼,往靜態變量地址寫數據的地方

之後在測試的時候,使用gdb watch這個地址,發現問題就是出在這裏。

 

如果在代碼中沒有檢索到dav關鍵字,可以在服務器上輸入如下命令,看哪些第三方庫使用到。

[root]$ find .|xargs grep -ri "string" -l                    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章