2011-08-20 53 views
2

最近幾天一直在調試一個非常奇怪的問題。爲在Windows上運行的i386構建的應用程序崩潰,並且調用堆棧的頂部完全損壞,指令指針位於無意義的位置。調用指令中的偏移量損壞

經過一番努力,我重建調用堆棧,並能確定IP如何在胡說的位置結束了。 boost共享指針代碼中的指令嘗試使用不正確的偏移量調用在我的DLL導入地址表中定義的函數。該指令看起來像:

call dword ptr [nonsense offset into import address table] 

因此,執行結束在一個糟糕的位置,不幸的是,可執行。然後繼續執行,吞噬棧頂直到最終崩潰。

通過推出我的電腦上相同的應用程序,並步入了有問題的代碼,我可以找到相同的調用指令,看看通過調用msvc100的new操作符它應該。

而且比較來自客戶端的PC到我的電腦的轉儲,我發現我的電腦是用電話在地址表中的偏移0x0254功能。在客戶端PC上,代碼嘗試調用偏移量爲0x8254的函數。

什麼是更令人困惑的是,這個偏移不從寄存器或其他存儲位置來。偏移是反彙編中的一個常量。因此,拆卸的樣子:

call dword ptr [ 0x50018254 ] 

不喜歡:

call dword ptr [ edx ] 

有誰知道這件事會發生?

+1

您已經發現了ASLR,地址空間佈局隨機化。旨在使惡意軟件難以修補程序的功能。尋找這樣的問題的更典型的原因:堆棧緩衝區溢出破壞了堆棧幀並覆蓋了返回地址。 –

回答

0

這是一個單比特翻轉:

0x0254 = 0b0000001001010100 
0x8254 = 0b1000001001010100 

可能損壞內存,磁盤損壞,γ射線從太陽...?

如果這種特定情況下是可重複的和他們在磁盤上的二進制匹配你的,我會進一步調查。如果它不是特別重現的,我會鼓勵客戶運行一些機器診斷。

+0

我的一位同事正在複製在他的電腦上看起來像是一個相同的故障,然後它就停止了發生。在發生這種情況之前,我們一直在想糟糕的記憶。我不是Windows加載DLL並填​​充調用指令中使用的地址的專家,所以我不確定它是通過什麼方式來破壞的。 – Andrew

0

這似乎是一個肯定的硬件錯誤,主要是內存錯誤。正如@Hostile_Fork指出的,只是有點翻轉。

您的內存是否具有ECC功能?它這樣做,確保啓用。我會通過memtest86的燒機內存測試來看看會發生什麼,我敢打賭你有一個錯誤的內存芯片,看起來不像一個錯誤。