1 year ago
#347455
nanofarad
What exactly does the 32-bit win32k.sys/win32kfull.sys do on a 64-bit Windows operating system?
tl;dr The 32-bit binaries SysWow64/win32k[full].sys cannot be loaded into a running 64-bit kernel and do not have useful PE resources. What is their purpose on a 64-bit Windows machine?
I'm studying the behavior of Windows' wow64 functionality to run 32-bit Windows code on a 64-bit Windows system. I recognize that these are implementation details, but I'm specifically interested in learning more about the implementation as I'm trying to get better with related kernel-mode development techniques.
So far, the normal NT API system call process is clear to me: 32-bit user code calls into a 32-bit stub in the 32-bit ntdll (e.g. ntdll32!NtOpenFile), wow64cpu.dll gets the CPU back into long mode through a farjump, and then a 64-bit thunk checks and extends arguments before making a syscall into the 64-bit ntoskrnl.exe from system32 (not SysWow64).
I'm a bit more confused about the win32 API system call process. From a normal non-wow process (32-bit on 32-bit or 64-bit on 64-bit), user code calls into user.dll -> win32u.dll -> syscall which gets routed through ntoskrnl.exe's syscall handler to kernel-mode code in win32k.sys and/or win32kfull.sys.
My understanding is that the wow64 win32k syscall should be analogous to the WoW64 ntdll syscall: 32-bit user code should call user.dll -> 32-bit win32u.dll -> Wow64 transition (farjump into long mode) -> 64-bit thunk to a 64-bit system call which hits 64-bit kernel-mode code in ntoskrnl.exe and win32k[full].sys. I can see the user-mode 32-bit debugger show a call into win32u.dll which calls the wow64 transition code that farjumps into long mode:
> bp win32u!NtCreateUserWindowEx
> g
> k
00 0019f7ac 776fff44 win32u!NtUserCreateWindowEx
01 0019fa8c 776feba4 USER32!VerNtUserCreateWindowEx+0x229
02 0019fbd4 776f4921 USER32!InternalCreateDialog+0x6c4
03 0019fc18 77751bdb USER32!InternalDialogBox+0xc6
> // trace a bunch of times
> u
77967000 ea097096773300 jmp 0033:77967009 // the farjump into long mode, at which point my debugger
// stops tracing
On the 64-bit debugger, I can see that we make a syscall into kernel mode:
Breakpoint 1 hit
wow64win!NtUserCreateWindowEx:
00007ffa`56f30dc0 4c8bd1 mov r10,rcx
0:000> k
# Child-SP RetAddr Call Site
00 00000000`0009e4e8 00007ffa`56f25361 wow64win!NtUserCreateWindowEx
01 00000000`0009e4f0 00007ffa`56fb901a wow64win!whNtUserCreateWindowEx+0x351
02 00000000`0009e620 00000000`779617c3 wow64!Wow64SystemServiceEx+0x15a
03 00000000`0009eee0 00000000`779611b9 wow64cpu!ServiceNoTurbo+0xb
04 00000000`0009ef90 00007ffa`56fb38c9 wow64cpu!BTCpuSimulate+0x9
0:000> u
wow64win!NtUserCreateWindowEx:
00007ffa`56f30dc0 4c8bd1 mov r10,rcx
00007ffa`56f30dc3 b874100000 mov eax,1074h
00007ffa`56f30dc8 f604250803fe7f01 test byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffa`56f30dd0 7503 jne wow64win!NtUserCreateWindowEx+0x15 (00007ffa`56f30dd5)
00007ffa`56f30dd2 0f05 syscall // <-- syscall into 64-bit ntoskrnl.exe
I don't have the means to attach a kernel debugger, but I'm almost fairly certain that after entering kernel mode, execution reaches the implementation of NtUserCreateWindowEx in the 64-bit win32kfull.sys, simply on the understanding that the kernel is 64-bit.
However, SysWow64 provides 32-bit versions of win32k.sys and win32kfull.sys:
They don't look like stubs based on their size and the fact that they import a ton of other kernel functions - this leads to my primary question: These kernel-mode binaries cannot actually be loaded into the kernel and called (because of an arch/bitness mismatch), they do not provide any resources, and they don't appear to have all of their deps. Are these just vestigial leftovers with no use, or is there some clever programming trick in Windows/wow64 that they enable?
winapi
windows-kernel
wow64
0 Answers
Your Answer