青青青国产依人在线观看视频_亚洲欧美一区二区骚虎_亚洲理论在线中文字幕a_无码a级毛片免费不卡

歡迎來到興華永恒!加入收藏設(shè)為首頁
您當(dāng)前所在位置:首頁 > 技術(shù)專欄 > 專業(yè)發(fā)布
技術(shù)專欄

針對CVE-2015-2545漏洞研究分析(中篇)


3.5.6 字典對象處理流程

關(guān)鍵的函數(shù)為forall在處理dict的過程,我們在第三個語句塊首部分下斷點(diǎn)<`EPSIMP32!RegisterPercentCallback+0x4664`>,觀察斷點(diǎn),入棧了3個參數(shù),調(diào)用一函數(shù),那么我們需要思考下這三個參數(shù)是什么,通過查詢<<PLRM2.PDF>>,我們得到關(guān)鍵性的資料,[`圖2`]上面說如果第一個操作是字典類型,那么它會入棧一個`key`和一個`數(shù)據(jù)`,這里類似哈希表的形式,通過一個key可以迅速得到對應(yīng)的數(shù)值;為什么`圖1`我寫`pNext`,通過`圖3`我們可以判斷其內(nèi)容是否為null,則`lea eax, [ebp-14]`eax取出來的是個指針,所以這里這個名字主要是方便識別其為指針?biāo)ā?/p>

1491893143694777.png

圖1

1491893171474704.png

圖2

1491893193459016.png

圖3

3.5.7 對象結(jié)構(gòu)解析

關(guān)于第一個CALL所做的事情,大致可以分為3個方面,給PNEXT附值,給KEY賦值,給VALUE賦值,這里說的簡單,里面的功能CALL需要自己手動調(diào)試下做好記錄更加方便理解是如何賦值的過程,這里直接說下是如何得到的這些數(shù)值,首先看下`ECX`所對應(yīng)的內(nèi)容`圖1`所示,其中`+0X8`偏移的位置是循環(huán)遍歷的次數(shù),相當(dāng)于一個`INDEX`也可以說是個`界限值`,里面的CALL循環(huán)條件的范圍就是 `400`, 其中`+0XC`的位置`8`表示`KEY`的個數(shù),為什么,如`圖2`所示,那么關(guān)于`+0X0`偏移的位置則是個`基址`的意思,所有的結(jié)果都是通過[基址+偏移*X]的形式得到相應(yīng)的數(shù)據(jù),`圖3`表示第一個`KEY1`中的內(nèi)容,同時`2B4`則為下標(biāo),通過基址+下標(biāo)*4即可獲取第一個KEY1對應(yīng)內(nèi)容的地址,這0x28個字節(jié)就是個結(jié)構(gòu)體,大致內(nèi)容如下所示,正好可以跟我們的數(shù)據(jù)一一對應(yīng),不過這里還是需要`多跟幾遍`才會更加明白`結(jié)構(gòu)`的情況,當(dāng)跑完第一個CALL之后的內(nèi)存情況如圖4所示。

2017-03-27_163447.png

圖1

1491893295712524.png

圖2

2017-03-27_164236.png

圖3

     

 struct {    
      dword * pNext; //指向下個結(jié)構(gòu)體
      dword dwIndex; //下標(biāo)
      ps_obj key;   //key
      ps_obj value;  //數(shù)據(jù)
      }kv_pair_element;
     
      struct PostScript object {
      dword type;//類型
      dword attr; //屬性
      dword value1; //數(shù)據(jù)
      dword value2; //數(shù)據(jù)
      }ps_obj;

2017-03-27_165635.png

圖4

00030000[類型] 00000000[屬性] 000001ff[數(shù)據(jù)]  04f32ea4[數(shù)據(jù)]
00000300[類型] 00000000[屬性] 04f69db0[數(shù)據(jù)]  04f32ea4[數(shù)據(jù)]
04f8fd98[pNext]

3.5.8 釋放空間函數(shù)分析

第二call,第三call,為同一call,在對key與value進(jìn)行操作,copy到其他位置,之后的`PROC`則為重點(diǎn)call,此call則執(zhí)行`forall`的所有的操作,我們只需要在copy函數(shù)的位置下斷點(diǎn)即可得到出發(fā)漏洞的位置<copy:`EPSIMP32!RegisterPercentCallback+0x15582`>,然后我們單步跟蹤即可,這里可以先用ida觀察下copy的大致流程,然后通過動態(tài)的方式更好的去跟蹤我們想要的數(shù)據(jù),由于copy的函數(shù)塊比較大,動態(tài)調(diào)試起來也不是特別容易,我這里跟的時候是每個call都跟進(jìn)去了,很費(fèi)時間,但肯定可以找到想要的函數(shù)數(shù)據(jù)的,這里我直接給下偏移<`EPSIMP32!RegisterPercentCallback+0x12e8e`>,如`圖1`所示為釋放過程的函數(shù)<`EPSIMP32+0x1a0e8`>,這個釋放的過程可以仔細(xì)觀察下,還記得開始的時候的this指針?biāo)赶虻膬?nèi)容嗎?[[this]],記得第一個call的時候,我們獲取KEY1-KEY8都是存在以[[this]]為基址,然后加上一個偏移得到這些數(shù)據(jù),第一次的循環(huán)delete也是從[[this]]為基址開始遍歷,判斷是否為null,不是空則delete,那么這正片空間都被delete了,這個的范圍也是我們剛剛進(jìn)入第一個call的時候的一個下標(biāo)`400`,循環(huán)結(jié)束之后,delete this,并且清空`+0x0`, `+0x8`,就是清空key的個數(shù)。

1491893589730477.png

圖1

1491893613379181.png

圖2(釋放:dict1 copy dict2—>釋放dict2過程)

3.5.9 copy字典對象

之后會進(jìn)行拷貝的操作,要把dict1–>copy到dict2中,則會new一段空間,而這段空間剛剛好為之前所釋放的[[this]],這里new的是`0x1000`大小,并且通過`memset`清空剛剛申請的空間中的內(nèi)容`圖1,2`所示,之后會繼續(xù)new0x28空間大小,為什么?因?yàn)閌dect1–>copy–>dect2`中,diect1只有`1個key`,則在0x1000中所填充的數(shù)據(jù)也就是1個4字節(jié)地址,所以需要new 0x28大小來保存數(shù)據(jù)圖3所示,copy完數(shù)據(jù)`圖4`所示。

1491893712750396.png

圖1

1491893741462057.png

圖2(新new空間與釋放的dict2一致)

1491893794695892.png

圖3

2017-03-27_184239.png

圖4(new0x28大小空間:內(nèi)容pNext,index, 類型,屬性,數(shù)據(jù),數(shù)據(jù),類型,屬性,數(shù)據(jù),數(shù)據(jù))

3.5.10 填充構(gòu)造數(shù)據(jù)

之后則為putinterval操作的過程,這個就會填充我們的pNext指針?biāo)赶虻臄?shù)據(jù)空間,斷點(diǎn)位置<`EPSIMP32!RegisterPercentCallback+0x160da`>,然后會進(jìn)行`memcpy`的操作,把我們數(shù)據(jù)正好填充到我們之前的pNext所指向的空間中,這樣會whlile循環(huán)會再次跑一邊,而這次的 key,vale則是我們自己所構(gòu)造的指定數(shù)據(jù),結(jié)構(gòu)如下所示。

1491893888518643.png

圖1

00000000[pNext]    000003ff[index]    00000003[類型]    00000000[屬性]
00000000[key.valu1]    44444444[key.value2]    00000500[類型]    00000000[屬性] 
00000000[value.1]    0462e0b0[value.2]//這里是原來數(shù)據(jù),并非復(fù)制過來的數(shù)據(jù)
在線咨詢 周一至周五
09:00-18:00