How to debug WOW64 applications?
Hello, my name is Venkatesh Ganga, and I’m an Escalation Engineer on the Microsoft Platform Global Escalation Services team. Recently, I worked on an issue where registry reflection was not happening while installing 32bit Office under the system account. This required looking into both the 32bit Office code and the Wow64 code where the registry reflection is implemented. When attaching to the Wow64 process using the 32bit debugger it’s like debugging a 32bit process on the 32bit machine; there are no 64bit binaries in the process. However, we needed to debug Wow64 to debug the registry reflection code. To do this we attached to the Wow64 process using the 64bit debugger which allows you to see the Wow64 binaries.
Ø lm
Base TimeStamp Module
400000 42435b2a Mar 24 18:28:26 2005 C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE
77ec0000 45d6cc72 Feb 17 03:35:46 2007 C:\WINDOWS\system32\ntdll.dll
6b000000 45d6943d Feb 16 23:35:57 2007 C:\WINDOWS\system32\wow64.dll
6b280000 45d695f3 Feb 16 23:43:15 2007 C:\WINDOWS\system32\wow64win.dll
78b80000 42438b7a Mar 24 21:54:34 2005 C:\WINDOWS\system32\wow64cpu.dll
There are 2 options for debugging Wow64 applications.
1. Using the 64bit debugger and Wow64 debugger extension (Wow64exts.dll)
2. Using the 32bit debugger
Using 64bit debugger and Wow64 debugger extension (Wow64exts.dll)
I ran the 32bit version of Internet Explorer on a 64bit machine and attached to it using the 64bit debugger. Here is the thread 0 call stack when viewed from 64bit debugger.
0:000> kL
Child-SP RetAddr Call Site
00000000`0013edf8 00000000`78b8428e wow64cpu!CpupSyscallStub+0x9
00000000`0013ee00 00000000`6b006a5a wow64cpu!Thunk0Arg+0x5
00000000`0013ee70 00000000`6b005e0d wow64!RunCpuSimulation+0xa
00000000`0013eea0 00000000`77ed8030 wow64!Wow64LdrpInitialize+0x2ed
00000000`0013f6d0 00000000`77ed582f ntdll!LdrpInitializeProcess+0x1538
00000000`0013f9d0 00000000`77ef30a5 ntdll!_LdrpInitialize+0x18f
00000000`0013fab0 00000000`77d59620 ntdll!KiUserApcDispatch+0x15
00000000`0013ffa8 00000000`00000000 0x77d59620
00000000`0013ffb0 00000000`00000000 0x0
00000000`0013ffb8 00000000`00000000 0x0
00000000`0013ffc0 00000000`00000000 0x0
00000000`0013ffc8 00000000`00000000 0x0
00000000`0013ffd0 00000000`00000000 0x0
00000000`0013ffd8 00000000`00000000 0x0
00000000`0013ffe0 00000000`00000000 0x0
00000000`0013ffe8 00000000`00000000 0x0
00000000`0013fff0 00000000`00000000 0x0
00000000`0013fff8 00000000`00000000 0x0
00000000`00140000 00000020`78746341 0x0
00000000`00140008 00005370`00000001 0x20`78746341
The above stack only shows the 64 bit calls; we cannot see what the 32 bit calls are doing. To get the 32bit stack you must use one of the below methods.
Ø Option 1 : Run “!wow64exts.k”
0:000> !wow64exts.k
Walking 64bit Stack…
Child-SP RetAddr Call Site
00000000`0013edf8 00000000`78b8428e wow64cpu!CpupSyscallStub+0x9
00000000`0013ee00 00000000`6b006a5a wow64cpu!Thunk0Arg+0x5
00000000`0013ee70 00000000`6b005e0d wow64!RunCpuSimulation+0xa
00000000`0013eea0 00000000`77ed8030 wow64!Wow64LdrpInitialize+0x2ed
00000000`0013f6d0 00000000`77ed582f ntdll!LdrpInitializeProcess+0x1538
00000000`0013f9d0 00000000`77ef30a5 ntdll!_LdrpInitialize+0x18f
00000000`0013fab0 00000000`77d59620 ntdll!KiUserApcDispatch+0x15
00000000`0013ffa8 00000000`00000000 0x77d59620
00000000`0013ffb0 00000000`00000000 0x0
00000000`0013ffb8 00000000`00000000 0x0
00000000`0013ffc0 00000000`00000000 0x0
00000000`0013ffc8 00000000`00000000 0x0
00000000`0013ffd0 00000000`00000000 0x0
00000000`0013ffd8 00000000`00000000 0x0
00000000`0013ffe0 00000000`00000000 0x0
00000000`0013ffe8 00000000`00000000 0x0
00000000`0013fff0 00000000`00000000 0x0
00000000`0013fff8 00000000`00000000 0x0
00000000`00140000 00000020`78746341 0x0
00000000`00140008 00005370`00000001 0x20`78746341
Walking 32bit Stack...
ChildEBP RetAddr
002ded98 75ec1c83 USER32!NtUserWaitMessage+0x15
002dee24 75ec61ef BROWSEUI!BrowserProtectedThreadProc+0x44
002dfea8 779ba3a6 BROWSEUI!SHOpenFolderWindow+0x22c
002dfec8 0040243d SHDOCVW!IEWinMain+0x129
002dff1c 00402748 IEXPLORE!WinMain+0x316
002dffc0 7d4e7d2a IEXPLORE!WinMainCRTStartup+0x186
002dfff0 00000000 KERNEL32!BaseProcessStart+0x28
Ø Option 2 : Switch to x86 mode (using “!wow64exts.sw”) and do KB.
0:000> !wow64exts.sw
Switched to 32bit mode
0:000:x86> kb
ChildEBP RetAddr Args to Child
002ded98 75ec1c83 002f1be8 002dee50 002f1be8 USER32!NtUserWaitMessage+0x15
002dee24 75ec61ef 002f1be8 002f1be8 00000000 BROWSEUI!BrowserProtectedThreadProc+0x44
002dfea8 779ba3a6 002f1be8 00000001 00000000 BROWSEUI!SHOpenFolderWindow+0x22c
002dfec8 0040243d 002e2508 00000001 ffffffff SHDOCVW!IEWinMain+0x129
002dff1c 00402748 00400000 00000000 002e2508 IEXPLORE!WinMain+0x316
002dffc0 7d4e7d2a 00000000 00000000 7efdf000 IEXPLORE!WinMainCRTStartup+0x186
002dfff0 00000000 004025c2 00000000 000000c8 KERNEL32!BaseProcessStart+0x28
The easiest way to see all of the 32bit call stacks is by switching to 32bit mode (!wow64exts.sw) and doing ~*k. In addition, you can set breakpoints in 32bit or 64 bit binaries using the 64bit debugger. Also note “!peb” will show both the 64bit and 32bit PEB.
Using the 32bit debugger
As mentioned earlier there is nothing wrong with using the 32 bit debugger. If you just need to debug the application’s 32bit code, using it is probably the simplest approach. However, if you need to view Wow64 code or binaries, you must use the 64bit debugger. Note that these techniques apply to debugging Wow64 dumps and live processes.
You can find more information about WoW64 applications at https://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx
Comments
Anonymous
June 04, 2008
Does .effmach x86 differ at all from using !wow64exts.sw ? thanksAnonymous
June 04, 2008
The recommended way to do this, or at least so I thought, was to use the built in ".effmach <arch-type>" command (e.g. "x86", "amd64", ...). [Internally .effmach and !wow64exts.sw make same call to change the processor mode that debugger uses. !wow64exts.sw is written to automatically switch between 32bit and 64bit mode whereas .effmach needs the machine type as input.]Anonymous
July 17, 2009
thank you for sharing this knowledge