我需要 WOW64 转储来进行 GDI 句柄分析吗?

Do I need a WOW64 dump for GDI Handle analysis?

我正在调试潜在的 GDI 句柄泄漏。感谢 @Alois Kraus, there is a WinDbg script 执行句柄计数。

从我的调试会话中,especially for .NET,我发现通常,最好有 32 位进程的 32 位转储和 64 位进程的 64 位转储。

不幸的是,我收到了 2 个故障转储,脚本无法运行。深入研究,我发现 GdiSharedHandleTable 在那些转储中是 null

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

现在,在 his website 上,Alois 提到了

Important: If you are running on a 64 bit OS you need to attach the 64-bit Windbg even if you debug a 32-bit application!

不幸的是,在 32 位故障转储上使用 64 位 WinDbg 没有帮助。结果还是一样

现在有一个理论:

所以我的问题是:我是否遇到需要 WOW64 崩溃转储的罕见情况? 如果能对我的理论进行更详细的解释,那就太好了。如果某本书中已经有很好的解释,那么参考该章就足够了。还没有我就买

对于 GDI 句柄转储,您需要进行 64 位转储,即使它是 Win64 计算机上的 32 位进程。如果您在 64 位机器上进行 32 位转储,则指向 GDI 共享句柄 table 的指针为空。看起来此信息仅为 64 位转储捕获。

这是有道理的,因为您需要在 32 位进程中处理 64 位指针,因为进程的 GDI 句柄 table 部分从内核 space 映射到您的地址 space。我想这样做是为了与 32 位进程应该只包含相同位数的指针的规则保持一致。

如果转储是在进程到达其 WinMain / Main /WinmainCrtStartup / Etc 之前进行的
也就是说,如果初始化代码不是 运行 那么 GdiSharedHandleTable 可以是 null

在正常运行期间崩溃的转储不是这种情况,但需要注意一点
例如,如果您在 windbg 中启动 calc.exe 并在第一次系统中断时检查 GdiSharedHandleTable GdiSharedHandle 可以为 NULL
但如果您在 @$exentry 或 calc!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