使用PageHeap.EXE或GFlags.EXE檢查內存越界錯誤
Posted on 2009-03-24 12:57 S.l.e!ep.¢% 閱讀(3697) 評論(0) 編輯 收藏 引用 所屬分類: WinDbg|
我推薦使用PageHeap.Exe和Gflags.Exe,主要的原因還是因為當有人問內存越界的錯誤如何查出來的時候,國外的朋友經常會推薦這兩個工具(highly recommend)。我用過之后,也覺得有些時候用用還是有好處的。 PageHeap.Exe將針對某個指定的應用程序啟用Page Heap標志,從而自動監視所有的malloc、new和heapAlloc的內存分配,找出內存錯誤。 PageHeap.Exe的下載地點: http://download.microsoft.com/download/vc60pro/utility/6.0/win98/en-us/pageheap1.exe 下面我們簡單地給出PageHeap使用步驟: 第一步: 在命令行中運行PageHeap.Exe。如果你以前設置過啟用Global Page Heap標志,那么你將看到一個列表,給出所有已經啟用了的應用程序的名字,不含路徑。 如下所示: C:\>pageheap pgh.exe????????????????????????????????? enabled testSplit.exe??????????????????????????? enabled
編譯一個小程序,其中有如下代碼:
void main() Build出一個Debug版本。運行之,你看不到有任何異常的報告。 但其實m_p[m_len]=0這句話就是越界寫了,因為只分配到了m_p[m_len-1]!這種情況就叫Dynamic memory overrun。用BoundsChecker是可以查到的。 這時,表面上看不出任何問題,但是一顆定時炸彈已經埋下了。
在命令行中運行PageHeap /enable YourApplicationName.exe 0x01。 再運行一次不帶參數的PageHeap,察看上面的命令是否生效。你的應用程序應該在啟用的列表中。 注意:千萬不要在YourApplication.Exe前面加上路徑!! 0x01的含義在后面說明。
再次運行你的程序。 你將會注意到在Output窗口的加載各種DLL之前,多了幾句話:
Loaded exports for 'C:\WINNT\System32\ntdll.dll' 這就是Page Heap的監視機制在發揮作用!他告訴你你的堆00470000被創建出來了。 然后程序退出后,Output窗口有這么幾句話表明一定有什么錯誤發生了:
Page heap: block @ 0015AFF8 is corrupted (reason 10) 這說明在銷毀堆00470000時遇到了麻煩,就是數據塊0015AFF8被誤用了,原因是誤用了下標語法。看,說得多么清楚!也節省了許多翻來覆去查代碼的工作!
1:啟用PageHeap不能夠影響正在運行中的應用程序。如果你需要啟用一些正在運行且不能重啟的程序的PageHeap,那請運行PageHeap啟用后,重新啟動機器。 2:要想查看PageHeap把信息放到哪里了,請打開你的注冊表,來到HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options 你將會看到你的應用程序也在這個項下面。你的應用程序的GlobalFlag被設置為了0x02000000,PageHeapFlags被設置為了0x01。 3:PageHeap的原理是這樣,它在已分配的內存的后面放上幾個守護字節(Guard Bytes),再跟上一個標記為PAGE_NOACCESS的內存頁。這樣,已分配內存的后面如果被重寫了,那么守護字節就會被改變,于是當內存被釋放時,PageHeap就會引發一個AV(Access Violation)。大體上就是這樣。所以只有最后釋放這塊問題內存時,才會有PageHeap的報告!這就是PageHeap的局限性吧。 參數0x01的含義: FLAGS hex value (0x...) has the following structure: ??? B7-B0?? Bit flags??? 1 - enable page heap
??? 01 - enable page heap. If zero normal heap is used. In 99% of the cases you will want this to be set. 看到了嗎?你還可以設置參數為0x10,從而可以檢查內存向前的越界寫! Gflags.Exe是微軟的Debugging Tools里面的工具。在Windows 2000的Resource Kit中也可以找得到。我們也可以用它來完成和PageHeap相同的任務。當然,Gflags.EXE還能做許許多多其他的事情。這里我們就不介紹了,總之物超所值。 具體的使用辦法是: 1)???? 運行Gflags.Exe; 2) 你將看到一個對話框。在”Image File”的編輯框中寫下你的應用程序的名字,如YourApp.Exe。注意不要路徑! 3) 選擇”Image File Options”的單選鈕;
4) 這時,你會看到對話框的內容突然一變。選中“Place heap 5) 點擊Apply按鈕。 這樣,就達到了PageHeap的效果。現在運行你的程序,overwrite你的堆,就應該生成一個AV了!
|


