2011-02-17 36 views
2

我們有一個測試用例,它會崩潰我們的大型基於MFC的應用程序,並出現堆損壞錯誤。解釋App驗證器輸出:堆損壞或將堆棧地址誤解爲堆地址?

我打開頁面堆使用應用程序驗證程序的問題的DLL(翻轉整個過程堆是不可行的其他原因,不幸的是。)驗證人沒有給我們比我們更多的信息已經有了;它在原始崩潰的同一時刻觸發。

現在我有兩個相互競爭的理論。你認爲哪種理論更可能是正確的,你的下一步將會是什麼?

  1. 這確實是堆腐敗。驗證者沒有捕獲原始損壞,因爲它發生在另一個DLL中。我們應該嘗試激活更多DLL的驗證程序,並確定哪些代碼損壞了堆。
  2. 堆很好;問題是我們將堆棧地址視爲堆地址。我們應該進一步研究這個調用堆棧中的代碼,以弄清楚什麼是錯誤的。

因爲參數free()看起來像一個堆棧地址,所以我傾向於#2,但到目前爲止沒有人提出解釋如何實現這一點。

這是調用堆棧的一個片段。 MyString是CString的簡單包裝。 MyAppDll是設置爲使用頁堆的DLL。

msvcr90.dll!free(void * pBlock=0x000000000012d6e8) Line 110 
mfc90u.dll!ATL::CStringT > >::~CStringT > >() Line 1011 + 0x1e bytes 
MyStringDll.dll!MyString::~MyString() Line 59 
MyAppDll.dll!doStuffWithLotsOfStringInlining(MyClass* input=0x000000000012d6d0) Line 863 + 0x26 bytes

這裏是免費的()堆棧幀內部寄存器:

 
RAX = 0000000000000000 RBX = 000000000012D6E8 RCX = 0000000000000000 
RDX = 0000000000000000 RSI = 000000000012D6D0 RDI = 00000000253C1090 
R8 = 0000000000000000 R9 = 0000000000000000 R10 = 0000000000000000 
R11 = 0000000000000000 R12 = 000000000012D7D0 R13 = 000007FFFFC04CE0 
R14 = 0000000025196600 R15 = 0000000000000000 RIP = 00000000725BC7BC 
RSP = 000000000012D570 RBP = 000007FFF3670900 EFL = 00000000 

而這裏的應用程序驗證信息:

 
VERIFIER STOP 0000000000000010: pid 0x1778: Corrupted start stamp for heap block. 

    00000000083B1000 : Heap handle used in the call. 
    000000006DD394E8 : Heap block involved in the operation. 
    54D32858A8747589 : Size of the heap block. 
    000000005E33BA8D : Corrupted stamp value. 

回答

1

我想你的字符串或用戶的是/正在溢出/下溢字符串的緩衝區,可能是字符串旁邊的字段,然後嘗試釋放。

您的RSP是12D570,與您試圖釋放的東西相距94個四邊形(整數),所以在這之間的某個地方,緩衝區出現了一些不好的情況。

驗證您是否正在執行任何不安全的字符串操作,並且您正在正確地閱讀將緩衝區/字符串傳遞到正在使用的DLL的文檔。

如果您想要更準確的答案,您可能需要更多代碼。

+0

謝謝,這是我正在尋找的答案。不幸的是,這裏只涉及太多的代碼來提供完整的圖片,我不認爲簡短的摘錄會有幫助。 – Dewb 2011-02-17 23:34:56