2016-12-01 81 views
7

我正在調試潛在的GDI手柄泄漏。由於@Alois Kraus,有一個WinDbg script它執行句柄計數。我是否需要WOW64轉儲進行GDI句柄分析?

從我的調試會話especially for .NET中,我發現通常最好是32位進程的32位轉儲和64位進程的64位轉儲。

不幸的是,在收到2次崩潰轉儲後,腳本無法運行。展望深入,我發現該GdiSharedHandleTable是null在那些垃圾堆:

0:000> dt ntdll!_PEB GdiSharedHandleTable @$peb 
    +0x094 GdiSharedHandleTable : (null) 

現在,his website,阿洛伊斯提到

重要:如果您在64位操作系統上運行,你需要即使您調試32位應用程序,也要附加64位Windbg!

不幸的是,在32位故障轉儲中使用64位WinDbg並沒有幫助。結果仍然是一樣的。

現在,這裏的一個理論:

  • 在32位過程中的一些DLL是64個DLL(請參閱Windows內部5,第3章, 「系統機制,」 211頁)
  • ntdll是一個(它在64位版本和32位版本中被加載兩次)
  • 雖然GDI對象是用戶對象(而不是內核對象),但它們仍然需要由操作系統繪製等。因此,可以要求他們在WOW64層管理
  • 這意味着,我必須有一個WOW64崩潰轉儲,使其工作

所以我的問題是:做我有很少的情況下在這裏,我需要一個WOW64崩潰轉儲?我的理論更詳細的解釋會很棒。如果在某本書中有一個很好的解釋,那麼對這一章的引用就足夠了。如果我還沒有,我會買它。

回答

1

對於GDI句柄轉儲,即使它是Win64機器上的32位進程,也需要進行64位轉儲。如果你在64位機器上進行32位轉儲,則指向GDI共享句柄表的指針爲空。它看起來像只有64位轉儲才能捕獲此信息。

這很有意義,因爲您需要處理32位進程中的64位指針,因爲您的進程的GDI句柄表部分已從內核空間映射到您的地址空間。我想這是爲了保持與32位進程只應包含相同位數的指針的規則一致。

2

如果轉儲過程之前拍攝達到了WinMain函數/主/ WinmainCrtStartup /等
即如果初始化代碼沒有然後運行GdiSharedHandleTable可以爲空

這不是一個轉儲的情況下在正常操作期間墜毀,但如果您開始計算,則需要注意的一點是
。exe文件在WinDbg中,檢查GdiSharedHandleTable當它是第一個系統上打破GdiSharedHandle可以爲NULL
,但如果你設置@ $ exentry或計算的突破將填補!WinMain函數

生成此輸出的腳本已張貼的答案linked thread

0:000> dd @@c++(@$Peb->GdiSharedHandleTable) 

00000000 ???????? ???????? ???????? ???????? 
00000010 ???????? ???????? ???????? ???????? 
00000020 ???????? ???????? ???????? ???????? 
00000030 ???????? ???????? ???????? ???????? 
00000040 ???????? ???????? ???????? ???????? 
00000050 ???????? ???????? ???????? ???????? 
00000060 ???????? ???????? ???????? ???????? 
00000070 ???????? ???????? ???????? ???????? 

0:000> g calc!WinMain 

calc!WinMain: 
00591635 8bff   mov  edi,edi 

0:000> dd @@c++(@$Peb->GdiSharedHandleTable) 

00470000 00000000 00000000 40000000 00000000 
00470010 00000000 00000000 00000000 00000000 
00470020 00000000 00000000 00000000 00000000 
00470030 00000000 00000000 00000000 00000000 
00470040 00000000 00000000 00000000 00000000 
00470050 00000000 00000000 00000000 00000000 
00470060 00000000 00000000 00000000 00000000 
00470070 00000000 00000000 00000000 00000000 

0:000> $$>a< c:\wdscr\dumpgdi.txt 

gdioffs Kaddr  Pid  Count Handle Type  Tname IsLive UAddr  
00472b30 fe6b5728 00000ca4 00000000 0d0102b3 00000001 DC  00000040 000e0cb0 
00472be0 fdf73da8 00000ca4 00000000 420502be 00000005 Bitmap 00000040 00000000 
004737b0 fddac108 00000ca4 00000000 9605037b 00000005 Bitmap 00000040 00000000 
00474030 fe76eda8 00000ca4 00000000 eb050403 00000005 Bitmap 00000040 00000000 
00474c90 fddde008 00000ca4 00000000 d70a04c9 0000000a Font  00000040 001fb1e8 
0047ab80 fddab008 00000ca4 00000000 ba050ab8 00000005 Bitmap 00000040 00000000 
0047f270 fddbcda8 00000ca4 00000000 16050f27 00000005 Bitmap 00000040 00000000 
0047fef0 fdee4da8 00000ca4 00000000 cd050fef 00000005 Bitmap 00000040 00000000 
004809f0 fe72eda8 00000ca4 00000000 3405109f 00000005 Bitmap 00000040 00000000 
00480e50 fdda5aa8 00000ca4 00000000 0e0510e5 00000005 Bitmap 00000040 00000000 
00481cf0 ffb0fda8 00000ca4 00000000 df0511cf 00000005 Bitmap 00000040 00000000 
00481d70 fddb0da8 00000ca4 00000000 930511d7 00000005 Bitmap 00000040 00000000 
00482020 ff4a1da8 00000ca4 00000000 d4051202 00000005 Bitmap 00000040 00000000 
00482060 fddd4008 00000ca4 00000000 39051206 00000005 Bitmap 00000040 00000000 
00482170 fddb6008 00000ca4 00000000 20051217 00000005 Bitmap 00000040 00000000 
00483140 ff4a0008 00000ca4 00000000 4e051314 00000005 Bitmap 00000040 00000000 
00483870 ff427980 00000ca4 00000000 6d051387 00000005 Bitmap 00000040 00000000 
00483d80 fe7d04b0 00000ca4 00000000 bd0513d8 00000005 Bitmap 00000040 00000000 
00484620 ff437eb8 00000ca4 00000000 0d101462 00000010 Brush 00000040 000f0fd8 
004846a0 fddc2da8 00000ca4 00000000 d305146a 00000005 Bitmap 00000040 00000000 
00484b80 fdf1a728 00000ca4 00000000 530114b8 00000001 DC  00000040 000e0ae0 


Gdi Handles for C:\Windows\system32\calc.exe 
Total Gdi Handles = 21 
DC  = 2 
Font  = 0 
Region = 17 
Brush = 0 
Bitmap = 1 
Pen  = 1 
Pallete = 0 
Unknpown = 0 

enter image description here

+0

你使用哪種鈣?在Win 7 x64上,calc是64位。在調試會話,'DD @@ C++(@ $ Peb-> GdiSharedHandleTable)''返回00000000 00000000',所以它的零和腳本不應該工作。但是,當您運行腳本時,它會返回正確的結果。這似乎對我來說是一個矛盾。 –

+0

對不起,我無法理解什麼矛盾,你看我做DD POI()2倍時首先應用在systembp和第二,當應用程序是在它的WinMain第一時間表爲空和第二時間表指向有效的內存 – blabb

+0

對不起,我故障。 –