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