Title: WoW64 Internal Architecture
1WoW64 Internal Architecture
- Samer Arafeh
- Software Design Engineer
- Windows Base OS Kernel
- samera _at_ microsoft.com
- Microsoft Corporation
2Agenda
- What is WoW64?
- WoW64 Process Address Space Layout
- WoW64 Registry Management
- WoW64 File System Redirection
- 32-bit I/O on 64-bit Windows
- 32/64 Inter-op Issues
- WoW64 Platform-Specific Support
- Debugging a WoW64 Process
- Discussion
3What Is WoW64?
- 32-bit Windows emulation layer on 64-bit Windows
- Installed as part of 64-bit Windows
- Binary compatibility with 32-bit Windows
applications is the prime goal - 64-bit Windows system setup installs and
registers 64-bit and 32-bit system files - 32-bit system files are copied to
windir\sysWoW64, likewise, 64-bit system files
are installed to windir\system32 - SystemDrive\Program Files (x86) is the place
for 32-bit applications, likewise,
SystemDrive\Program Files is the place for
64-bit applications - Environment variables are duplicated as well
- ProgramFiles and ProgramFiles(x86)
- CommonProgramFiles and CommonProgramFiles(x86)
4What Is WoW64?
- Once 64-bit Windows is installed, you should be
able to run 32-bitWindows applications! - x86 binaries on 64-bit Windows are identical to
their counterpart on a native 32-bit Windows x86
system - Compatibility
- Feature parity with the native 32-bit Windows
Operating System (OS)
5How Does WoW64 Work?
- WoW64 intercepts system calls from the 32-bit
application - Transitions to 64-bit mode
- Converts 32-bit data structure into 64-bit
aligned structures - Issues the native 64-bit system call
- Writes back any output data from the 64-bit
system call - Returns to 32-bit mode
- Hooks exception dispatching
- WoW64 core consists of
- WoW64.dll Manages process and thread
initialization, exception dispatching to 32-bit
code and intercepts base system calls - WoW64win.dll Intercepts GUI system calls
- WoW64cpu.dll Manages thread contexts and has
processor architecture specific support for
switching CPU modes
6WoW64 Process Address Space Layout
NT Executive
Win32k.sys
Kernel Mode
User Mode
Reserved Address Space
0x000000007FFEFFFF or 0x00000000FFFEFFFF
64-bit ntdll.dll
WoW64.dll
WoW64win.dll
WoW64cpu.dll
32-bit ntdll.dll
32-bit modules
7WoW64 Process Address Space Layout
- Address space is limited to 2GB (or 4GB if the
application is marked Large-Address-Aware in the
header) - WoW64 processes can NOT load 64-bit DLLs except
for the core one! - Likewise, native 64-bit processes can NOT load
32-bit DLLs - LoadLibrary() will fail
- Once WoW64 is initialized, 32-bit code executes
as if it is running on a native x86 processor
8WoW64 Registry
- Two views of the registry exist on 64-bit
Windows Native and WoW64 - By default, a native 64-bit Windows application
sees the native registry view, and a WoW64
application sees the WoW64 view - Why different WoW64 registry view?
- Compatibility
- Separates 32-bit application state from 64-bit
state - For example Not supported features stored in
the registry - Provides a safe execution environment for both
32-bit and 64-bit applications - For example a registry value hosting a DLL path
9WoW64 Registry Redirection
- Certain parts of the system registry are
separated - HKEY_LOCAL_MACHINE\Software
- HKEY_CLASSES_ROOT
- A new key, WoW6432Node, is created at the
splitted nodes - When a WoW64 process opens/creates a key
- WoW64 redirects the path of the key if it is one
of the above by inserting WoW6432Node to the
above path - Transparent forWin32 applications
10WoW64 Registry Reflection
- Everything else is shared
- API flags to explicitly specify a view of the
registry - Can be used in RegOpenKeyEx() or RegCreateKeyEx()
- KEY_WoW64_64KEY explicitly opens a 64-bit key
from either a 32-bit or 64-bit application - KEY_WoW64_32KEY explicitly opens a 64-bit key
from either a 32-bit or 64-bit application - windir\syswow64\regedit.exe m launches the
32-bit registry editor - What else is missing?
- Registry Reflection
11WoW64 Registry Reflection
- Enables 64-bit and 32-bit application
Inter-Opthrough COM - Mirrors certain registry keys and values between
the 32-bit and 64-bit registry views - Happens in real-time
- Reflected keys are
- HKEY_LOCAL_MACHINE\Software\Classes
- HKEY_LOCAL_MACHINE\Software\Ole
- HKEY_LOCAL_MACHINE\Software\Rpc
- HKEY_LOCAL_MACHINE\Software\COM3
- HKEY_LOCAL_MACHINE\Software\EventSystem
- Ownership-based reflection
- Helps intelligent reflection of COM servers
12WoW64 Registry Reflection
- Rules for HKEY_CLASSES_ROOT\CLSID reflection
- InProcServer32 and InProcHandler32 arenot
reflected - LocalServer32 is reflected
- Delete reflected keys only if written byWoW64
reflector
13WoW64 File System Redirection
- Redirects file-level access from
windir\system32 to windir\syswow64 - Many 32-bit Windows applications hard-codes
windir\system32 - 32-bit Windows applications which try to open or
create a file underneath windir\system32\...
are automatically redirected to
windir\syswow64\... file - Helps side-by-side system files installation and
compatibility - Some directories are exempted from redirection
- Dont contain bitness-sensitive data
- windir\system32\spool
- windir\system32\catroot
- windir\system32\catroot2
- windir\system32\drivers\etc
14WoW64 File System Redirection
- Turned ON by default for allWoW64 applications
- Can be controlled through Wow64EnableWow64FsRedire
ction() - Exists on platforms starting with Windows Server
2003 - Fails on non 64-bit platforms
- Helpful for many 32-bit applications, e.g., Virus
Scanners
BOOLEAN Wow64EnableWow64FsRedirection ( IN
BOOLEAN Wow64FsEnableRedirection )
15WoW64 File System Redirection
HANDLE File
WIN32_FIND_DATA FindData BOOLEAN bRet
// // Disable WoW64 file system
redirection // bRet
Wow64EnableWow64FsRedirection (FALSE)
File FindFirstFileA ("windir\\system32\\.",
FindData) do . .
. while (FindNextFileA (File,
FindData) ! 0) FindClose (File)
// // Enable WoW64 file-system
redirection // if (bRet
TRUE) Wow64EnableWow64FsRedirecti
on (TRUE)
1632-Bit I/O On 64-Bit Windows
- Kernel is native on 64-bit Windows and so are
all kernel drivers - 32-bit kernel device drivers wont run on 64-bit
Windows - Need to be ported
- WoW64 cant handle I/O buffer for
NtDeviceIoControlFile() - I/O buffer is only known to the device driver
- Two or more device drivers can use the same IOCTL
with different I/O buffers interpretation - 64-bit device drivers needs to support I/O
requests from WoW64 applications
1732-Bit I/O On 64-Bit Windows
- So if the 64-bit kernel device driver
- Receives IOCTLs from user mode applications
- And it supports 32-bit and 64-bit applications
- And the I/O structures are pointer-dependent or
requirea specific alignment - Then the 64-bit kernel device driver needs
tosupport WoW64 - What does a kernel device driver need to do
tosupport WoW64? - In your IRP_MJ_DEVICE_CONTROL handler, detect if
the I/O Request Packet (IRP) originated from a
WoW64 application - Use IoIs32bitProcess() exported from ntoskrnl
- Convert 32-bit structures into 64-bit
1832-Bit I/O On 64-Bit Windows
BOOLEAN IoIs32bitProcess( IN PIRP Irp
OPTIONAL ) / Routine Description
This API returns TRUE if the process that
originated the IRP is running a 32 bit x86
application. If there is no IRP then a NULL can
be passed to the API and that implies that the
current process context is used to test if its
running a 32 bit x86 application. Its assumed a
NULL will be passed by drivers executing in the
fast io path. Arguments IRP
OPTIONAL. Return Value TRUE if the process
is WoW64, otherwise FALSE. --/
1932-Bit I/O On 64-Bit Windows
- Real sample code from fastfat.sys driver
- MOVE_FILE_DATA is pointer-dependent
- structure size is different when compiled by a
32-bit or a 64-bit application
typedef struct HANDLE FileHandle
LARGE_INTEGER StartingVcn LARGE_INTEGER
StartingLcn ULONG ClusterCount
MOVE_FILE_DATA, PMOVE_FILE_DATA
NTSTATUS FatUserFsCtrl ( IN PIRP_CONTEXT
IrpContext, IN PIRP Irp
) . . PIO_STACK_LOCATION IrpSp
IoGetCurrentIrpStackLocation( Irp ) switch
(IrpSp-gtParameters.FileSystemControl.FsControlCode
) . . case FSCTL_MOVE_FILE Status
FatMoveFile( IrpContext, Irp ) break
2032-Bit I/O On 64-Bit Windows
NTSTATUS FatMoveFile ( IN PIRP_CONTEXT
IrpContext, IN PIRP Irp ) . .
InputBuffer (PMOVE_FILE_DATA)
Irp-gtAssociatedIrp.SystemBuffer // //
Do a quick check on the input buffer. //
if (InputBuffer NULL (InputBufferLength lt
sizeof(MOVE_FILE_DATA))
FatCompleteRequest( IrpContext, Irp,
STATUS_BUFFER_TOO_SMALL) return
STATUS_BUFFER_TOO_SMALL
TargetCluster InputBuffer-gtStartingLcn.LowPart
2 . .
2132-Bit I/O On 64-Bit Windows
NTSTATUS FatMoveFile ( IN PIRP_CONTEXT
IrpContext, IN PIRP Irp ) if
defined(_WIN64) MOVE_FILE_DATA
LocalMoveFileData PMOVE_FILE_DATA32
MoveFileData32 endif InputBuffer
(PMOVE_FILE_DATA)Irp-gtAssociatedIrp.SystemBuffer
if defined(_WIN64) if (IoIs32bitProcess(
Irp )) if (InputBuffer NULL
InputBufferLength lt sizeof(MOVE_FILE_DATA32))
FatCompleteRequest( IrpContext, Irp,
STATUS_BUFFER_TOO_SMALL ) return
STATUS_BUFFER_TOO_SMALL
MoveFileData32 (PMOVE_FILE_DATA32)
InputBuffer LocalMoveFileData.FileHandle
(HANDLE) LongToHandle( MoveFileData32- gtFileHand
le ) LocalMoveFileData.StartingVcn
MoveFileData32-gtStartingVcn
LocalMoveFileData.StartingLcn
MoveFileData32-gtStartingLcn
LocalMoveFileData.ClusterCount
MoveFileData32-gtClusterCount
InputBuffer LocalMoveFileData else
endif if (InputBuffer NULL
InputBufferLength lt sizeof(MOVE_FILE_DATA))
FatCompleteRequest( IrpContext, Irp,
STATUS_BUFFER_TOO_SMALL ) return
STATUS_BUFFER_TOO_SMALL if
defined(_WIN64) endif TargetCluster
InputBuffer-gtStartingLcn.LowPart 2
typeset struct HANDLE FileHandle
LARGE_INTEGER StartingVcn LARGE_INTEGER
StartingLcn ULONG ClusterCount
MOVE_FILE_DATA, PMOVE_FILE_DATA if
defined(_WIN64) // // 32/64 Bit thunking
support // structure // typedef struct
_MOVE_FILE_DATA32 UINT32 FileHandle
LARGE_INTEGER StartingVcn LARGE_INTEGER
StartingLcn ULONG ClusterCount
MOVE_FILE_DATA32, PMOVE_FILE_DATA32 endif
2232/64 Inter-Op Issues
- Pointer data type storage is 64-bit (8 bytes) on
64-bit Windows systems while it is 32-bits (4
bytes) on 32-bit Windows systems - Alignment is different as well
- Example
- Client/Server application set communicating using
shared memory - Client is 32-bit running on 64-bit Windows and
server is 64-bit or vice versa - Shared structures are pointer-dependent
- Two solutions
- 32-bit Client writes compatible 64-bit structures
- 64-bit Server doesnt need to be WoW64 aware
- 64-bit Server reads 32-bit and 64-bit structures
- 64-bit Server is WoW64 aware
- 32-bit Client may need to change if source
request is not known to the 64-bit server
2332/64 Inter-Op Issues
- Solution 1 Changing 32-bit client code
- 32-bit client checks to see if it is running
inside WoW64 - IsWow64Process() detects the process type
- Writes the appropriate structure based on which
OS it is running on
typedef struct _SERVER_REQUEST HANDLE
ThreadHandle PVOID DataBaseAddress ULONG
Count SERVER_REQUEST, PSERVER_REQUEST if
!defined(_WIN64) typedef struct _SERVER_REQUEST64
LONGLONG ThreadHandle ULONGLONG
DataBaseAddress ULONG Count
SERVER_REQUEST64, PSERVER_REQUEST64 endif
BOOLEAN SendServerRequest (PSERVER_REQUEST Rq)
if !defined(_WIN64) SERVER_REQUEST64
Rq64 BOOL WoW64Process endif PVOID p
(PVOID) Rq ULONG size sizeof
(SERVER_REQUEST) if !defined(_WIN64) if
((IsWow64Process (GetCurrentProcess(),
WoW64Process) TRUE) (WoW64Process
TRUE)) Rq64.ThreadHandle
(LONGLONG)Rq-gtThreadHandle
Rq64.DataBaseAddress (ULONGLONG)(ULONG)
Rq-gtDataBaseAddress Rq64.Count
Rq-gtCount p (PVOID) Rq64 size
sizeof (SERVER_REQUEST64) endif return
WriteRequestToSharedMem (p, size)
2432/64 Inter-Op Issues
- Solution 2 Changing 64-bit server code
- 64-bit server checks the source process of the
request message - 64-bit server reads structure based on process
type
typedef struct _SERVER_REQUEST HANDLE
ThreadHandle PVOID DataBaseAddress ULONG
Count SERVER_REQUEST, PSERVER_REQUEST if
defined(_WIN64) typedef struct _SERVER_REQUEST32
LONG ThreadHandle ULONG DataBaseAddress ULO
NG Count SERVER_REQUEST32, PSERVER_REQUEST32
endif
BOOLEAN ProcessServerRequest (PSERVER_REQUEST
Rq, HANDLE SourceProcess) if
defined(_WIN64) PSERVER_REQUEST32 Rq32 BOOL
WoW64Process endif PVOID p HANDLE h ULONG
count if defined(_WIN64) if ((IsWow64Process
(SourceProcess, WoW64Process) TRUE)
(WoW64Process TRUE)) Rq32
(PSERVER_REQUEST32) Rq h LongToHandle
(Rq32-gtThreadHandle) p UlongToPtr
(Rq32-gtDataBaseAddress) count
Rq32-gtCount else endif
DataBaseAddress Rq-gtDataBaseAddress count
Rq-gtCount h Rq-gtThreadHandle if
defined(_WIN64) endif return ReadClientData
(SourceProcess, DataBaseAddress, count, h)
2532/64 Inter-Op Issues
- Dont pass addresses above 2GB (or 4GB) to a
WoW64 application - How to convert data types?
26WoW64 Platform-Specific Support
- GetNativeSystemInfo() retreives information about
the native system - No 16-bit support on 64-bit Windows
- Win32 APIs for 16-bit support are stubbed out to
fail - 32-bit kernel drivers wont run on 64-bit Windows
- Needs to be ported and support WoW64
- WoW64 emulates Win32 applications running on x86
hardware - Target 64-bit platform may not support specific
features - Different levels of WoW64 support
27WoW64 Platform-Specific Support
28WoW64 Debugging
- GetThreadContext() and SetThreadContext() works
if the target process of the same type - Use user-mode 32-bit debugger to debug WoW64
applications - Debug as if you are running on a native 32-bit
Windows OS - Visual C 6.0
- User mode debuggers (e.g. ntsd.exe)
- Or any other 32-bit debugger package
- View only 32-bit loaded modules
- Can not be used to debug native 64-bit
applications - Use user-mode 64-bit debugger to debug inside
WoW64s 64-bit code - WoW64 debugger extensions comes with Microsoft
debugging tools - Allows to switch between 32-bit and 64-bit modes
using !sw command - View all loaded modules (32-bit and 64-bit)
- Can debug WoW64 as well as native 64-bit
applications
29Server SP1/AMD64
- Support for
- Running 32-bit ASP pages
- .NET Framework 1.1
- Managed code support
- Run managed ASP.NET
- Visual Studio .NET 2003
30Resources
- Links
- http//msdn.microsoft.com
- WoW64 implementation details
- http//msdn.microsoft.com/library/en-us/win64/win6
4/wow64_implementation_details.asp?frametrue - WoW64 debugging
- http//msdn.microsoft.com/library/default.asp?url
/library/en-us/win64/win64/debugging_wow64.asp - Porting your driver to Win64
- http//msdn.microsoft.com/library/default.asp?url
/library/en-us/kmarch/hh/kmarch/other_53mv.asp - Debugging tools
- http//www.microsoft.com/whdc/ddk/debugging/
31Community Resources
- Community Sites
- http//www.microsoft.com/communities/default.mspx
- List of Newsgroups
- http//communities2.microsoft.com/communities/news
groups/en-us/default.aspx - Attend a free chat or webcast
- http//www.microsoft.com/communities/chats/default
.mspx - http//www.microsoft.com/seminar/events/webcasts/d
efault.mspx - Locate a local user group(s)
- http//www.microsoft.com/communities/usergroups/de
fault.mspx - Non-Microsoft Community Sites
- http//www.microsoft.com/communities/related/defau
lt.mspx
32(No Transcript)