windbg分析堆溢出

  本文實驗的例子來自《windows高級調試》第6.2.2節,參考書中的方法進行。

1.通過windbg分析堆塊

  (1)在命令行運行程序,輸入參數(輸入超過10個字符),在出現如下提示的時候,使用windbg attach到該進程。

  (2)按任意鍵繼續執行,執行完後,程序崩潰到windbg,使用kb命令查看堆棧如下: 

  (3)我們看到報的堆棧信息是在HeapFree函數中,其實我們知道原因是wcscpy函數溢出了,但崩潰點卻不在溢出發生的地方,堆破壞的最大問題在於造成錯誤的代碼無法在發生堆破壞時被發現,我們可以通過查看當前堆的一些情況進行分析。 

  (4)查看默認堆的詳細情況,由於信息比較多,我僅僅把最後一部分打印出來。

  (5) 我們看到最後一個堆塊是有問題的,可以看下該堆的內容,我們從004e5188地址開始打印。

  (6)我們看到了一系列的0x31字符,就是我們參數輸入的“1”,我們可以用du命令再打印下: 

  (7)果然是我們輸入的參數,而且參數越過了堆塊004e51a8,我們把該堆塊的頭打印出來: 

  發現堆塊的頭全都被我們輸入的參數覆蓋了,這就導致了內存訪問異常。 

2.通過windbg+普通頁堆分析

  上面的程序很簡單,很容易通過分析堆塊來找出問題,然而通過分析堆塊來查找堆溢出的問題並非總是可行的,還有一種方式可以讓我們很快找到堆溢出的原因,就是頁堆,我們可以通過Application Verifier工具開啓頁堆。

  通過Add Application菜單,添加我們要分析的應用程序,然後再右邊會有Heaps的選項。 

  右擊Heaps 選擇屬性,在彈出框中,把full去掉(我們先分析普通頁堆,之後再分析完全頁堆)。 

   完成後我們按照原來的方式執行,程序崩潰後,打印堆棧如下。

  上面給了我們堆的內存信息,要轉儲頁堆數據的內容,我們需要將該地址減去32字節然後再轉成_DPH_BLOCK_INFORMATION結構,如下: 

  上述結構體最重要的一項是StackTrace,可以查找堆棧的回溯,如下: 

  通過上述信息,我們很快就能找到有問題堆的分配棧回溯,通過分析代碼很容易發現堆的溢出情況。 

3.通過windbg+完全頁堆分析

  普通頁堆還不是很直觀的發現堆溢出的地方,但是開啓了完全頁堆就不一樣了,完全頁堆開啓後,程序只要發生堆溢出就立馬崩潰,這樣就很好的發現問題所在了,開啓完全頁堆:

  再次運行程序,崩潰後堆棧情況: 

  很快就找到問題所在了,我們可以把wcscpy拷貝的字符打印出來:

  就是我們傳入的參數導致的溢出。 

 

 

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