Archive for the ‘Debugging’ Category

Crash Dump Analysis Patterns (Part 58a)

Wednesday, April 9th, 2008

Among various memory leaks leading to Insufficient Memory pattern there is so called session pool leak briefly touched in the previous kernel pool leaks post. I decided to factor it out separately because it also involves GDI handles and structures allocated per user session that has the limit on how many of them can be created and this case should rather be called Handle Limit. Such leaks can result in poor visual application behavior after some time when drawing requests are not satisfied anymore. In severe cases, when the same bugs are present in a display driver, it can result in bugchecks like

BugCheck AB: SESSION_HAS_VALID_POOL_ON_EXIT

or, if a handle allocation request was not satisfied, it may result in a NULL pointer stored somewhere with the subsequent Invalid Pointer access:

SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e)

CONTEXT:  b791e010 -- (.cxr 0xffffffffb791e010)
eax=00000000 ebx=bc43d004 ecx=a233add8 edx=00000000 esi=bc430fff edi=00000000
eip=bfe7d380 esp=b791e3dc ebp=b791e480 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
DisplayDriver+0×3e380:
bfe7d380 8a4702          mov     al,byte ptr [edi+2]        ds:0023:00000002=??

Rather than providing examples from specific kernel dump files I created 3 Win32 applications in Visual C++ that simulate GDI leaks. All of them create GDI objects in a loop and select them into their current graphics device context (DC) on Windows Server 2003 x64 SP2. Before running them I got the following session paged pool statistics:

lkd> !poolused c

   Sorting by Session Paged Pool Consumed

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 NV_x        0        0         5 14024704 UNKNOWN pooltag 'NV_x', please update pooltag.txt
 BIG         0        0       257  3629056 Large session pool allocations (ntos\ex\pool.c) , Binary: nt!mm
 NV          0        0       203  1347648 nVidia video driver
 Ttfd        0        0       233  1053152 TrueType Font driver
 Gh05        0        0       391  1050400 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gla1        0        0       348   785088 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gcac        0        0        25   640880 Gdi glyph cache
 Gla5        0        0       631   323072 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gdrs        0        0        33   172288 Gdi GDITAG_DRVSUP
 Gla:        0        0       212   139072 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gla4        0        0       487   116880 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Usti        0        0       148    97088 THREADINFO , Binary: win32k!AllocateW32Thread
 Gla8        0        0       383    91920 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gla@        0        0       339    70512 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gbaf        0        0        48    67584 UNKNOWN pooltag ‘Gbaf’, please update pooltag.txt
 knlf        0        0        20    66496 UNKNOWN pooltag ‘knlf’, please update pooltag.txt
 GDev        0        0         7    57344 Gdi pdev
 Usqu        0        0       152    53504 Q , Binary: win32k!InitQEntryLookaside
 Uscu        0        0       334    53440 CURSOR , Binary: win32k!_CreateEmptyCursorObject
 Bmfd        0        0        21    50224 Font related stuff
 Uspi        0        0       153    40000 PROCESSINFO , Binary: win32k!MapDesktop
 Gfnt        0        0        47    39856 UNKNOWN pooltag ‘Gfnt’, please update pooltag.txt
 Ggb         0        0        34    39088 Gdi glyph bits
 Gh08        0        0        33    38656 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Ghab        0        0       228    32832 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Ovfl        0        0         1    32768 The internal pool tag table has overflowed - usually this is a result of nontagged allocations being made
 Gpff        0        0        88    27712 Gdi physical font file
 Gpfe        0        0        88    27600 UNKNOWN pooltag ‘Gpfe’, please update pooltag.txt
 thdd        0        0         1    20480 DirectDraw/3D handle manager table
 Gebr        0        0        17    19776 Gdi ENGBRUSH
 Gh0@        0        0        86    19264 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gsp         0        0        79    18960 Gdi sprite
 HT40        0        0         2    16384 UNKNOWN pooltag ‘HT40′, please update pooltag.txt
 Gpat        0        0         4    16192 UNKNOWN pooltag ‘Gpat’, please update pooltag.txt
 Ggls        0        0       169    12944 Gdi glyphset
 Glnk        0        0       371    11872 Gdi PFELINK
 Gldv        0        0         9    11248 Gdi Ldev
 Gffv        0        0        84     9408 Gdi FONTFILEVIEW
 Gfsb        0        0         1     8192 Gdi font sustitution list
 Uskt        0        0         2     7824 KBDTABLE , Binary: win32k!ReadLayoutFile
 Gh04        0        0         7     5856 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gdcf        0        0        51     5712 UNKNOWN pooltag ‘Gdcf’, please update pooltag.txt
 Gh0<        0        0        88     5632 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gglb        0        0         1     4096 Gdi temp buffer
 Ustm        0        0        30     3360 TIMER , Binary: win32k!InternalSetTimer
 Gspm        0        0        39     3120 UNKNOWN pooltag ‘Gspm’, please update pooltag.txt
 Usac        0        0        16     3056 ACCEL , Binary: win32k!_CreateAcceleratorTable
 Usqm        0        0        25     2800 QMSG , Binary: win32k!InitQEntryLookaside
 Ghas        0        0         3     2592 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Uscl        0        0        20     2128 CLASS , Binary: win32k!ClassAlloc
 Uswl        0        0         1     2032 WINDOWLIST , Binary: win32k!BuildHwndList
 Gmul        0        0        19     1520 UNKNOWN pooltag ‘Gmul’, please update pooltag.txt
 Dddp        0        0         8     1472 UNKNOWN pooltag ‘Dddp’, please update pooltag.txt
 Ggdv        0        0         8     1472 Gdi GDITAG_GDEVICE
 UsDI        0        0         4     1408 DEVICEINFO , Binary: win32k!CreateDeviceInfo
 Vtfd        0        0         4     1312 Font file/context
 Ushk        0        0        20     1280 HOTKEY , Binary: win32k!_RegisterHotKey
 Gspr        0        0         3     1264 Gdi sprite grow range
 Gtmw        0        0        13     1248 Gdi TMW_INTERNAL
 Gxlt        0        0         8     1152 Gdi Xlate
 Gpft        0        0         2      944 Gdi font table
 Uspp        0        0         5      944 PNP , Binary: win32k!AllocateAndLinkHidTLCInf
 Ussm        0        0         7      896 SMS , Binary: win32k!InitSMSLookaside
 Gdbr        0        0        10      800 Gdi driver brush realization
 Usdc        0        0         8      768 DCE , Binary: win32k!CreateCacheDC
 Usct        0        0        12      768 CHECKPT , Binary: win32k!CkptRestore
 Usim        0        0         2      736 IME , Binary: win32k!CreateInputContext
 Usci        0        0         3      720 CLIENTTHREADINFO , Binary: win32k!InitSystemThread
 Gh09        0        0         1      640 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Ussy        1       80         4      608 SYSTEM , Binary: win32k!xxxDesktopThread
 Urdr        0        0         9      576 REDIRECT , Binary: win32k!SetRedirectionBitmap
 Uswd        0        0         2      576 WINDOW , Binary: win32k!xxxCreateWindowEx
 Uscb        0        0         3      544 CLIPBOARD , Binary: win32k!_ConvertMemHandle
 Gcsl        0        0         1      496 Gdi string resource script names
 Ustx        0        0        10      496 TEXT , Binary: win32k!NtUserDrawCaptionTemp
 Ussw        0        0         1      496 SWP , Binary: win32k!_BeginDeferWindowPos
 Gdev        0        0         2      480 Gdi GDITAG_DEVMODE
 Usih        0        0        10      480 IMEHOTKEY , Binary: win32k!SetImeHotKey
 Gdrv        0        0         1      368 UNKNOWN pooltag ‘Gdrv’, please update pooltag.txt
 GVdv        0        0         1      320 UNKNOWN pooltag ‘GVdv’, please update pooltag.txt
 Gmap        0        0         1      320 Gdi font map signature table
 Uskb        0        0         2      288 KBDLAYOUT , Binary: win32k!xxxLoadKeyboardLayoutEx
 Uskf        0        0         2      288 KBDFILE , Binary: win32k!LoadKeyboardLayoutFile
 Uswe        0        0         2      224 WINEVENT , Binary: win32k!_SetWinEventHook
 Gddf        0        0         2      224 Gdi ddraw driver heaps
 Gddv        0        0         2      192 Gdi ddraw driver video memory list
 GFil        0        0         2      192 Gdi engine descriptor list
 Gdwd        0        0         2       96 Gdi watchdog support objects , Binary: win32k.sys
 Usd9        0        0         1       80 DDE9 , Binary: win32k!xxxCsDdeInitialize
 Gvds        0        0         1       64 UNKNOWN pooltag ‘Gvds’, please update pooltag.txt
 GreA        0        0         1       64 UNKNOWN pooltag ‘GreA’, please update pooltag.txt
 Usse        0        0         1       48 SECURITY , Binary: win32k!SetDisconnectDesktopSecu
 Usvl        0        0         1       48 VWPL , Binary: win32k!VWPLAdd
 Mdxg        1      112         0        0 UNKNOWN pooltag ‘Mdxg’, please update pooltag.txt
 Gini        3      128         0        0 Gdi fast mutex
 Usev        1       64         0        0 EVENT , Binary: win32k!xxxPollAndWaitForSingleO
 Gdde        3      240         0        0 Gdi ddraw event
 TOTAL           9      624      6256 24408704

The first application leaks fonts:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;

 switch (message)
 {
   case WM_PAINT:
     hdc = BeginPaint(hWnd, &ps);
     while (true)
     {
        HFONT hf = CreateFont(10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial");
        SelectObject(ps.hdc, hf);
     }
     EndPaint(hWnd, &ps);
     break;

We clearly see the leak as the greatly increased number of allocations for ”Gla:” pool tag:

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 NV_x        0        0         5 14024704 UNKNOWN pooltag 'NV_x', please update pooltag.txt
 Gla:        0        0     10194  6687264 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 BIG         0        0       248  3690496 Large session pool allocations (ntos\ex\pool.c) , Binary: nt!mm
 NV          0        0       203  1347648 nVidia video driver
 Gh05        0        0       396  1057888 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Ttfd        0        0       226  1043264 TrueType Font driver

The second application leaks fonts and pens:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;

 switch (message)
 {
   case WM_PAINT:
     hdc = BeginPaint(hWnd, &ps);
     while (true)
     {
       HFONT hf = CreateFont(10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial");
       HPEN hp = CreatePen(0, 10, RGB(10, 20, 30));
       SelectObject(ps.hdc, hf);
       SelectObject(ps.hdc, hp);
     }
     EndPaint(hWnd, &ps);
     break;

We see that the roughly the same number of allocations is split between ”Gla:” and “Gh0@” pool tags:

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 NV_x        0        0         5 14024704 UNKNOWN pooltag 'NV_x', please update pooltag.txt
 BIG         0        0       262  3874816 Large session pool allocations (ntos\ex\pool.c) , Binary: nt!mm
 Gla:        0        0      5203  3413168 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 NV          0        0       203  1347648 nVidia video driver
 Gh0@        0        0      5077  1137248 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Ttfd        0        0       233  1053152 TrueType Font driver

The third program leaks fonts, pens and brushes:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;

 switch (message)
 {
   case WM_PAINT:
   hdc = BeginPaint(hWnd, &ps);
   while (true)
   {
     HFONT hf = CreateFont(10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial");
     HPEN hp = CreatePen(0, 10, RGB(10, 20, 30));
     HBRUSH hb = CreateSolidBrush(RGB(10, 20, 30));
     SelectObject(ps.hdc, hf);
     SelectObject(ps.hdc, hp);
     SelectObject(ps.hdc, hb);
   }
   EndPaint(hWnd, &ps);
   break;

Now we see that the same number of allocations is almost equally split between ”Gla:”, “Gh0@” and “Gla@” pool tags:

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 NV_x        0        0         5 14024704 UNKNOWN pooltag 'NV_x', please update pooltag.txt
 BIG         0        0       262  3874816 Large session pool allocations (ntos\ex\pool.c) , Binary: nt!mm
 Gla:        0        0      3539  2321584 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 NV          0        0       203  1347648 nVidia video driver
 Ttfd        0        0       233  1053152 TrueType Font driver
 Gh05        0        0       392  1052768 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gla1        0        0       353   796368 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gh0@        0        0      3414   764736 Gdi Handle manager specific object types: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gla@        0        0      3665   762320 Gdi handle manager specific object types allocated from lookaside memory: defined in w32\ntgdi\inc\ntgdistr.h , Binary: win32k.sys
 Gcac        0        0        25   640880 Gdi glyph cache

When the certain amount of handles is reached all subsequent GDI Create calls fail and other applications start showing various visual defects. Print screen operation also fails with insufficient memory message.
                                                                                                                                                                                                        
- Dmitry Vostokov @ DumpAnalysis.org -

The Inception of Debugging Studio

Wednesday, April 2nd, 2008

Born out of 2008 April Fool’s joke (although I was thinking about it long before) the idea is to have a general framework and associated IDE for analysis activities for various tools that produce logs. Similar to planned GUI Monitor integrating WindowHistory, MesageHistory and ScreenHistory tools but also including Debugger Log Analyzer, Debugging Notebooks, various memory and trace log visualization subsystems. It also has the working title UTF (Unified Tools Framework).

Seems I’m very easy on inceptions :-) All this will be covered in great detail in the forthcoming book which I tirelessly advertise:

DebugWare: The Art and Craft of Writing Troubleshooting Tools

- Dmitry Vostokov @ DumpAnalysis.org -

Microsoft gives sneak preview of Debugging Studio

Tuesday, April 1st, 2008

This looks really cool:

http://www.microsoft.com/whdc/devstudio/default.mspx 

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Forum has been reopened!

Sunday, March 30th, 2008

This is an attempt to revive the forum closed a year ago due to the lack of interest during that time. Now the number of visitors has increased by an order of magnitude and I get more and more requests to help with crash dump analysis but I cannot guarantee immediate response. Therefore I upgraded and reopened Crash Dump Analysis and Debugging Forum and encourage using it. In order to prevent spammers gaining access any new registration has to be approved by me (usually in less than 24 hours).

- Dmitry Vostokov @ DumpAnalysis.org -

Ceteris Paribus in Comparative Troubleshooting

Thursday, March 27th, 2008

Ceteris Paribus means “with other things [being] the same” (Latin) and when applied to software troubleshooting and debugging means equal environment and configuration. My favorite example is troubleshooting an issue using two Citrix CDF traces (ETW based): one is for the problem and another for the expected behavior. Say we have a terminal services connectivity problem where a published application doesn’t start on the one particular server in Citrix farm. Here Ceteris Paribus means that the application, connection method, configuration, user name, and so on, are all the same for both traces. 

Looks like I have used Latin to obfuscate something obvious but surely many engineers forget it when facing complex issues. This equally applies to debugging as well. 

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Publishing Roadmap

Wednesday, March 26th, 2008

It may appear that I have announced too many titles but they all fall into the well-defined publishing roadmap (excluding a couple of publishing digressions like Debugware book):

This is a high level illustration of global incremental and iterative parts of IIPP (Iterative and Incremental Publishing Process) that I coined some months earlier. More about local iterative and incremental parts in one of my next posts. 

- Dmitry Vostokov @ DumpAnalysis.org -

Memory Dump Analysis Anthology, Volume 2

Tuesday, March 25th, 2008

Although the first volume has not been published yet (scheduled for 15th of April, 2008) the planning for the second volume has already begun. Preliminary information is:

  • Title: Memory Dump Analysis Anthology, Volume 2
  • Paperback: 512 pages (*)
  • ISBN-13: 978-0-9558328-7-1
  • Author: Dmitry Vostokov
  • Publisher: Opentask (01 Oct 2008)
  • Language: English
  • Product Dimensions: 22.86 x 15.24

Hardcover version is also planned. PDF version will be available for download too.

(*) subject to change

- Dmitry Vostokov @ DumpAnalysis.org -

Exploring NDIS Extension

Tuesday, March 25th, 2008

There is a good Microsoft white paper about !ndiskd commands to interrogate kernel dumps:

Debugging NDIS Drivers

Applying !ndiskd.protocols command we can see that there are more protocols added to Vista: 

Windows Server 2003 SP2:

kd> !ndiskd.protocols
 Protocol 862db330: NDISUIO
    Open 86420650 - Miniport: 862e2ab0 AMD PCNET Family PCI Ethernet Adapter

 Protocol 86324780: TCPIP_WANARP
    Open 86324008 - Miniport: 863a2130 WAN Miniport (IP)

 Protocol 86318790: TCPIP
    Open 8637c008 - Miniport: 862e2ab0 AMD PCNET Family PCI Ethernet Adapter

 Protocol 863e3c28: NDPROXY
    Open 8639e0d0 - Miniport: 86361530 Direct Parallel
    Open 8639bb48 - Miniport: 86361530 Direct Parallel
    Open 863e48b0 - Miniport: 863e3130 WAN Miniport (L2TP)
    Open 86404008 - Miniport: 863e3130 WAN Miniport (L2TP)

 Protocol 863a9d80: RASPPPOE

 Protocol 863a9008: NDISWAN
    Open 863e3ab0 - Miniport: 86361530 Direct Parallel
    Open 86398c30 - Miniport: 862c4530 WAN Miniport (PPTP)
    Open 864618f8 - Miniport: 8637a870 WAN Miniport (PPPOE)
    Open 86468a28 - Miniport: 863e3130 WAN Miniport (L2TP)

Vista: 

1: kd> !ndiskd.protocols
 Protocol fffffa8004569580: RSPNDR
    Open fffffa8004566a20 - Miniport: fffffa80039711a0 Broadcom NetXtreme 57xx Gigabit Controller

 Protocol fffffa80043a4900: LLTDIO
    Open fffffa800428a1d0 - Miniport: fffffa80039711a0 Broadcom NetXtreme 57xx Gigabit Controller

 Protocol fffffa8003f6c820: WANARPV6
    Open fffffa8003f1c010 - Miniport: fffffa800399f1a0 WAN Miniport (IPv6)

 Protocol fffffa8003f6cd20: WANARP
    Open fffffa8003f1c670 - Miniport: fffffa80039d61a0 WAN Miniport (IP)

 Protocol fffffa8003eedb10: TCPIP6TUNNEL
    Open fffffa8003f33010 - Miniport: fffffa800396c1a0 isatap.company.com
    Open fffffa8003f0f010 - Miniport: fffffa80038f21a0 Teredo Tunneling Pseudo-Interface

 Protocol fffffa8003eeb580: TCPIPTUNNEL

 Protocol fffffa8003eeb010: TCPIP6
    Open fffffa8003f452e0 - Miniport: fffffa80039711a0 Broadcom NetXtreme 57xx Gigabit Controller

 Protocol fffffa8003ee90d0: TCPIP
    Open fffffa8003ffc480 - Miniport: fffffa80039711a0 Broadcom NetXtreme 57xx Gigabit Controller

 Protocol fffffa8003c56010: NDPROXY
    Open fffffa8003d41450 - Miniport: fffffa800399d1a0 WAN Miniport (L2TP)
    Open fffffa8003d41a30 - Miniport: fffffa800399d1a0 WAN Miniport (L2TP)

 Protocol fffffa80039ad790: RASPPPOE

 Protocol fffffa80039af4e0: NDISWAN
    Open fffffa8004737a10 - Miniport: fffffa8004a321a0 RAS Async Adapter
    Open fffffa8003bf8ac0 - Miniport: fffffa80039c21a0 WAN Miniport (PPTP)
    Open fffffa8003c5cac0 - Miniport: fffffa80039c01a0 WAN Miniport (PPPOE)
    Open fffffa8003c565a0 - Miniport: fffffa800399d1a0 WAN Miniport (L2TP)

I noticed this extension when I got a bugcheck from the 3rd-party custom protocol driver:

SYSTEM_PTE_MISUSE (da)
The stack trace identifies the guilty driver.
Arguments:
Arg1: 00000400, Type of error.
Arg2: f7a9a413
Arg3: 00000001
Arg4: 00000000

0: kd> kL
ChildEBP RetAddr 
f5c68a68 8083b6e1 nt!KeBugCheckEx+0x1b
f5c68a90 8083d478 nt!MiRemoveIoSpaceMap+0x5d
f5c68b38 f5b6ebea nt!MmUnmapIoSpace+0x10c
WARNING: Stack unwind information not available. Following frames may be wrong.
f5c68b90 f5b69abe protocol!foo2+0x28ac
f5c68bf4 f70fd4be protocol!foo+0x1aa0
f5c68c90 f70fd2fc NDIS!ndisInitializeBinding+0x189
f5c68d18 f70fce48 NDIS!ndisCheckAdapterBindings+0xd9
f5c68d98 f70fca66 NDIS!ndisCheckProtocolBindings+0xd2
f5c68dac 80949b7c NDIS!ndisWorkerThread+0x74
f5c68ddc 8088e062 nt!PspSystemThreadStartup+0x2e
00000000 00000000 nt!KiThreadStartup+0x16

Arg1 0×400 one tells us this (from WinDbg help):

0×400 The base address of the I/O space mapping The number of pages to be freed 0 (Windows XP and later only) The caller is trying to free an I/O space mapping that the system is unaware of.

PTE  looks unknown indeed:

0: kd> !pte f7a9a413
VA f7a9a413
PDE at 00000000C0603DE8 PTE at 00000000C07BD4D0
contains 0000000000A87863 contains 0000000000000000
pfn a87 —DA–KWEV

We can see this protocol in the list:

0: kd> !ndiskd.protocols
 Protocol 89df10a0: CustomProtocol
    Open 89b4e6d8 - Miniport: 8a59d290 Broadcom BCM5708S NetXtreme II GigE (NDIS VBD Client)

 Protocol 8918f248: NDISUIO

 Protocol 89dd8008: TCPIP_WANARP
    Open 8a4da6f0 - Miniport: 8a50a9e8 WAN Miniport (IP)

 Protocol 89b4ec88: TCPIP

 Protocol 8a4cd5a0: NDPROXY
    Open 8a59b128 - Miniport: 8a58eab0 Direct Parallel
    Open 8a59b328 - Miniport: 8a58eab0 Direct Parallel
    Open 8a4f1580 - Miniport: 8a58a328 WAN Miniport (L2TP)
    Open 8a507008 - Miniport: 8a58a328 WAN Miniport (L2TP)

 Protocol 8a4e7008: RASPPPOE

 Protocol 8a5cb490: NDISWAN
    Open 8a59b988 - Miniport: 8a58eab0 Direct Parallel
    Open 8a5976c0 - Miniport: 8a591628 WAN Miniport (PPTP)
    Open 8a594468 - Miniport: 8a4e93f0 WAN Miniport (PPPOE)
    Open 8a4d3580 - Miniport: 8a58a328 WAN Miniport (L2TP)

- Dmitry Vostokov @ DumpAnalysis.org -

Windows® Device Drivers

Thursday, March 20th, 2008

Why do we need yet another book about device drivers? There are couple of reasons here:

  1. Old books are more about developing the narrow range of legacy drivers than troubleshooting and debugging them.

  2. New books shift towards WDF and ignore legacy drivers.

  3. Windows Internals book is too big and something lightweight is desperately needed.

  4. No published driver books use UML as communication device and discuss driver developement as software factory.

  5. Existing books mostly view device drivers as hardware device drivers.

I started collecting and organizing information about Windows drivers 2 years ago and published a few selected materials so you can get an approximate flavour of what is expected in the forthcoming book scheduled for the next year:

UML and Device Drivers

  • Title:  Windows Device Drivers: An Introduction
  • Author: Dmitry Vostokov
  • Paperback: 128 pages
  • ISBN-13: 978-0-9558328-4-0
  • Publisher: Opentask (15 Apr 2009)
  • Language: English
  • Product Dimensions: 22.86 x 15.24

- Dmitry Vostokov @ DumpAnalysis.org -

WinDbg book to be published after MDAA V1

Thursday, March 20th, 2008

This is a forthcoming reference book for technical support and escalation engineers troubleshooting and debugging complex software issues. The book is also invaluable for software maintenance and development engineers debugging unmanaged, managed and native code.

  • Title: Windows® Debugging Notebook: Essential Concepts, WinDbg Commands and Tools
  • Author: Dmitry Vostokov
  • Hardcover: 256 pages
  • ISBN-13: 978-0-9558328-5-7
  • Publisher: Opentask (1 September 2008)
  • Language: English
  • Product Dimensions: 22.86 x 15.24

- Dmitry Vostokov @ DumpAnalysis.org -

Memory Search Revisited

Thursday, March 20th, 2008

We all know about s memory search WinDbg command but it only searches the current virtual memory range. This is fine if we have a kernel memory or a user dump where we have uniform virtual space but for complete memory dumps we have many virtual to physical address mappings to cover user space of various processes. This is better illustrated on the following highly simplified picture where the typical current virtual space in a complete memory dump is enclosed in the shadowed box and consists of the kernel space and process A virtual address space ranges:

 

Therefore some data will be present in physical memory but not accessible through virtual memory search. To search through all physical memory there is !search WinDbg command and by default it searches for specific 32-bit value on 32-bit Windows and 64-bit value on 64-bit Windows. The latter means that we can search for 8 character string fragments on 64-bit Windows. For example, if we want to search for occurrences of ”ImaSrv.exe” string we can specify “ImaS” on 32-bit platform and “ImaSrv.e” on 64-bit platform. Taking into account little endian byte ordering we get the following hexadecimal equivalents:

0: kd> .formats 'SamI'
Evaluate expression:
  Hex:     53616d49
  Decimal: 1398893897
  Octal:   12330266511
  Binary:  01010011 01100001 01101101 01001001
  Chars:   SamI
  Time:    Wed Apr 30 22:38:17 2014
  Float:   low 9.68201e+011 high 0
  Double:  6.91145e-315

0: kd> .formats 'e.vrSamI'
Evaluate expression:
  Hex:     652e7672`53616d49
  Decimal: 7290895080156654921
  Octal:   0624563547112330266511
  Binary:  01100101 00101110 01110110 01110010 01010011 01100001 01101101 01001001
  Chars:   e.vrSamI
  Time:    Mon Dec  5 23:20:15.665 24704 (GMT+0)
  Float:   low 9.68201e+011 high 5.14923e+022
  Double:  2.46885e+179

Physical memory search gives us plenty of results:

0: kd> !search 53616d49
Searching PFNs in range 00000001 - 0013FFFF for [53616D49 - 53616D49]

Pfn      Offset   Hit      Va       Pte     
- - - - - - - - - - - - - - - - - - - - - - - - - - -
000079FA 000004C4 53616D49 A3AFB4C4 C051D7D8
 a3afb340+0x184   : Proc (Protected)  -- Process objects
00011442 00000848 53616D49 66EC2848 C0337610
00011442 0000093C 53616D49 66EC293C C0337610
0001328A 000009F4 43616D49 672E59F4 C0339728
000156F6 000009F4 43616D49 672E59F4 C0339728
00018C7C 000009DC 43616D49 671F49DC C0338FA0
0001ADF0 000003D4 52616D49 00000000 DC3E3B48
0001ADF0 000003E4 52616D49 00000000 DC3E3B48
00020BCE 000009DC 43616D49 671F49DC C0338FA0
...
...
...

We can dump either a virtual address if it is available and valid by using normal d* commands or dump a physical address by using their !d* extension equivalents, for example:

Pfn      Offset   Hit      Va       Pte     
- - - - - - - - - - - - - - - - - - - - - - - - - - -
00011442 00000848 53616D49 66EC2848 C0337610

 0: kd> !dc 11442000+00000848
#11442848 53616d49 65747379 6c642e6d 0000006c ImaSystem.dll...
#11442858 00000000 00000000 00000000 45cd0da0 ...............E
#11442868 00000000 0000293c 00000001 00000012 ....<)..........
#11442878 00000012 00002888 000028d0 00002918 .....(...(...)..
#11442888 00001160 000010b0 00001020 00001000 `....... .......
#11442898 00001130 00001010 000010a0 00001030 0...........0...
#114428a8 000020d8 000020cc 00001300 000013c0 . ... ..........
#114428b8 00001200 00001050 00001040 00001080 ....P...@.......

Note: Physical addresses are formed from PFN (Page Frame Numbers) by shifting them to the left by 12 bits (by adding 3 zeroes to the left). For example: 00011442 -> 11442000.

The cool feature of !search command is that it automatically recognizes pool tags and in our case it has found the process object: 

Pfn      Offset   Hit      Va       Pte     
- - - - - - - - - - - - - - - - - - - - - - - - - - -
000079FA 000004C4 53616D49 A3AFB4C4 C051D7D8
 a3afb340+0×184   : Proc (Protected)  — Process objects



0: kd> !pool A3AFB4C4
Pool page a3afb340 region is Nonpaged pool
 a3afb000 size:  120 previous size:    0  (Allocated)  MQAC
 a3afb120 size:   20 previous size:  120  (Allocated)  VadS
 a3afb140 size:   98 previous size:   20  (Allocated)  File (Protected)
 a3afb1d8 size:   30 previous size:   98  (Allocated)  MQAC
 a3afb208 size:   20 previous size:   30  (Allocated)  VadS
 a3afb228 size:   28 previous size:   20  (Free)       CcBc
 a3afb250 size:   30 previous size:   28  (Allocated)  Vad
 a3afb280 size:   30 previous size:   30  (Allocated)  Vad
 a3afb2b0 size:   20 previous size:   30  (Allocated)  VadS
 a3afb2d0 size:   40 previous size:   20  (Allocated)  SeTd
 a3afb310 size:   30 previous size:   40  (Allocated)  Vad
*a3afb340 size:  298 previous size:   30  (Allocated) *Proc (Protected)
  Pooltag Proc : Process objects, Binary : nt!ps

 a3afb5d8 size:    8 previous size:  298  (Free)       Irp
 a3afb5e0 size:   20 previous size:    8  (Allocated)  VadS
 a3afb600 size:    8 previous size:   20  (Free)       Irp
 a3afb608 size:   30 previous size:    8  (Allocated)  Even (Protected)
 a3afb638 size:   30 previous size:   30  (Allocated)  Vad
 a3afb668 size:   40 previous size:   30  (Allocated)  Vadl
 a3afb6a8 size:   70 previous size:   40  (Allocated)  NWFS
 a3afb718 size:   30 previous size:   70  (Allocated)  Vad
 a3afb748 size:   28 previous size:   30  (Allocated)  NpFr Process: a3afb360
 a3afb770 size:   98 previous size:   28  (Allocated)  File (Protected)
 a3afb808 size:   60 previous size:   98  (Allocated)  MmCa
 a3afb868 size:   98 previous size:   60  (Allocated)  File (Protected)
 a3afb900 size:   30 previous size:   98  (Allocated)  Even (Protected)
 a3afb930 size:   20 previous size:   30  (Allocated)  VadS
 a3afb950 size:   98 previous size:   20  (Allocated)  File (Protected)
 a3afb9e8 size:   30 previous size:   98  (Allocated)  MQAC
 a3afba18 size:  120 previous size:   30  (Allocated)  MQAC
 a3afbb38 size:   50 previous size:  120  (Allocated)  NpFc Process: a5659d88
 a3afbb88 size:   20 previous size:   50  (Allocated)  Port
 a3afbba8 size:   98 previous size:   20  (Allocated)  File (Protected)
 a3afbc40 size:   30 previous size:   98  (Allocated)  MQAC
 a3afbc70 size:  120 previous size:   30  (Allocated)  MQAC
 a3afbd90 size:  270 previous size:  120  (Allocated)  Thre (Protected)

0: kd> dc A3AFB4C4 l10
a3afb4c4  53616d49 652e7672 00006578 00000000  ImaSrv.exe......
a3afb4d4  00000000 00000000 00000000 a3afbfd4  ................
a3afb4e4  a282fe44 00000000 f7a60500 0000004c  D...........L...
a3afb4f4  001f07fb 00008005 00000000 7ffdd000  ................

Seems the search has found ImageFileName field of _EPROCESS structure. The field has 0×164 offset and we can dump the whole structure:

0: kd> dt _EPROCESS A3AFB4C4-0x164
ntdll!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x078 ProcessLock      : _EX_PUSH_LOCK
   +0x080 CreateTime       : _LARGE_INTEGER 0x1c86f66`5b95204a
   +0x088 ExitTime         : _LARGE_INTEGER 0x0
   +0x090 RundownProtect   : _EX_RUNDOWN_REF
   +0x094 UniqueProcessId  : 0x000009d0
   +0x098 ActiveProcessLinks : _LIST_ENTRY [ 0xa3af2598 - 0xa3b0a0b8 ]
   +0x0a0 QuotaUsage       : [3] 0x17030
   +0x0ac QuotaPeak        : [3] 0x18028
   +0x0b8 CommitCharge     : 0x37b6
   +0x0bc PeakVirtualSize  : 0x132d4000
   +0x0c0 VirtualSize      : 0x12d64000
   +0x0c4 SessionProcessLinks : _LIST_ENTRY [ 0xa3af25c4 - 0xa3b0a0e4 ]
   +0x0cc DebugPort        : (null)
   +0x0d0 ExceptionPort    : 0xd738e828
   +0x0d4 ObjectTable      : 0xdc23a008 _HANDLE_TABLE
   +0x0d8 Token            : _EX_FAST_REF
   +0x0dc WorkingSetPage   : 0x11741f
   +0x0e0 AddressCreationLock : _KGUARDED_MUTEX
   +0x100 HyperSpaceLock   : 0
   +0x104 ForkInProgress   : (null)
   +0x108 HardwareTrigger  : 0
   +0x10c PhysicalVadRoot  : 0xa3c21448 _MM_AVL_TABLE
   +0x110 CloneRoot        : (null)
   +0x114 NumberOfPrivatePages : 0x318d
   +0x118 NumberOfLockedPages : 7
   +0x11c Win32Process     : 0xbc33d968
   +0x120 Job              : (null)
   +0x124 SectionObject    : 0xdc2710c8
   +0x128 SectionBaseAddress : 0x00400000
   +0x12c QuotaBlock       : 0xa3bb2f38 _EPROCESS_QUOTA_BLOCK
   +0x130 WorkingSetWatch  : (null)
   +0x134 Win32WindowStation : 0x00000078
   +0x138 InheritedFromUniqueProcessId : 0x00000228
   +0x13c LdtInformation   : (null)
   +0x140 VadFreeHint      : (null)
   +0x144 VdmObjects       : (null)
   +0x148 DeviceMap        : 0xd7d0ff30
   +0x14c Spare0           : [3] (null)
   +0x158 PageDirectoryPte : _HARDWARE_PTE_X86
   +0x158 Filler           : 0
   +0x160 Session          : 0xf79d5000
   +0×164 ImageFileName    : [16]  “ImaSrv.exe”
   +0×174 JobLinks         : _LIST_ENTRY [ 0×0 - 0×0 ]
   +0×17c LockedPagesList  : (null)
   +0×180 ThreadListHead   : _LIST_ENTRY [ 0xa3afbfd4 - 0xa282fe44 ]
   +0×188 SecurityPort     : (null)
   +0×18c PaeTop           : 0xf7a60500
   +0×190 ActiveThreads    : 0×4c
   +0×194 GrantedAccess    : 0×1f07fb
   +0×198 DefaultHardErrorProcessing : 0×8005
   +0×19c LastThreadExitStatus : 0
   +0×1a0 Peb              : 0×7ffdd000 _PEB
   +0×1a4 PrefetchTrace    : _EX_FAST_REF
   +0×1a8 ReadOperationCount : _LARGE_INTEGER 0xf01d3
   +0×1b0 WriteOperationCount : _LARGE_INTEGER 0×3b08c
   +0×1b8 OtherOperationCount : _LARGE_INTEGER 0×67845
   +0×1c0 ReadTransferCount : _LARGE_INTEGER 0×9b087eec
   +0×1c8 WriteTransferCount : _LARGE_INTEGER 0×39f8a27a
   +0×1d0 OtherTransferCount : _LARGE_INTEGER 0×25dd749
   +0×1d8 CommitChargeLimit : 0
   +0×1dc CommitChargePeak : 0×394b
   +0×1e0 AweInfo          : (null)
   +0×1e4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0×1e8 Vm               : _MMSUPPORT
   +0×230 MmProcessLinks   : _LIST_ENTRY [ 0xa3af2730 - 0xa3b0a250 ]
   +0×238 ModifiedPageCount : 0xc835
   +0×23c JobStatus        : 0
   +0×240 Flags            : 0×4d0801
   +0×240 CreateReported   : 0y1
   +0×240 NoDebugInherit   : 0y0
   +0×240 ProcessExiting   : 0y0
   +0×240 ProcessDelete    : 0y0
   +0×240 Wow64SplitPages  : 0y0
   +0×240 VmDeleted        : 0y0
   +0×240 OutswapEnabled   : 0y0
   +0×240 Outswapped       : 0y0
   +0×240 ForkFailed       : 0y0
   +0×240 Wow64VaSpace4Gb  : 0y0
   +0×240 AddressSpaceInitialized : 0y10
   +0×240 SetTimerResolution : 0y0
   +0×240 BreakOnTermination : 0y0
   +0×240 SessionCreationUnderway : 0y0
   +0×240 WriteWatch       : 0y0
   +0×240 ProcessInSession : 0y1
   +0×240 OverrideAddressSpace : 0y0
   +0×240 HasAddressSpace  : 0y1
   +0×240 LaunchPrefetched : 0y1
   +0×240 InjectInpageErrors : 0y0
   +0×240 VmTopDown        : 0y0
   +0×240 ImageNotifyDone  : 0y1
   +0×240 PdeUpdateNeeded  : 0y0
   +0×240 VdmAllowed       : 0y0
   +0×240 SmapAllowed      : 0y0
   +0×240 CreateFailed     : 0y0
   +0×240 DefaultIoPriority : 0y000
   +0×240 Spare1           : 0y0
   +0×240 Spare2           : 0y0
   +0×244 ExitStatus       : 259
   +0×248 NextPageColor    : 0xf91e
   +0×24a SubSystemMinorVersion : 0 ”
   +0×24b SubSystemMajorVersion : 0×4 ”
   +0×24a SubSystemVersion : 0×400
   +0×24c PriorityClass    : 0×6 ”
   +0×250 VadRoot          : _MM_AVL_TABLE
   +0×270 Cookie           : 0×5a583219

We can also see that by default !search command finds entries differing in a single bit, for example:

Pfn      Offset   Hit      Va       Pte     
- - - - - - - - - - - - - - - - - - - - - - - - - - -
...
...
...
00011442 0000093C 53616D49 66EC293C C0337610
0001328A 000009F4 43616D49 672E59F4 C0339728


0: kd> !dc 0001328A9F4
#1328a9f4 43616d49 6f6d6d6f 64702e6e 00000062 ImaCommon.pdb...
#1328aa04 672e7170 00000000 00000000 ffffffff pq.g............
#1328aa14 00000000 00000000 672e5a04 00000000 .........Z.g....
#1328aa24 00000000 00000000 00000001 672e5a1c .............Z.g
#1328aa34 00000000 00000000 00000000 672e7170 ............pq.g
#1328aa44 672e5a24 00000000 00000000 00004c24 $Z.g........$L..
#1328aa54 00000000 00000000 00000000 00000000 ................
#1328aa64 00000000 672e7138 00000000 ffffffff ....8q.g........

In the case of kernel memory dumps physical memory search might be better alternative to virtual memory search if we need to see pool tags corresponding to search hits or search for data differing in some bits, for example:

3: kd> .ignore_missing_pages 1
Suppress kernel summary dump missing page error message

3: kd> s -d 80000000 L?20000000 53616d49
86a6eeec  53616d49 652e7672 00006578 00000000  ImaSrv.exe......

3: kd> !search 53616d49
Debuggee is a kernel summary dump, some physical pages may not be present.
Searches will miss hits from those pages.
Searching PFNs in range 00000001 - 0007FFFF for [53616D49 - 53616D49]

Pfn      Offset   Hit      Va       Pte     
- - - - - - - - - - - - - - - - - - - - - - - - - - -
00005DED 00000EEC 53616D49 86A6EEEC C021A9B8
 86a6ed68+0x184   : Proc (Protected)  -- Process objects
Search done.

- Dmitry Vostokov @ DumpAnalysis.org -

New planned book about .NET debugging

Wednesday, March 19th, 2008

This is a forthcoming book about .NET debugging seen in a wider context than .NET runtime environment (CLR). There is the whole new generation of .NET software developers, designers and architects thinking in terms of managed code and associated concepts. However CLR runs in unmanaged environment which finally interfaces with native code. Therefore understanding unmanaged and native code is vital for successful debugging of real customer problems. Preliminary information is:

  • Title: Unmanaged Code: Escaping the Matrix of .NET
  • Author: Dmitry Vostokov
  • Paperback: 512 pages (*)
  • ISBN-13: 978-0-9558328-6-4
  • Publisher: Opentask (1 Feb 2009)
  • Language: English
  • Product Dimensions: 22.86 x 15.24

(*) subject to change

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Patterns (Part 13e)

Tuesday, March 18th, 2008

I’m coming back to my old Insufficient Memory pattern range (see Committed Memory, Handle Leak, Kernel Pool, PTE). This post discusses the user space case when we don’t have enough virtual memory available for reservation due to memory fragmentation. For example, a java virtual machine is pre-allocating memory for its garbage-collected heap. However after installing some 3rd-party software the amount of pre-allocated memory is less than expected. In such cases it is possible to do comparative memory dump analysis to see the difference in virtual address spaces. Original memory dump has this module distribution in memory:

0:000> lm
start    end        module name
00400000 0040b000   javaw      (deferred)            
009e0000 009e7000   hpi        (deferred)            
00a30000 00a3e000   verify     (deferred)            
00a40000 00a59000   java       (deferred)            
00a60000 00a6d000   zip        (deferred)            
03ff0000 03fff000   net        (deferred)            
040a0000 040a8000   nio        (deferred)            
040b0000 0410a000   hnetcfg    (deferred)            
041d0000 042e2000   awt        (deferred)            
04540000 04591000   fontmanager   (deferred)            
04620000 04670000   msctf      (deferred)            
047c0000 047de000   jpeg       (deferred)            
05820000 05842000   dcpr       (deferred)            
05920000 05932000   pkcs11wrapper   (deferred)            
08000000 08139000   jvm        (deferred)            
10000000 100e0000   moduleA    (deferred)            
68000000 68035000   rsaenh     (deferred)

6e220000 6e226000   RMProcessLink   (deferred)            
71ae0000 71ae8000   wshtcpip   (deferred)            
71b20000 71b61000   mswsock    (deferred)            
71bf0000 71bf8000   ws2help    (deferred)            
71c00000 71c17000   ws2_32     (deferred)            
71c20000 71c32000   tsappcmp   (deferred)            
71c40000 71c97000   netapi32   (deferred)            
73070000 73097000   winspool   (deferred)            
76290000 762ad000   imm32      (deferred)            
76920000 769e2000   userenv    (deferred)            
76aa0000 76acd000   winmm      (deferred)            
76b70000 76b7b000   psapi      (deferred)            
76ed0000 76efa000   dnsapi     (deferred)            
76f10000 76f3e000   wldap32    (deferred)            
76f50000 76f63000   secur32    (deferred)            
76f70000 76f77000   winrnr     (deferred)            
76f80000 76f85000   rasadhlp   (deferred)            
77380000 77411000   user32     (deferred)            
77670000 777a9000   ole32      (deferred)            
77ba0000 77bfa000   msvcrt     (deferred)            
77c00000 77c48000   gdi32      (deferred)            
77c50000 77cef000   rpcrt4     (deferred)            
77e40000 77f42000   kernel32   (deferred)            
77f50000 77feb000   advapi32   (deferred)            
78130000 781cb000   msvcr80    (deferred)            
7c800000 7c8c0000   ntdll      (pdb symbols)

We see the big gap between 100e0000 and 68000000 addresses. This means that it is theoretically possible to reserve and/or commit up to 57F20000 bytes (about 1.4Gb). !address WinDbg command shows that at least 1.1Gb region (shown in bold below) was reserved indeed:

0:000> !address
00000000 : 00000000 - 00010000
              Type     00000000
              Protect  00000001 PAGE_NOACCESS
              State    00010000 MEM_FREE
              Usage    RegionUsageFree
00010000 : 00010000 - 00001000
              Type     00020000 MEM_PRIVATE
              Protect  00000004 PAGE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageEnvironmentBlock
00011000 : 00011000 - 0000f000
              Type     00000000
              Protect  00000001 PAGE_NOACCESS
              State    00010000 MEM_FREE
              Usage    RegionUsageFree
00020000 : 00020000 - 00001000
              Type     00020000 MEM_PRIVATE
              Protect  00000004 PAGE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageProcessParametrs
00021000 : 00021000 - 0000f000
              Type     00000000
              Protect  00000001 PAGE_NOACCESS
              State    00010000 MEM_FREE
              Usage    RegionUsageFree
00030000 : 00030000 - 00003000
              Type     00020000 MEM_PRIVATE
              Protect  00000140 <unk>
              State    00001000 MEM_COMMIT
              Usage    RegionUsageStack
              Pid.Tid  97c.1b3c
...
...
...
100e0000 : 100e0000 - 000a0000
              Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
         10180000 - 05cc0000
              Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD
         15e40000 - 004f3000
              Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
         16333000 - 45bad000
              Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD

         5bee0000 - 00ac0000
              Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
         5c9a0000 - 03540000
              Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD
5fee0000 : 5fee0000 - 00120000
              Type     00000000
              Protect  00000001 PAGE_NOACCESS
              State    00010000 MEM_FREE
              Usage    RegionUsageFree


Looking at the problem memory dump we see that the gap is smaller (less than 1.1Gb):

0:000> lm
start    end        module name
00400000 0040b000   javaw      (deferred)            
08000000 08139000   jvm        (deferred)            
10000000 10007000   hpi        (deferred)            
51120000 511bb000   msvcr80  # (private pdb symbols)

520f0000 520fe000   verify     (deferred)            
52100000 52119000   java       (deferred)            
52120000 5212d000   zip        (deferred)            
52130000 5213f000   net        (deferred)            
52140000 52148000   nio        (deferred)            
52150000 52262000   awt        (deferred)            
52270000 522c1000   fontmanager   (deferred)            
522d0000 52320000   MSCTF      (deferred)            
52330000 5234e000   jpeg       (deferred)            
52350000 52372000   dcpr       (deferred)            
52510000 52522000   pkcs11wrapper   (deferred)            
5f270000 5f2ca000   hnetcfg    (deferred)            
60000000 60029000   3rdPartyHook   (deferred)            
61e80000 61e86000   detoured   (export symbols)
68000000 68035000   rsaenh     (deferred)            
71ae0000 71ae8000   wshtcpip   (deferred)            
71b20000 71b61000   mswsock    (deferred)            
71bf0000 71bf8000   ws2help    (deferred)            
71c00000 71c17000   ws2_32     (deferred)            
71c20000 71c32000   tsappcmp   (deferred)            
71c40000 71c97000   netapi32   (deferred)            
73070000 73097000   winspool   (deferred)            
76290000 762ad000   imm32      (deferred)            
76920000 769e2000   userenv    (deferred)            
76aa0000 76acd000   winmm      (deferred)            
76b70000 76b7b000   psapi      (deferred)            
76ed0000 76efa000   dnsapi     (deferred)            
76f10000 76f3e000   wldap32    (deferred)            
76f50000 76f63000   secur32    (deferred)            
76f70000 76f77000   winrnr     (deferred)            
76f80000 76f85000   rasadhlp   (deferred)            
77380000 77411000   user32     (pdb symbols)         
77670000 777a9000   ole32      (deferred)            
77ba0000 77bfa000   msvcrt     (deferred)            
77c00000 77c48000   gdi32      (deferred)            
77c50000 77cef000   rpcrt4     (deferred)            
77e40000 77f42000   kernel32   (pdb symbols)         
77f50000 77feb000   advapi32   (pdb symbols)         
7c340000 7c396000   msvcr71    (deferred)            
7c800000 7c8c0000   ntdll      (pdb symbols)

!address command shows that less memory was reserved in the latter case (about 896Mb):

0:000> !address
...
...
...
10010000 : 10010000 - 000a0000
             Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
         100b0000 - 04a70000
              Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD
         14b20000 - 004a6000
              Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
         14fc6000 - 3804a000
             Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD

          4d010000 - 00ac0000
              Type     00020000 MEM_PRIVATE
              Protect  00000040 PAGE_EXECUTE_READWRITE
              State    00001000 MEM_COMMIT
              Usage    RegionUsageIsVAD
          4dad0000 - 03540000
              Type     00020000 MEM_PRIVATE
              State    00002000 MEM_RESERVE
              Usage    RegionUsageIsVAD
51010000 : 51010000 - 00110000
              Type     00000000
              Protect  00000001 PAGE_NOACCESS
              State    00010000 MEM_FREE
              Usage    RegionUsageFree


Looking at module list again we notice that most java runtime modules were shifted to 50000000 address range. We also notice that new 3rdPartyHook and detoured modules appear in our problem memory dump. 

Module information is missing for detoured module:

0:000> lmv m detoured
start    end        module name
61e80000 61e86000   detoured   (deferred)            
    Image path: C:\WINDOWS\system32\detoured.dll
    Image name: detoured.dll
    Timestamp:        Thu Feb 07 04:14:16 2008 (47AA8598)
    CheckSum:         0000EF91
    ImageSize:        00006000
    File version:     0.0.0.0
    Product version:  0.0.0.0
    File flags:       0 (Mask 0)
    File OS:          0 Unknown Base
    File type:        0.0 Unknown
    File date:        00000000.00000000
    Translations:     0000.04b0 0000.04e0 0409.04b0 0409.04e0

However applying Unknown Component pattern we see that is Microsoft Research Detours Package:

0:000> db 61e80000 61e86000
61e80000  MZ..............
61e80010  ........@.......
61e80020  ................
61e80030  ................
61e80040  ........!..L.!Th
61e80050  is program canno
61e80060  t be run in DOS
61e80070  mode....$.......
61e80080  5...q...q...q...
61e80090  ....r...q...p...
61e800a0  V%..p...V%..p...
61e800b0  V%..p...V%..p...
61e800c0  Richq...........
61e800d0  ................
61e800e0  PE..L......G....
61e800f0  .......!........
61e80100  ................
...
...
...
...
61e84390  ..P.r.o.d.u.c.t.
61e843a0  N.a.m.e…..M.i.
61e843b0  c.r.o.s.o.f.t. .
61e843c0  R.e.s.e.a.r.c.h.
61e843d0  .D.e.t.o.u.r.s.
61e843e0  .P.a.c.k.a.g.e.

61e843f0  ….j.#…P.r.o.
61e84400  d.u.c.t.V.e.r.s.
61e84410  i.o.n…P.r.o.f.
61e84420  e.s.s.i.o.n.a.l.
61e84430  .V.e.r.s.i.o.n.
61e84440  .2…1. .B.u.i.
61e84450  l.d._.2.1.0…..
61e84460  D…..V.a.r.F.i.


0:000> du 61e843a0+C
61e843ac  "Microsoft Research Detours Packa"
61e843ec  "ge"

We can also see that 3rdPartyHook module imports this library and lots of kernel32 API related to memory allocation, file mapping and loading DLLs (see No Component Symbols pattern):

0:000> !dh 60000000
...
...
...
OPTIONAL HEADER VALUES
     10B magic #
    8.00 linker version
   18000 size of code
    F000 size of initialized data
       0 size of uninitialized data
   13336 address of entry point
    1000 base of code
         ----- new -----
60000000 image base
    1000 section alignment
    1000 file alignment
       2 subsystem (Windows GUI)
    4.00 operating system version
    0.00 image version
    4.00 subsystem version
   29000 size of image
    1000 size of headers
   3376F checksum
00100000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
       0 [       0] address [size] of Export Directory
   218CC [      8C] address [size] of Import Directory
   25000 [     5F4] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
   28000 [    19E0] address [size] of Security Directory
   26000 [    2670] address [size] of Base Relocation Directory
   19320 [      1C] address [size] of Debug Directory
       0 [       0] address [size] of Description Directory
       0 [       0] address [size] of Special Directory
       0 [       0] address [size] of Thread Storage Directory
   1F3C0 [      40] address [size] of Load Configuration Directory
       0 [       0] address [size] of Bound Import Directory
   19000 [     2B0] address [size] of Import Address Table Directory
       0 [       0] address [size] of Delay Import Directory
       0 [       0] address [size] of COR20 Header Directory
       0 [       0] address [size] of Reserved Directory


0:000> dds 60000000+19000 60000000+19000+2B0
60019064  7c82b0dc ntdll!RtlReAllocateHeap
60019068  77e4ec39 kernel32!HeapDestroy
6001906c  77e41fba kernel32!GetSystemTimeAsFileTime
60019070  77e619d1 kernel32!GetTickCount
60019074  77e69577 kernel32!QueryPerformanceCounter
60019078  7c82a9be ntdll!RtlSizeHeap
6001907c  77e82060 kernel32!SetUnhandledExceptionFilter
60019080  77e7690d kernel32!UnhandledExceptionFilter
60019084  77e42004 kernel32!TerminateProcess
60019088  7c82a136 ntdll!RtlRestoreLastWin32Error
6001908c  77e77a5f kernel32!SuspendThread
60019090  77e76a26 kernel32!SetThreadContext
60019094  77e77ae3 kernel32!GetThreadContext
60019098  77e73347 kernel32!FlushInstructionCache
6001909c  77e5f38b kernel32!ResumeThread
600190a0  77e616a8 kernel32!InterlockedCompareExchange
600190a4  77e645a9 kernel32!VirtualAlloc
600190a8  77e41fe3 kernel32!VirtualProtect
600190ac  77e66ed1 kernel32!VirtualQuery
600190b0  77e44960 kernel32!GetLogicalDriveStringsA
600190b4  77eab401 kernel32!GetVolumeNameForVolumeMountPointA
600190b8  77e6794d kernel32!GetACP
600190bc  77e6f3cf kernel32!GetLocaleInfoA
600190c0  77e622b7 kernel32!GetThreadLocale
600190c4  77e69d74 kernel32!GetVersionExA
600190c8  77e4beab kernel32!RaiseException
600190cc  77e60037 kernel32!GetSystemDirectoryA
600190d0  77e52bf4 kernel32!GetWindowsDirectoryA
600190d4  77e5c7a8 kernel32!lstrcmpA
600190d8  77e46c99 kernel32!OutputDebugStringA
600190dc  77e5bd7d kernel32!CreateEventA
600190e0  77e62311 kernel32!SetEvent
600190e4  77e51281 kernel32!ExpandEnvironmentStringsA
600190e8  77e9f365 kernel32!MoveFileA
600190ec  77e5da00 kernel32!IsDebuggerPresent
600190f0  77e9e4b1 kernel32!QueryDosDeviceA
600190f4  7c829e08 ntdll!RtlGetLastWin32Error
600190f8  77e63d7a kernel32!GetProcAddress
600190fc  77e41dc6 kernel32!LoadLibraryA
60019100  7c829e17 ntdll!RtlFreeHeap
60019104  77e62419 kernel32!LocalFree
60019108  7c829fd6 ntdll!RtlAllocateHeap
6001910c  77e63ec7 kernel32!GetProcessHeap
60019110  77ea2186 kernel32!VerifyVersionInfoA
60019114  7c81379f ntdll!VerSetConditionMask
60019118  77e63143 kernel32!WideCharToMultiByte
6001911c  77e70550 kernel32!SizeofResource
60019120  77e6b11b kernel32!SetHandleCount
60019124  77e69bf9 kernel32!LoadResource
60019128  77e511e1 kernel32!FindResourceA
6001912c  77e7388c kernel32!FindResourceExA
60019130  77e5be30 kernel32!lstrlenA
60019134  77e424de kernel32!Sleep
60019138  77ea2cb1 kernel32!WaitNamedPipeA
6001913c  77e63e6f kernel32!CloseHandle
60019140  77e5e123 kernel32!OpenEventA
60019144  77e622c9 kernel32!lstrlenW
60019148  77e62fc7 kernel32!GetCurrentThreadId
6001914c  77e5fdd4 kernel32!OpenProcess
60019150  77e63c78 kernel32!GetCurrentProcessId
60019154  7c81a3ab ntdll!RtlLeaveCriticalSection
60019158  7c81a360 ntdll!RtlEnterCriticalSection
6001915c  77e4cabf kernel32!GetComputerNameA
60019160  77e6f032 kernel32!ProcessIdToSessionId
60019164  77e645ff kernel32!GetModuleFileNameA
60019168  77e6474a kernel32!GetModuleHandleA
6001916c  77e62f9d kernel32!GetCurrentProcess
60019170  77e49968 kernel32!GetCurrentDirectoryA
60019174  77e61c7b kernel32!WaitForSingleObject
60019178  77e63868 kernel32!GetCurrentThread
6001917c  7c82c988 ntdll!RtlDeleteCriticalSection
60019180  77e67861 kernel32!InitializeCriticalSection
60019184  77e6b1a1 kernel32!FreeLibrary
60019188  77e63f41 kernel32!UnmapViewOfFile
6001918c  77e643f1 kernel32!MapViewOfFile
60019190  77e6b65f kernel32!OpenFileMappingA
60019194  77e61694 kernel32!InterlockedExchange
60019198  77e4d2fb kernel32!DeleteFileA
...
...
...
60019294  00000000
60019298  61e81000 detoured!Detoured
6001929c  00000000


This warrants the suspicion that 3rdPartyHook somehow optimized the virtual address space for its own purposes and this resulted in more fragmented virtual address space.

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Patterns (Part 2b)

Thursday, March 13th, 2008

Here is an additional kernel space example to my old Dynamic Memory Corruption pattern. If kernel pools are corrupt then calls that allocate or free memory result in bugchecks C2 or 19 and in other less frequent bugchecks (from Google stats):

BugCheck C2: BAD_POOL_CALLER

1600

BugCheck 19: BAD_POOL_HEADER

434

BugCheck C5: DRIVER_CORRUPTED_EXPOOL

207

BugCheck DE: POOL_CORRUPTION_IN_FILE_AREA

106

BugCheck D0: DRIVER_CORRUPTED_MMPOOL

8

BugCheck D6: DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION

3

BugCheck CD: PAGE_FAULT_BEYOND_END_OF_ALLOCATION

2

BugCheck C6: DRIVER_CAUGHT_MODIFYING_FREED_POOL

0

Bug Checks 0xC2 and 0×19 have parameters in bugcheck arguments that tell the type of detected pool corruption. Refer to WinDbg help for details or use the variant of !analyze command where you can supply optional bugcheck arguments:

1: kd> !analyze -show c2
BAD_POOL_CALLER (c2)
The current thread is making a bad pool request.  Typically this is at a bad IRQL level or double freeing the same allocation, etc.
Arguments:
Arg1: 00000000, The caller is requesting a zero byte pool allocation.
Arg2: 00000000, zero.
Arg3: 00000000, the pool type being allocated.
Arg4: 00000000, the pool tag being used.

1: kd> !analyze -show 19 2 1 1 1
BAD_POOL_HEADER (19)
The pool is already corrupt at the time of the current request.
This may or may not be due to the caller.
The internal pool links must be walked to figure out a possible cause of
the problem, and then special pool applied to the suspect tags or the driver
verifier to a suspect driver.
Arguments:
Arg1: 00000002, the verifier pool pattern check failed.  The owner has likely corrupted the pool block
Arg2: 00000001, the pool entry being checked.
Arg3: 00000001, size of the block.
Arg4: 00000001, 0.

If we enable special pool on suspected drivers we might get these bugchecks too with the following Google frequency:

BugCheck C1: SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION

59

BugCheck D5: DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL

5

BugCheck CC: PAGE_FAULT_IN_FREED_SPECIAL_POOL

1

Here is one example of nonpaged pool corruption detected during free operation with the following !analyze -v output:

BAD_POOL_HEADER (19)
The pool is already corrupt at the time of the current request.
This may or may not be due to the caller.
The internal pool links must be walked to figure out a possible cause of
the problem, and then special pool applied to the suspect tags or the driver
verifier to a suspect driver.
Arguments:
Arg1: 00000020, a pool block header size is corrupt.
Arg2: a34583b8, The pool entry we were looking for within the page.
Arg3: a34584f0, The next pool entry.
Arg4: 0a270001, (reserved)

POOL_ADDRESS:  a34583b8 Nonpaged pool

PROCESS_NAME:  process.exe

CURRENT_IRQL:  2

STACK_TEXT: 
b80a60cc 808927bb nt!KeBugCheckEx+0x1b
b80a6134 80892b6f nt!ExFreePoolWithTag+0x477
b80a6144 b9591400 nt!ExFreePool+0xf
WARNING: Stack unwind information not available. Following frames may be wrong.
b80a615c b957b954 driver+0x38400
b80a617c b957d482 driver+0x22954
b80a61c0 b957abf4 driver+0x24482
b80a6260 b957ccef driver+0x21bf4
b80a62a8 8081df65 driver+0x23cef
b80a62bc f721ac45 nt!IofCallDriver+0x45
b80a62e4 8081df65 fltMgr!FltpDispatch+0x6f
b80a62f8 b99de70b nt!IofCallDriver+0x45
b80a6308 b99da6ee filter!Dispatch+0xfb
b80a6318 8081df65 filter!dispatch+0x6e
b80a632c b9bdebfe nt!IofCallDriver+0x45
b80a6334 8081df65 2ndfilter!Redirect+0x7ea
b80a6348 b9bd1756 nt!IofCallDriver+0x45
b80a6374 b9bd1860 3rdfilter!PassThrough+0x136
b80a6384 8081df65 3rdfilter!Dispatch+0x80
b80a6398 808f5437 nt!IofCallDriver+0x45
b80a63ac 808ef963 nt!IopSynchronousServiceTail+0x10b
b80a63d0 8088978c nt!NtQueryDirectoryFile+0x5d
b80a63d0 7c8285ec nt!KiFastCallEntry+0xfc
00139524 7c8274eb ntdll!KiFastSystemCallRet
00139528 77e6ba40 ntdll!NtQueryDirectoryFile+0xc
00139830 77e6bb5f kernel32!FindFirstFileExW+0x3d5
00139850 6002665e kernel32!FindFirstFileW+0x16
00139e74 60026363 process+0x2665e
0013a328 60027852 process+0x26363
0013a33c 60035b58 process+0x27852
0013b104 600385ff process+0x35b58
0013b224 612cb643 process+0x385ff
0013b988 612cc109 dll!FileDialog+0xc53
0013bba0 612cb47b dll!FileDialog+0x1719
0013c2c0 7739b6e3 dll!FileDialog+0xa8b
0013c2ec 77395f82 USER32!InternalCallWinProc+0x28
0013c368 77395e22 USER32!UserCallDlgProcCheckWow+0x147
0013c3b0 7739c9c6 USER32!DefDlgProcWorker+0xa8
0013c3d8 7c828536 USER32!__fnDWORD+0x24
0013c3d8 808308f4 ntdll!KiUserCallbackDispatcher+0x2e
b80a66b8 8091d6d1 nt!KiCallUserMode+0x4
b80a6710 bf8a2622 nt!KeUserModeCallback+0x8f
b80a6794 bf8a2517 win32k!SfnDWORD+0xb4
b80a67dc bf8a13d9 win32k!xxxSendMessageToClient+0x133
b80a6828 bf85ae67 win32k!xxxSendMessageTimeout+0x1a6
b80a684c bf8847a1 win32k!xxxWrapSendMessage+0x1b
b80a6868 bf8c1459 win32k!NtUserfnNCDESTROY+0x27
b80a68a0 8088978c win32k!NtUserMessageCall+0xc0
b80a68a0 7c8285ec nt!KiFastCallEntry+0xfc
0013c3d8 7c828536 ntdll!KiFastSystemCallRet
0013c3d8 808308f4 ntdll!KiUserCallbackDispatcher+0x2e
b80a6b7c 8091d6d1 nt!KiCallUserMode+0x4
b80a6bd4 bf8a2622 nt!KeUserModeCallback+0x8f
b80a6c58 bf8a23a0 win32k!SfnDWORD+0xb4
b80a6ca0 bf8a13d9 win32k!xxxSendMessageToClient+0x118
b80a6cec bf85ae67 win32k!xxxSendMessageTimeout+0x1a6
b80a6d10 bf8c148c win32k!xxxWrapSendMessage+0x1b
b80a6d40 8088978c win32k!NtUserMessageCall+0x9d
b80a6d40 7c8285ec nt!KiFastCallEntry+0xfc
0013f474 7c828536 ntdll!KiFastSystemCallRet
0013f4a0 7739d1ec ntdll!KiUserCallbackDispatcher+0x2e
0013f4dc 7738cf29 USER32!NtUserMessageCall+0xc
0013f4fc 612d3276 USER32!SendMessageA+0x7f
0013f63c 611add41 dll!SubWindow+0x3dc6
0013f658 7739b6e3 dll!SetWindowText+0x37a1
0013f684 7739b874 USER32!InternalCallWinProc+0x28
0013f6fc 7739ba92 USER32!UserCallWinProcCheckWow+0x151
0013f764 7739bad0 USER32!DispatchMessageWorker+0x327
0013f774 61221ca8 USER32!DispatchMessageW+0xf
0013f7e0 0040156d dll!MainLoop+0x2c8
0013ff24 00401dfa process+0x156d
0013ffc0 77e6f23b process+0x1dfa
0013fff0 00000000 kernel32!BaseProcessStart+0x23

MODULE_NAME: driver

IMAGE_NAME:  driver.sys

We see that WinDbg pointed to driver.sys by using a procedure described in one of my old minidump analysis posts: BugCheck C2 Minidump Analysis

However any OS component could corrupt the pool prior to detection as the bugcheck description says: “The pool is already corrupt at the time of the current request.”. What other evidence can reinforce our belief in driver.sys? Let’s look at our pool entry tag first:

1: kd> !pool a34583b8
Pool page a34583b8 region is Nonpaged pool
 a3458000 size:  270 previous size:    0  (Allocated)  Thre (Protected)
 a3458270 size:   10 previous size:  270  (Free)       RxIr
 a3458280 size:   40 previous size:   10  (Allocated)  Vadl
 a34582c0 size:   98 previous size:   40  (Allocated)  File (Protected)
 a3458358 size:    8 previous size:   98  (Free)       Vadl
 a3458360 size:   50 previous size:    8  (Allocated)  Gsem
 a34583b0 size:    8 previous size:   50  (Free)       CcSc
*a34583b8 size:  138 previous size:    8  (Allocated) *DRIV
  Owning component : Unknown (update pooltag.txt)
a34584f0 is not a valid large pool allocation, checking large session pool…
a34584f0 is freed (or corrupt) pool
Bad allocation size @a34584f0, zero is invalid

***
*** An error (or corruption) in the pool was detected;
*** Attempting to diagnose the problem.
***
*** Use !poolval a3458000 for more details.
***

Pool page [ a3458000 ] is __inVALID.

Analyzing linked list...
[ a34583b8 --> a34583d8 (size = 0x20 bytes)]: Corrupt region
[ a34583f8 --> a34585e8 (size = 0x1f0 bytes)]: Corrupt region

Scanning for single bit errors...

None found

We see that the tag is DRIV and we know either from association or from similar problems in the past that it belongs to driver.sys. Let’s dump our pool entry contents to see if there are any symbolic hints in it:

1: kd> dps a34583b8
a34583b8 0a270001
a34583bc 5346574e
a34583c0 00000000
a34583c4 00000000
a34583c8 b958f532 driver+0×36532
a34583cc a3471010
a34583d0 0000012e
a34583d4 00000001
a34583d8 00041457
a34583dc 05af0026
a34583e0 00068002
a34583e4 7b9ec6f5
a34583e8 ffffff00
a34583ec 73650cff
a34583f0 7461445c
a34583f4 97a10061
a34583f8 ff340004
a34583fc c437862a
a3458400 6a000394
a3458404 00000038
a3458408 00000000
a345840c bf000000
a3458410 bf0741b5
a3458414 f70741b5
a3458418 00000000
a345841c 00000000
a3458420 00000000
a3458424 00000000
a3458428 05000000
a345842c 34303220
a3458430 31323332
a3458434 ff322d36

Indeed we see the possible code pointer driver+0×36532 and the code around this address looks normal:

3: kd> .asm no_code_bytes
Assembly options: no_code_bytes

3: kd> u b958f532
driver+0x36532:
b958f532 push    2Ch
b958f534 push    offset driver+0x68d08 (b95c1d08)
b958f539 call    driver+0x65c50 (b95bec50)
b958f53e mov     byte ptr [ebp-19h],0
b958f542 and     dword ptr [ebp-24h],0
b958f546 call    dword ptr [driver+0x65f5c (b95bef5c)]
b958f54c mov     ecx,dword ptr [ebp+0Ch]
b958f54f cmp     eax,ecx

3: kd> ub b958f532
driver+0x36528:
b958f528 leave
b958f529 ret     18h
b958f52c int     3
b958f52d int     3
b958f52e int     3
b958f52f int     3
b958f530 int     3
b958f531 int     3

- Dmitry Vostokov @ DumpAnalysis.org -

Bug Check Frequencies

Wednesday, March 12th, 2008

259 bugchecks are documented in WinDbg help. I did Google search for every one and here is their search results distribution graph cut off for data with less than 10 matches:

Of course there is some noise and matches do not always correspond to WinDbg bugcheck analysis output but we can get rough idea about bugcheck frequency. For example, unhandled exceptions in kernel mode, IRQL contract violation, pool corruption and hardware failures are the most frequent. Here is the full table:

BugCheck 1000008E: KERNEL_MODE_EXCEPTION_NOT_HANDLED_M

3440

BugCheck A: IRQL_NOT_LESS_OR_EQUAL

2890

BugCheck D1: DRIVER_IRQL_NOT_LESS_OR_EQUAL

2840

BugCheck 50: PAGE_FAULT_IN_NONPAGED_AREA

2040

BugCheck C2: BAD_POOL_CALLER

1600

BugCheck 9C: MACHINE_CHECK_EXCEPTION

1150

BugCheck 1000007F: UNEXPECTED_KERNEL_MODE_TRAP_M

1070

BugCheck 7E: SYSTEM_THREAD_EXCEPTION_NOT_HANDLED

998

BugCheck 1000007E: SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M

917

BugCheck 7F: UNEXPECTED_KERNEL_MODE_TRAP

834

BugCheck 4E: PFN_LIST_CORRUPT

799

BugCheck 24: NTFS_FILE_SYSTEM

697

BugCheck 8E: KERNEL_MODE_EXCEPTION_NOT_HANDLED

686

BugCheck 1E: KMODE_EXCEPTION_NOT_HANDLED

571

BugCheck 100000EA: THREAD_STUCK_IN_DEVICE_DRIVER_M

450

BugCheck EA: THREAD_STUCK_IN_DEVICE_DRIVER

446

BugCheck 19: BAD_POOL_HEADER

434

BugCheck F4: CRITICAL_OBJECT_TERMINATION

397

BugCheck 1A: MEMORY_MANAGEMENT

373

BugCheck C4: DRIVER_VERIFIER_DETECTED_VIOLATION

360

BugCheck 7B: INACCESSIBLE_BOOT_DEVICE

347

BugCheck 1: APC_INDEX_MISMATCH

242

BugCheck 77: KERNEL_STACK_INPAGE_ERROR

240

BugCheck FE: BUGCODE_USB_DRIVER

239

BugCheck 44: MULTIPLE_IRP_COMPLETE_REQUESTS

216

BugCheck C5: DRIVER_CORRUPTED_EXPOOL

207

BugCheck 124: WHEA_UNCORRECTABLE_ERROR

204

BugCheck C000021A: STATUS_SYSTEM_PROCESS_TERMINATED

187

BugCheck 20: KERNEL_APC_PENDING_DURING_EXIT

168

BugCheck B8: ATTEMPTED_SWITCH_FROM_DPC

124

BugCheck 5: INVALID_PROCESS_ATTACH_ATTEMPT

123

BugCheck C: MAXIMUM_WAIT_OBJECTS_EXCEEDED

110

BugCheck 7A: KERNEL_DATA_INPAGE_ERROR

110

BugCheck DE: POOL_CORRUPTION_IN_FILE_AREA

106

BugCheck A0: INTERNAL_POWER_ERROR

104

BugCheck FC: ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY

101

BugCheck 9F: DRIVER_POWER_STATE_FAILURE

98

BugCheck E2: MANUALLY_INITIATED_CRASH

98

BugCheck 2: DEVICE_QUEUE_NOT_BUSY

97

BugCheck AB: SESSION_HAS_VALID_POOL_ON_EXIT

86

BugCheck 93: INVALID_KERNEL_HANDLE

83

BugCheck 51: REGISTRY_ERROR

73

BugCheck 3: INVALID_AFFINITY_SET

71

BugCheck 35: NO_MORE_IRP_STACK_LOCATIONS

71

BugCheck 3B: SYSTEM_SERVICE_EXCEPTION

70

BugCheck CE: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS

65

BugCheck C1: SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION

59

BugCheck E3: RESOURCE_NOT_OWNED

43

BugCheck 109: CRITICAL_STRUCTURE_CORRUPTION

33

BugCheck E: NO_USER_MODE_CONTEXT

32

BugCheck D: MUTEX_LEVEL_NUMBER_VIOLATION

23

BugCheck 12: TRAP_CAUSE_UNKNOWN

14

BugCheck 23: FAT_FILE_SYSTEM

10

BugCheck 116: VIDEO_TDR_ERROR

10

BugCheck 9: IRQL_NOT_GREATER_OR_EQUAL

9

BugCheck 10D: WDF_VIOLATION

9

BugCheck 4: INVALID_DATA_ACCESS_TRAP

8

BugCheck 6: INVALID_PROCESS_DETACH_ATTEMPT

8

BugCheck 3F: NO_MORE_SYSTEM_PTES

8

BugCheck C9: DRIVER_VERIFIER_IOMANAGER_VIOLATION

8

BugCheck D0: DRIVER_CORRUPTED_MMPOOL

8

BugCheck 117: VIDEO_TDR_TIMEOUT_DETECTED

8

BugCheck F: SPIN_LOCK_ALREADY_OWNED

7

BugCheck 11: THREAD_NOT_MUTEX_OWNER

6

BugCheck 6B: PROCESS1_INITIALIZATION_FAILED

6

BugCheck BE: ATTEMPTED_WRITE_TO_READONLY_MEMORY

6

BugCheck B: NO_EXCEPTION_HANDLING_SUPPORT

5

BugCheck 27: RDR_FILE_SYSTEM

5

BugCheck 41: MUST_SUCCEED_POOL_EMPTY

5

BugCheck 96: INVALID_WORK_QUEUE_ITEM

5

BugCheck D5: DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL

5

BugCheck DA: SYSTEM_PTE_MISUSE

5

BugCheck E1: WORKER_THREAD_RETURNED_AT_BAD_IRQL

5

BugCheck E6: DRIVER_VERIFIER_DMA_VIOLATION

5

BugCheck 10E: VIDEO_MEMORY_MANAGEMENT_INTERNAL

5

BugCheck 8: IRQL_NOT_DISPATCH_LEVEL

4

BugCheck 18: REFERENCE_BY_POINTER

4

BugCheck 34: CACHE_MANAGER

4

BugCheck 76: PROCESS_HAS_LOCKED_PAGES

4

BugCheck CA: PNP_DETECTED_FATAL_ERROR

4

BugCheck CB: DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS

4

BugCheck D2: BUGCODE_ID_DRIVER

4

BugCheck D4: SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD

4

BugCheck D9: LOCKED_PAGES_TRACKER_CORRUPTION

4

BugCheck F7: DRIVER_OVERRAN_STACK_BUFFER

4

BugCheck 101: CLOCK_WATCHDOG_TIMEOUT

4

BugCheck C0000218: STATUS_CANNOT_LOAD_REGISTRY_FILE

4

BugCheck 7: INVALID_SOFTWARE_INTERRUPT

3

BugCheck 13: EMPTY_THREAD_REAPER_LIST

3

BugCheck 14: CREATE_DELETE_LOCK_NOT_LOCKED

3

BugCheck 22: FILE_SYSTEM

3

BugCheck 29: SECURITY_SYSTEM

3

BugCheck 39: SYSTEM_EXIT_OWNED_MUTEX

3

BugCheck 46: DEREF_UNKNOWN_LOGON_SESSION

3

BugCheck 4D: NO_PAGES_AVAILABLE

3

BugCheck 9E: USER_MODE_HEALTH_MONITOR

3

BugCheck BA: SESSION_HAS_VALID_VIEWS_ON_EXIT

3

BugCheck D3: DRIVER_PORTION_MUST_BE_NONPAGED

3

BugCheck D6: DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION

3

BugCheck E7: INVALID_FLOATING_POINT_STATE

3

BugCheck 100: LOADER_BLOCK_MISMATCH

3

BugCheck 106: AGP_ILLEGALLY_REPROGRAMMED

3

BugCheck DEADDEAD: MANUALLY_INITIATED_CRASH1

3

BugCheck 10: SPIN_LOCK_NOT_OWNED

2

BugCheck 21: QUOTA_UNDERFLOW

2

BugCheck 26: CDFS_FILE_SYSTEM

2

BugCheck 30: SET_OF_INVALID_CONTEXT

2

BugCheck 33: UNEXPECTED_INITIALIZATION_CALL

2

BugCheck 36: DEVICE_REFERENCE_COUNT_NOT_ZERO

2

BugCheck 37: FLOPPY_INTERNAL_ERROR

2

BugCheck 40: TARGET_MDL_TOO_SMALL

2

BugCheck 42: ATDISK_DRIVER_INTERNAL

2

BugCheck 4A: IRQL_GT_ZERO_AT_SYSTEM_SERVICE

2

BugCheck 72: ASSIGN_DRIVE_LETTERS_FAILED

2

BugCheck 73: CONFIG_LIST_FAILED

2

BugCheck CD: PAGE_FAULT_BEYOND_END_OF_ALLOCATION

2

BugCheck CF: TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE

2

BugCheck E4: WORKER_INVALID

2

BugCheck 104: AGP_INVALID_ACCESS

2

BugCheck 15: LAST_CHANCE_CALLED_FROM_KMODE

1

BugCheck 16: CID_HANDLE_CREATION

1

BugCheck 17: CID_HANDLE_DELETION

1

BugCheck 28: CORRUPT_ACCESS_TOKEN

1

BugCheck 38: SERIAL_DRIVER_INTERNAL

1

BugCheck 43: NO_SUCH_PARTITION

1

BugCheck 45: INSUFFICIENT_SYSTEM_MAP_REGS

1

BugCheck 48: CANCEL_STATE_IN_COMPLETED_IRP

1

BugCheck 49: PAGE_FAULT_WITH_INTERRUPTS_OFF

1

BugCheck 57: XNS_INTERNAL_ERROR

1

BugCheck 58: FTDISK_INTERNAL_ERROR

1

BugCheck 5C: HAL_INITIALIZATION_FAILED

1

BugCheck 60: PROCESS_INITIALIZATION_FAILED

1

BugCheck 62: OBJECT1_INITIALIZATION_FAILED

1

BugCheck 63: SECURITY1_INITIALIZATION_FAILED

1

BugCheck 64: SYMBOLIC_INITIALIZATION_FAILED

1

BugCheck 67: CONFIG_INITIALIZATION_FAILED

1

BugCheck 68: FILE_INITIALIZATION_FAILED

1

BugCheck 70: SESSION4_INITIALIZATION_FAILED

1

BugCheck 74: BAD_SYSTEM_CONFIG_INFO

1

BugCheck 75: CANNOT_WRITE_CONFIGURATION

1

BugCheck 79: MISMATCHED_HAL

1

BugCheck 7D: INSTALL_MORE_MEMORY

1

BugCheck 80: NMI_HARDWARE_FAILURE

1

BugCheck 82: DFS_FILE_SYSTEM

1

BugCheck 85: SETUP_FAILURE

1

BugCheck 99: INVALID_REGION_OR_SEGMENT

1

BugCheck A1: PCI_BUS_DRIVER_INTERNAL

1

BugCheck BF: MUTEX_ALREADY_OWNED

1

BugCheck CC: PAGE_FAULT_IN_FREED_SPECIAL_POOL

1

BugCheck DB: DRIVER_CORRUPTED_SYSPTES

1

BugCheck E8: INVALID_CANCEL_OF_FILE_OPEN

1

BugCheck ED: UNMOUNTABLE_BOOT_VOLUME

1

BugCheck FD: DIRTY_NOWRITE_PAGES_CONGESTION

1

BugCheck 108: THIRD_PARTY_FILE_SYSTEM_FAILURE

1

BugCheck 111: RECURSIVE_NMI

1

BugCheck 121: DRIVER_VIOLATION

1

BugCheck 122: WHEA_INTERNAL_ERROR

1

BugCheck 1B: PFN_SHARE_COUNT

0

BugCheck 1C: PFN_REFERENCE_COUNT

0

BugCheck 1D: NO_SPIN_LOCK_AVAILABLE

0

BugCheck 1F: SHARED_RESOURCE_CONV_ERROR

0

BugCheck 25: NPFS_FILE_SYSTEM

0

BugCheck 2A: INCONSISTENT_IRP

0

BugCheck 2B: PANIC_STACK_SWITCH

0

BugCheck 2C: PORT_DRIVER_INTERNAL

0

BugCheck 2D: SCSI_DISK_DRIVER_INTERNAL

0

BugCheck 2E: DATA_BUS_ERROR

0

BugCheck 2F: INSTRUCTION_BUS_ERROR

0

BugCheck 31: PHASE0_INITIALIZATION_FAILED

0

BugCheck 32: PHASE1_INITIALIZATION_FAILED

0

BugCheck 3A: SYSTEM_UNWIND_PREVIOUS_USER

0

BugCheck 3C: INTERRUPT_UNWIND_ATTEMPTED

0

BugCheck 3D: INTERRUPT_EXCEPTION_NOT_HANDLED

0

BugCheck 3E: MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED

0

BugCheck 47: REF_UNKNOWN_LOGON_SESSION

0

BugCheck 4B: STREAMS_INTERNAL_ERROR

0

BugCheck 4C: FATAL_UNHANDLED_HARD_ERROR

0

BugCheck 4F: NDIS_INTERNAL_ERROR

0

BugCheck 52: MAILSLOT_FILE_SYSTEM

0

BugCheck 53: NO_BOOT_DEVICE

0

BugCheck 54: LM_SERVER_INTERNAL_ERROR

0

BugCheck 55: DATA_COHERENCY_EXCEPTION

0

BugCheck 56: INSTRUCTION_COHERENCY_EXCEPTION

0

BugCheck 59: PINBALL_FILE_SYSTEM

0

BugCheck 5A: CRITICAL_SERVICE_FAILED

0

BugCheck 5B: SET_ENV_VAR_FAILED

0

BugCheck 5D: UNSUPPORTED_PROCESSOR

0

BugCheck 5E: OBJECT_INITIALIZATION_FAILED

0

BugCheck 5F: SECURITY_INITIALIZATION_FAILED

0

BugCheck 61: HAL1_INITIALIZATION_FAILED

0

BugCheck 65: MEMORY1_INITIALIZATION_FAILED

0

BugCheck 66: CACHE_INITIALIZATION_FAILED

0

BugCheck 69: IO1_INITIALIZATION_FAILED

0

BugCheck 6A: LPC_INITIALIZATION_FAILED

0

BugCheck 6C: REFMON_INITIALIZATION_FAILED

0

BugCheck 6D: SESSION1_INITIALIZATION_FAILED

0

BugCheck 6E: SESSION2_INITIALIZATION_FAILED

0

BugCheck 6F: SESSION3_INITIALIZATION_FAILED

0

BugCheck 71: SESSION5_INITIALIZATION_FAILED

0

BugCheck 78: PHASE0_EXCEPTION

0

BugCheck 7C: BUGCODE_NDIS_DRIVER

0

BugCheck 81: SPIN_LOCK_INIT_FAILURE

0

BugCheck 8B: MBR_CHECKSUM_MISMATCH

0

BugCheck 8F: PP0_INITIALIZATION_FAILED

0

BugCheck 90: PP1_INITIALIZATION_FAILED

0

BugCheck 92: UP_DRIVER_ON_MP_SYSTEM

0

BugCheck 94: KERNEL_STACK_LOCKED_AT_EXIT

0

BugCheck 97: BOUND_IMAGE_UNSUPPORTED

0

BugCheck 98: END_OF_NT_EVALUATION_PERIOD

0

BugCheck 9A: SYSTEM_LICENSE_VIOLATION

0

BugCheck 9B: UDFS_FILE_SYSTEM

0

BugCheck A2: MEMORY_IMAGE_CORRUPT

0

BugCheck A3: ACPI_DRIVER_INTERNAL

0

BugCheck A4: CNSS_FILE_SYSTEM_FILTER

0

BugCheck A5: ACPI_BIOS_ERROR

0

BugCheck A7: BAD_EXHANDLE

0

BugCheck AC: HAL_MEMORY_ALLOCATION

0

BugCheck AD: VIDEO_DRIVER_DEBUG_REPORT_REQUEST

0

BugCheck B4: VIDEO_DRIVER_INIT_FAILURE

0

BugCheck B9: CHIPSET_DETECTED_ERROR

0

BugCheck BB: NETWORK_BOOT_INITIALIZATION_FAILED

0

BugCheck BC: NETWORK_BOOT_DUPLICATE_ADDRESS

0

BugCheck C6: DRIVER_CAUGHT_MODIFYING_FREED_POOL

0

BugCheck C7: TIMER_OR_DPC_INVALID

0

BugCheck C8: IRQL_UNEXPECTED_VALUE

0

BugCheck D7: DRIVER_UNMAPPING_INVALID_VIEW

0

BugCheck D8: DRIVER_USED_EXCESSIVE_PTES

0

BugCheck DC: DRIVER_INVALID_STACK_ACCESS

0

BugCheck DF: IMPERSONATING_WORKER_THREAD

0

BugCheck E0: ACPI_BIOS_FATAL_ERROR

0

BugCheck E9: ACTIVE_EX_WORKER_THREAD_TERMINATION

0

BugCheck EB: DIRTY_MAPPED_PAGES_CONGESTION

0

BugCheck EC: SESSION_HAS_VALID_SPECIAL_POOL_ON_EXIT

0

BugCheck EF: CRITICAL_PROCESS_DIED

0

BugCheck F1: SCSI_VERIFIER_DETECTED_VIOLATION

0

BugCheck F3: DISORDERLY_SHUTDOWN

0

BugCheck F5: FLTMGR_FILE_SYSTEM

0

BugCheck F6: PCI_VERIFIER_DETECTED_VIOLATION

0

BugCheck F8: RAMDISK_BOOT_INITIALIZATION_FAILED

0

BugCheck F9: DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN

0

BugCheck FA: HTTP_DRIVER_CORRUPTED

0

BugCheck FF: RESERVE_QUEUE_OVERFLOW

0

BugCheck 105: AGP_GART_CORRUPTION

0

BugCheck 10A: APP_TAGGING_INITIALIZATION_FAILED

0

BugCheck 10C: FSRTL_EXTRA_CREATE_PARAMETER_VIOLATION

0

BugCheck 10F: RESOURCE_MANAGER_EXCEPTION_NOT_HANDLED

0

BugCheck 112: MSRPC_STATE_VIOLATION

0

BugCheck 113: VIDEO_DXGKRNL_FATAL_ERROR

0

BugCheck 114: VIDEO_SHADOW_DRIVER_FATAL_ERROR

0

BugCheck 115: AGP_INTERNAL

0

BugCheck 119: VIDEO_SCHEDULER_INTERNAL_ERROR

0

BugCheck 11A: EM_INITIALIZATION_FAILURE

0

BugCheck 11B: DRIVER_RETURNED_HOLDING_CANCEL_LOCK

0

BugCheck 11C: ATTEMPTED_WRITE_TO_CM_PROTECTED_STORAGE

0

BugCheck 11D: EVENT_TRACING_FATAL_ERROR

0

BugCheck 127: PAGE_NOT_ZERO

0

BugCheck 12B: FAULTY_HARDWARE_CORRUPTED_PAGE

0

BugCheck 12C: EXFAT_FILE_SYSTEM

0

BugCheck C0000221: STATUS_IMAGE_CHECKSUM_MISMATCH

0

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Patterns (Part 55)

Tuesday, March 11th, 2008

Now it’s time to write about Wild Pointer pattern I briefly mentioned in Local Buffer Overflow post which shows examples of pointers having UNICODE structure in their values. I have also observed pointers with ASCII structure as .formats WinDbg command indicates:

FAILED_INSTRUCTION_ADDRESS: 
65747379`735c5357 ??              ???

IP_ON_HEAP:  65747379735c5357

0:012> .formats rip
Evaluate expression:
  Hex:     65747379`735c5357
  Decimal: 7310595060592825175
  Octal:   0625643467456327051527
  Binary:  01100101 01110100 01110011 01111001 01110011 01011100 01010011 01010111
  Chars:   etsys\SW
  Time:    Wed May 10 22:00:59.282 24767 (GMT+1)
  Float:   low 1.7456e+031 high 7.21492e+022
  Double:  5.30388e+180

Here is another example of a pointer having UNICODE structure:

FAILED_INSTRUCTION_ADDRESS: 
0045004c`00490046 ??              ???

0:014> .formats rip
Evaluate expression:
  Hex:     0045004c`00490046
  Decimal: 19422099815333958
  Octal:   0001050004600022200106
  Binary:  00000000 01000101 00000000 01001100 00000000 01001001 00000000 01000110
  Chars:   .E.L.I.F
  Time:    Wed Jul 19 07:46:21.533 1662 (GMT+1)
  Float:   low 6.70409e-039 high 6.33676e-039
  Double:  2.33646e-307

When we have EIP or RIP pointers I have another pattern to name when the value is coincidentally lies inside some valid region of memory: Wild Code. Here is one example of the latter pattern I’m going to write about soon:

IP_ON_STACK:
+e11ffa8

STACK_TEXT:
0e11ff7c 098eeef2 0xe11ffa8
0e11ff84 77b6b530 dll!StartWorking+0xcab
0e11ffb8 7c826063 msvcrt!_endthreadex+0xa3
0e11ffec 00000000 kernel32!BaseThreadStart+0×34

0:020> u
0e11ffa8 dcff fdiv st(7),st


We see that EIP is very close to EBP/ESP and this explains why !analyze -v reports IP_ON_STACK. Clearly floating-point code is not what we should expect. This example shows that wild pointers sometimes are valid but either through code chain or pointer chain execution reaches Invalid Pointer and a process or a system crashes.

- Dmitry Vostokov @ DumpAnalysis.org -

Time Travel Debugging

Saturday, March 8th, 2008

I was wondering whether there are any tools that allow to step through unmanaged and native code backwards when we do crash dump analysis or live debugging on Windows platforms and found these interesting references from Microsoft Research:

It would be really good if Microsoft integrates this into Debugging Tools for Windows. 

- Dmitry Vostokov @ DumpAnalysis.org -

Debugging Architects

Friday, March 7th, 2008

They know buzzwords like heap corruption, buffer overflow and multi-threading, talk about designing maintainable software but unable to cope with real-life debugging scenarios. I remember old days in one company where the executable Rational Rose Real-Time model with IDebug interface crashed and the whole team of software designers couldn’t find the defect in code and when I pointed them to the problem source code line after loading and running the executable under the Visual Studio debugger I was nominated as an expert in implementation.

- Dmitry Vostokov @ DumpAnalysis.org -

Thinking Out of the Box

Friday, March 7th, 2008

Q. Every time you open the specific Microsoft Word 2007 document on Vista WER error message box appears on the screen (click on the picture to enlarge):

What might be the cause of it?

You can find the correct answer in the comments to this post. 

- Dmitry Vostokov @ DumpAnalysis.org -

Signaled Objects

Thursday, March 6th, 2008

I decided to elaborate a bit on how to see whether the specific synchronization object has signaled or not. If that object has signaled (is in signaled state) then any wait on it will be satisfied immediately. All such objects like kernel events, processes and threads are structures in memory and have _OBJECT_HEADER structure followed by _DISPATCHER_HEADER structure and then by the actual object body (if it is necessary). These objects can be found in the output of !process or !thread commands where they are listed as being waited for, for example:

THREAD 88865db0  Cid 05d0.5ea8  Teb: 7ffaa000 Win32Thread: 00000000 WAIT: (Unknown) UserMode Non-Alertable
    89a65a68  SynchronizationEvent
Not impersonating
DeviceMap                 e1536358
Owning Process            8abbdd88       Image:         svchost.exe
Wait Start TickCount      5303768        Ticks: 1132797 (0:04:54:59.953)
Context Switch Count      193            
UserTime                  00:00:00.015
KernelTime                00:00:00.000
Start Address kernel32!BaseThreadStartThunk (0×7c82b5f3)
Stack Init b8ca2000 Current b8ca1c60 Base b8ca2000 Limit b8c9f000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0
Kernel stack not resident.
ChildEBP RetAddr 
b8ca1c78 80832f7a nt!KiSwapContext+0×26
b8ca1ca4 8082925c nt!KiSwapThread+0×284
b8ca1cec 80937e6a nt!KeWaitForSingleObject+0×346
b8ca1d50 80888c7c nt!NtWaitForSingleObject+0×9a
b8ca1d50 7c94ed54 nt!KiFastCallEntry+0xfc
00c6fea0 7c942124 ntdll!KiFastSystemCallRet
00c6fea4 7c95970f ntdll!NtWaitForSingleObject+0xc
00c6fee0 7c959620 ntdll!RtlpWaitOnCriticalSection+0×19c
00c6ff00 7c95c1e7 ntdll!RtlEnterCriticalSection+0xa8
00c6ffa8 7c8261d6 ntdll!LdrShutdownThread+0×33
00c6ffb8 7c826090 kernel32!ExitThread+0×2f
00c6ffec 00000000 kernel32!BaseThreadStart+0×39

We can see them as parameters of KeWaitForSingle(Multiple)Objects functions:

0: kd> !thread 88865db0
THREAD 88865db0  Cid 05d0.5ea8  Teb: 7ffaa000 Win32Thread: 00000000 WAIT: (Unknown) UserMode Non-Alertable
    89a65a68  SynchronizationEvent
Not impersonating
DeviceMap                 e1536358
Owning Process            8abbdd88       Image:         svchost.exe
Wait Start TickCount      5303768        Ticks: 1132797 (0:04:54:59.953)
Context Switch Count      193            
UserTime                  00:00:00.015
KernelTime                00:00:00.000
Start Address kernel32!BaseThreadStartThunk (0×7c82b5f3)
Stack Init b8ca2000 Current b8ca1c60 Base b8ca2000 Limit b8c9f000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0
Kernel stack not resident.
ChildEBP RetAddr  Args to Child             
b8ca1c78 80832f7a 88865e28 88865db0 88865e58 nt!KiSwapContext+0×26
b8ca1ca4 8082925c 00000000 00000000 00000000 nt!KiSwapThread+0×284
b8ca1cec 80937e6a 89a65a68 00000006 00000001 nt!KeWaitForSingleObject+0×346
b8ca1d50 80888c7c 00000470 00000000 00000000 nt!NtWaitForSingleObject+0×9a
b8ca1d50 7c94ed54 00000470 00000000 00000000 nt!KiFastCallEntry+0xfc
00c6fea0 7c942124 7c95970f 00000470 00000000 ntdll!KiFastSystemCallRet
00c6fea4 7c95970f 00000470 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
00c6fee0 7c959620 00000000 00000004 009171a8 ntdll!RtlpWaitOnCriticalSection+0×19c
00c6ff00 7c95c1e7 7c9a9d94 00000000 7ffaa000 ntdll!RtlEnterCriticalSection+0xa8
00c6ffa8 7c8261d6 00000000 00000000 00c6ffec ntdll!LdrShutdownThread+0×33
00c6ffb8 7c826090 00000000 00000000 00000000 kernel32!ExitThread+0×2f
00c6ffec 00000000 77c2de6d 009171a8 00000000 kernel32!BaseThreadStart+0×39

We can also see them as part of other structures, for example:

0: kd> !irp 88f4fd28 1
Irp is active with 1 stacks 1 is current (= 0x88f4fd98)
 No Mdl: No System Buffer: Thread 8a9449a0:  Irp stack trace. 
Flags = 00000800
ThreadListEntry.Flink = 8a944ba8
ThreadListEntry.Blink = 8a944ba8
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000001
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = 00dddf04
UserEvent = 8a033c88
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00dddf04
Overlay.AllocationSize = 00000000 - 00000000
CancelRoutine = f75c815c   Npfs!NpCancelListeningQueueIrp
UserBuffer = 00000000
&Tail.Overlay.DeviceQueueEntry = 88f4fd68
Tail.Overlay.Thread = 8a9449a0
Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = e311f7d4
Tail.Overlay.ListEntry.Blink = e311f7d4
Tail.Overlay.CurrentStackLocation = 88f4fd98
Tail.Overlay.OriginalFileObject = 884bc8a0
Tail.Apc = 00000000
Tail.CompletionKey = 00000000
     cmd  flg cl Device   File     Completion-Context
>[  d, 0]   5  1 8a937398 884bc8a0 00000000-00000000    pending
        \FileSystem\Npfs
   Args: 00000000 00000000 00110008 00000000

0: kd> !object 8a033c88
Object: 8a033c88  Type: (8ad7a990) Event
    ObjectHeader: 8a033c70 (old version)
    HandleCount: 1  PointerCount: 3

They can also be found in process or kernel (System process) handle tables: 

0: kd> !process 0 0
...
...
...
PROCESS 8a8fa8c0  SessionId: 0  Cid: 037c    Peb: 7ffd8000  ParentCid: 04ac
    DirBase: f3b10360  ObjectTable: e1c276b8  HandleCount: 500.
    Image: MyService.exe
...
...
...

0: kd> !kdexts.handle 0 3 037c
...
...
...
0510: Object: 89237d88  GrantedAccess: 001f0fff Entry: e1cafa20
Object: 89237d88  Type: (8ad84900) Process
    ObjectHeader: 89237d70 (old version)
        HandleCount: 1  PointerCount: 2


Let’s look at the last process object 89237d88. This is the start of object-specific structure whose first member is _DISPATCHER_HEADER. Every object-specific structure is preceded in memory by _OBJECT_HEADER structure and in our case its address is 89237d70. To illustrate this memory layout we can write this inheritance relationship in C++ pseudo-code where I put relevant structure members:    

struct _KPROCESS : _DISPATCHER_HEADER
{
   // ... members
};

struct _DISPATCHER_HEADER
{
   UChar Type;
   // ... members
   Int4B SignalState; 
   // ... members
};

struct _OBJECT_HEADER
{
   Int4B PointerCount;
   Int4B HandleCount; 
   // ... members
   _OBJECT_TYPE *Type;
   // ... members
   _QUAD Body; // Int8B - first 8 bytes of _DISPATCHER_HEADER  
};

HandleCount is the number of open handles and PointerCount is the number of dereferences.  

I also put all this on the following simplified UML diagram:

Here is the detailed data for our process object: 

0: kd> dt _OBJECT_HEADER 89237d70
ntdll!_OBJECT_HEADER
   +0x000 PointerCount     : 2
   +0x004 HandleCount      : 1
   +0x004 NextToFree       : 0x00000001
   +0x008 Type             : 0x8ad84900 _OBJECT_TYPE
   +0x00c NameInfoOffset   : 0 ''
   +0x00d HandleInfoOffset : 0 ''
   +0x00e QuotaInfoOffset  : 0 ''
   +0x00f Flags            : 0x20 ' '
   +0x010 ObjectCreateInfo : 0x808ad180 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : 0x808ad180
   +0x014 SecurityDescriptor : 0xe1002bd6
   +0x018 Body             : _QUAD

0: kd> dt _DISPATCHER_HEADER 89237d88
ntdll!_DISPATCHER_HEADER
   +0x000 Type             : 0x3 ''
   +0x001 Absolute         : 0 ''
   +0x001 NpxIrql          : 0 ''
   +0x002 Size             : 0x1e ''
   +0x002 Hand             : 0x1e ''
   +0x003 Inserted         : 0 ''
   +0x003 DebugActive      : 0 ''
   +0x000 Lock             : 1966083
   +0×004 SignalState      : 1
   +0×008 WaitListHead     : _LIST_ENTRY [ 0×89237d90 - 0×89237d90 ]

0: kd> dt _OBJECT_TYPE 0x8ad84900
ntdll!_OBJECT_TYPE
   +0x000 Mutex            : _ERESOURCE
   +0x038 TypeList         : _LIST_ENTRY [ 0x8ad84938 - 0x8ad84938 ]
   +0×040 Name             : _UNICODE_STRING “Process”
   +0×048 DefaultObject    : (null)
   +0×04c Index            : 5
   +0×050 TotalNumberOfObjects : 0×18d
   +0×054 TotalNumberOfHandles : 0×35d
   +0×058 HighWaterNumberOfObjects : 0×2d4
   +0×05c HighWaterNumberOfHandles : 0xd66
   +0×060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0×0ac Key              : 0×636f7250
   +0×0b0 ObjectLocks      : [4] _ERESOURCE

We see that SignalState is 1 and this means that the process is in signaled state (exited) and the wait on it will be satisfied immediately (WaitForSingleObject will return). If we close its handle the object will be destroyed.

If we look at other objects threads are waiting for we would see SignalState equal to 0. For example, in the following thread below event handle 4b0 corresponds to a34d9940 _KEVENT address and the latter object is inherited from _DISPATCHER_HEADER:

3: kd> !thread a34369d0
THREAD a34369d0  Cid 1fc8.1e88  Teb: 7ffae000 Win32Thread: bc6d5818 WAIT: (Unknown) UserMode Non-Alertable
    a34d9940  SynchronizationEvent
    a3436a48  NotificationTimer
Not impersonating
DeviceMap                 e12256a0
Owning Process            a3340a10       Image:         IEXPLORE.EXE
Wait Start TickCount      1450409        Ticks: 38 (0:00:00:00.593)
Context Switch Count      7091                 LargeStack
UserTime                  00:00:01.015
KernelTime                00:00:02.250
Win32 Start Address mshtml!CExecFT::StaticThreadProc (0×7fab1061)
Start Address kernel32!BaseThreadStartThunk (0×77e617ec)
Stack Init f252b000 Current f252ac60 Base f252b000 Limit f2528000 Call 0
Priority 11 BasePriority 10 PriorityDecrement 0
ChildEBP RetAddr  Args to Child             
f252ac78 80833465 a34369d0 a3436a78 00000003 nt!KiSwapContext+0×26
f252aca4 80829a62 00000000 f252ad14 00000000 nt!KiSwapThread+0×2e5
f252acec 80938d0c a34d9940 00000006 f252ac01 nt!KeWaitForSingleObject+0×346
f252ad50 8088978c 000004b0 00000000 f252ad14 nt!NtWaitForSingleObject+0×9a
f252ad50 7c8285ec 000004b0 00000000 f252ad14 nt!KiFastCallEntry+0xfc (TrapFrame @ f252ad64)
030dff08 7c827d0b 77e61d1e 000004b0 00000000 ntdll!KiFastSystemCallRet
030dff0c 77e61d1e 000004b0 00000000 030dff50 ntdll!NtWaitForSingleObject+0xc
030dff7c 77e61c8d 000004b0 000927c0 00000000 kernel32!WaitForSingleObjectEx+0xac
030dff90 7fab08a3 000004b0 000927c0 00000000 kernel32!WaitForSingleObject+0×12
030dffa8 7fab109c 00000000 7fab106e 030dffec mshtml!CDwnTaskExec::ThreadExec+0xae
030dffb0 7fab106e 030dffec 77e64829 02714f30 mshtml!CExecFT::ThreadProc+0×28
030dffb8 77e64829 02714f30 00000000 00000000 mshtml!CExecFT::StaticThreadProc+0xd
030dffec 00000000 7fab1061 02714f30 00000000 kernel32!BaseThreadStart+0×34

3: kd> dt _DISPATCHER_HEADER a34d9940
cutildll!_DISPATCHER_HEADER
   +0x000 Type             : 0x1 ''
   +0x001 Absolute         : 0xda ''
   +0x002 Size             : 0x4 ''
   +0x003 Inserted         : 0xa3 ''
   +0x003 DebugActive      : 0xa3 ''
   +0x000 Lock             : -1559963135
   +0×004 SignalState      : 0
   +0×008 WaitListHead     : _LIST_ENTRY [ 0xa3436a78 - 0xa3436a78 ]

For real life example of signaled process objects please see Zombie Processes pattern case study.

- Dmitry Vostokov @ DumpAnalysis.org -