Do I need a WOW64 dump for GDI Handle analysis?

I'm debugging a potential GDI Handle Leak. Thanks to @Alois Kraus, there is a WinDbg script which performs a handle count.

From my debugging sessions, especially for .NET, I find that usually, it's better to have 32-bit dumps of 32-bit processes and 64-bit dumps of 64-bit processes.

Unfortunately, with 2 crash dumps I received, the script does not work. Looking deeper into it, I found out that the GdiSharedHandleTable is null in those dumps:

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

Now, on his website, Alois mentions

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!

Unfortunately, using 64-bit WinDbg on the 32-bit crash dump does not help. The result is still the same.

Now here's a theory:

  • some DLLs in a 32-bit process are 64 bit DLLs (see Windows Internals 5, Chapter 3, "System mechanisms," page 211)
  • ntdll is one of them (it is loaded twice, in the 64-bit version and the 32-bit version)
  • While GDI objects are user objects (and not kernel objects), they still need to be painted, etc. by the OS. Therefore it could be required that they are managed in the WOW64 layer
  • This would mean that I have to have a WOW64 crash dump to make it work
  • So my question is: do I have the seldom case here that I need a WOW64 crash dump? A more detailed explanation of my theory would be great. If there's a good explanation in some book already, a reference to the chapter is enough. I'll buy it if I don't have it yet.


    For a GDI handle dump you need to take 64 bit dump even if it is a 32 bit process on a Win64 machine. If you take a 32 bit dump on a 64 bit machine the pointer to the GDI Shared handle table is null. It looks like this information is only captured for a 64 bit dump.

    That makes sense since you would need to deal with 64 bit pointers in a 32 bit process because the GDI handle table part of your process is mapped from the kernel space into your address space. I guess that was done to stay consistent with the rule that a 32 bit process should only contain pointers of the same bitness.


    if the dump was taken before the process reached its WinMain / Main /WinmainCrtStartup / Etc
    that is if the initialization code isn't run then GdiSharedHandleTable can be null

    It is not the case for a dump that crashed during its normal operation but it is a point to note
    for example if you started calc.exe in windbg and check for GdiSharedHandleTable when it was on the first system break GdiSharedHandle can be NULL
    but will be filled if you set a break on @$exentry or calc!WinMain

    the script that generated this output has been posted as an answer to 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:wdscrdumpgdi.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:Windowssystem32calc.exe
    Total Gdi Handles = 21
    DC       = 2
    Font     = 0
    Region   = 17
    Brush    = 0
    Bitmap   = 1
    Pen      = 1
    Pallete  = 0
    Unknpown = 0
    

    在这里输入图像描述

    链接地址: http://www.djcxy.com/p/37338.html

    上一篇: 如何在使用Slick的VARCHAR列中使用UUID?

    下一篇: 我需要一个WOW64转储进行GDI句柄分析吗?