This exception occurs when the CommandString parameter for the !for_each_module contains the !address command.
0:000> !for_each_module !address @#Base ... c0000005 Exception in ext.for_each_module debugger extension. PC: 00000000 VA: 00000000 R/W: 8 Parameter: 00000000
0:018> lmDvmext ... Image name: ext.dll Timestamp: Thu Aug 22 07:11:11 2013 (52158F5F) CheckSum: 002EAC1C ImageSize: 00300000 File version: 6.3.9600.16384 Product version: 6.3.9600.16384 File flags: 0 (Mask 3F) File OS: 40004 NT Win32 File type: 2.0 Dll File date: 00000000.00000000 Translations: 0409.04b0 CompanyName: Microsoft Corporation ProductName: Microsoft® Windows® Operating System InternalName: ext.DLL OriginalFilename: ext.DLL ProductVersion: 6.3.9600.16384 FileVersion: 6.3.9600.16384 (debuggers(dbg).130821-1623)
From the next excerpts we can see that the !for_each_module command was written by using Debugger Engine API and the WdbgExts API. It obtains the Debugger Engine interfaces in the ext!ExtQuery function and initializes the ExtensionApis global variable in the ext!InitializeGlobals function. Then it calls dbgeng!DebugClient::Execute method to execute the !address command.
0:018> uf . ext!for_each_module: 64a44126 8bff mov edi,edi 64a44128 55 push ebp 64a44129 8bec mov ebp,esp 64a4412b 83e4f8 and esp,0FFFFFFF8h 64a4412e 81ecb40a0000 sub esp,0AB4h 64a44134 a12430b464 mov eax,dword ptr [ext!__security_cookie (64b43024)] 64a44139 33c4 xor eax,esp 64a4413b 898424b00a0000 mov dword ptr [esp+0AB0h],eax 64a44142 53 push ebx 64a44143 8b5d0c mov ebx,dword ptr [ebp+0Ch] 64a44146 33c0 xor eax,eax 64a44148 834c241cff or dword ptr [esp+1Ch],0FFFFFFFFh 64a4414d 8bcb mov ecx,ebx 64a4414f 56 push esi 64a44150 57 push edi 64a44151 8b7d08 mov edi,dword ptr [ebp+8] 64a44154 89442414 mov dword ptr [esp+14h],eax 64a44158 8d5101 lea edx,[ecx+1] 64a4415b 89442410 mov dword ptr [esp+10h],eax 64a4415f 8944242c mov dword ptr [esp+2Ch],eax 64a44163 8a01 mov al,byte ptr [ecx] 64a44165 41 inc ecx 64a44166 84c0 test al,al 64a44168 75f9 jne ext!for_each_module+0x3d (64a44163) Branch 64a4416a 8364242800 and dword ptr [esp+28h],0 64a4416f 2bca sub ecx,edx 64a44171 0fb7c1 movzx eax,cx 64a44174 8bcf mov ecx,edi 64a44176 89442434 mov dword ptr [esp+34h],eax 64a4417a e8f460ffff call ext!ExtQuery (64a3a273) ... 64a44638 6a02 push 2 64a4463a 53 push ebx 64a4463b 6a01 push 1 64a4463d 8b08 mov ecx,dword ptr [eax] 64a4463f 50 push eax 64a44640 ff9108010000 call dword ptr [ecx+108h] ds:002b:6bb92bb0={dbgeng!DebugClient::Execute (6bc1cea4)} 64a44646 ff15a0ccb864 call dword ptr [ext!ExtensionApis+0x14 (64b8cca0)] <- Access Violation will occur here 0:018> dps ext!ExtensionApis+0x14 L1 64b8cca0 6bd176f2 dbgeng!CheckUserInterrupt
ext!ExtQuery: ext!ExtQuery: 64a3a273 8bff mov edi,edi 64a3a275 51 push ecx 64a3a276 a1f800b964 mov eax,dword ptr [ext!g_RecursionCount (64b900f8)] 64a3a27b 40 inc eax 64a3a27c a3f800b964 mov dword ptr [ext!g_RecursionCount (64b900f8)],eax 64a3a281 56 push esi 64a3a282 8bf1 mov esi,ecx 64a3a284 57 push edi 64a3a285 83f801 cmp eax,1 64a3a288 7e07 jle ext!ExtQuery+0x1e (64a3a291) 64a3a28a 33c0 xor eax,eax 64a3a28c e9ed000000 jmp ext!ExtQuery+0x10b (64a3a37e) 64a3a291 8b06 mov eax,dword ptr [esi] 64a3a293 68f4abb764 push offset ext!g_ExtAdvanced (64b7abf4) 64a3a298 68d8aa9564 push offset ext!_GUID_f2df5f53_071f_47bd_9de6_5734c3fed689 (6495aad8) 64a3a29d 56 push esi 64a3a29e ff10 call dword ptr [eax] ds:002b:6bb92d6c={dbgeng!DebugClient::QueryInterface (6bc17a48)} ... 64a3a31f e83afbffff call ext!InitializeGlobals (64a39e5e) ... 64a3a37e 5f pop edi 64a3a37f 5e pop esi 64a3a380 59 pop ecx 64a3a381 c3 ret
ext!InitializeGlobals: ... 64a39eae 688cccb864 push offset ext!ExtensionApis (64b8cc8c) 64a39eb3 56 push esi 64a39eb4 ff9040010000 call dword ptr [eax+140h] ds:002b:6bb92be8={dbgeng!DebugClient::GetWindbgExtensionApis64 (6bc1e196)} ...
Also we can see that the !address command was written by using the EngExtCpp API and that the ExtensionApis global variable is automatically initialized on entry to an EngExtCpp method and cleared on exit.
ext!ExtExtension::Query: ... 64aeb1fa 688cccb864 push offset ext!ExtensionApis (64b8cc8c) 64aeb1ff 50 push eax 64aeb200 8b08 mov ecx,dword ptr [eax] 64aeb202 ff9140010000 call dword ptr [ecx+140h] ds:002b:6bb92be8={dbgeng!DebugClient::GetWindbgExtensionApis64 (6bc1e196)} ... 0:018> k # ChildEBP RetAddr 00 02d7c428 64aeb79a ext!ExtExtension::Query+0x379 01 02d7c464 649caebd ext!ExtExtension::CallExtCodeSEH+0x1c 02 02d7c4a8 6bc794ca ext!address+0x50 03 02d7c524 6bc7962c dbgeng!ExtensionInfo::CallA+0x1d3 04 02d7c6c8 6bc796a4 dbgeng!ExtensionInfo::Call+0xec 05 02d7c6ec 6bc78763 dbgeng!ExtensionInfo::CallAny+0x4c 06 02d7cb58 6bca9cbb dbgeng!ParseBangCmd+0x439 07 02d7cbc8 6bcaa955 dbgeng!ProcessCommands+0x753 08 02d7cc28 6bc1cdd4 dbgeng!ProcessCommandsAndCatch+0x91 09 02d7d094 6bc1cfc5 dbgeng!Execute+0x226 0a 02d7d0e0 6bc1cf18 dbgeng!DebugClient::ExecuteWide+0x8d 0b 02d7d330 64a44646 dbgeng!DebugClient::Execute+0x74 0c 02d7de08 6bc794ca ext!for_each_module+0x520
ext!ExtExtension::Release ... 64aeb5c3 6a30 push 30h 64aeb5c5 57 push edi 64aeb5c6 688cccb864 push offset ext!ExtensionApis (64b8cc8c) 64aeb5cb e8569f0000 call ext!memset (64af5526) ... 0:018> r @edi edi=00000000 0:018> k # ChildEBP RetAddr 00 02d7c424 64aeb7e5 ext!ExtExtension::Release+0x333 01 02d7c428 64aeb7ce ext!ExtExtension::CallExtCodeSEH+0x67 02 02d7c464 649caebd ext!ExtExtension::CallExtCodeSEH+0x50 03 02d7c4a8 6bc794ca ext!address+0x50 04 02d7c524 6bc7962c dbgeng!ExtensionInfo::CallA+0x1d3 05 02d7c6c8 6bc796a4 dbgeng!ExtensionInfo::Call+0xec 06 02d7c6ec 6bc78763 dbgeng!ExtensionInfo::CallAny+0x4c 07 02d7cb58 6bca9cbb dbgeng!ParseBangCmd+0x439 08 02d7cbc8 6bcaa955 dbgeng!ProcessCommands+0x753 09 02d7cc28 6bc1cdd4 dbgeng!ProcessCommandsAndCatch+0x91 0a 02d7d094 6bc1cfc5 dbgeng!Execute+0x226 0b 02d7d0e0 6bc1cf18 dbgeng!DebugClient::ExecuteWide+0x8d 0c 02d7d330 64a44646 dbgeng!DebugClient::Execute+0x74 0d 02d7de08 6bc794ca ext!for_each_module+0x520
So, after the execution of the !address command we have an empty ExtensionApis structure, which is still used by ext!for_each_module function.
0:018> r eax=00000000 ebx=02d7dedc ecx=6bc1cf30 edx=ffffffff esi=80070715 edi=00000000 eip=64a44646 esp=02d7d348 ebp=02d7de08 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ext!for_each_module+0x520: 64a44646 ff15a0ccb864 call dword ptr [ext!ExtensionApis+0x14 (64b8cca0)] ds:002b:64b8cca0=00000000 0:018> dps ext!ExtensionApis+0x14 L1 64b8cca0 00000000
I also took an extra step and found that the !address command was rewritten using the EngExtCpp framework in the Windows Driver Kit 8.0, and that the conjunction of these commands in the previous version of the WDK does not cause the problem.