340 likes | 706 Views
WINE. Windows NT Architecture. WINE Architecture. socket. pipe. Wine Directory Structure. server/ wineserver Windows abstract object (mailslot, mutex, … etc) dlls/ Windows DLL loader/ Wine call a preloader to reserve memory space for Windows application. Wine Overview. Windows App.
E N D
WINE Architecture socket pipe
Wine Directory Structure • server/ • wineserver • Windows abstract object (mailslot, mutex, … etc) • dlls/ • Windows DLL • loader/ • Wine call a preloader to reserve memory space for Windows application
Wine Overview Windows App wineserver Windows EXE Kernel32.DLL socket NTDLL.DLL pipe • Client send request to wineserver through the pipe • winserver poll request then call corresponding handler
Load Windows Binary - Part 1 • Example • wine → wine_preloader → wine → notepad.exe • They are the same process but with different image • wine check a environment variable too see if preloader already ran before, and when wine_preloader finish its job, it reload wine image and start to load Windows application (i.e., notepad.exe)
Load Windows Binary - Part 1 • wine_preloader • Use customized entry function _start • _start call wld_start to reserve memory space for Windows PE binary, then jump to dynamic linker return by wld_start
Load Windows Binary - Part 2 • Since preloader already ran, we are ready to start the real and complicate job • wine → wine_preloader → wine → notepad.exe
Load Windows Binary - Part 2 • wine → wine_init • wine_init → __wine_process_init (NTDLL.DLL) • __wine_process_init →__wine_kernel_init (Kernel32.DLL) • __wine_kernel_init → start_process • start_process → notepad.exe
Load Windows Binary - Part 2 • wine_init (libs/wine/loader.c) • Set up DLL path so that wine can load correct DLL it want • Load built-in NTDLL.DLL. Built-in DLL contains standard WinAPI and wine internal functions • Get address of function __wine_process_init from built-in BTDLL.DLL • Run __wine_process_init
Load Windows Binary - Part 2 • wine_process_init(dlls/ntdll/loader.c) • Call function thread_init to initialize TEB, PEB and other environment for Windows application. Launch winserver if needed and set up connection to the winserver • Load built-in Kernel32.DLL • Get address of function __wine_kernel_init from built-in Kernel32.DLL
Load Windows Binary - Part 2 • wine_kernel_init • Initialize things like register this Windows application to wineserver, set up current directory and environment parameters • Load image of Windows application
Load Windows Binary - Part 2 • start_process • LdrInitializeThunk loads remaining DLL needed by the target Windows application • Jump to Windows application entry point and kick off • All WinAPI called by Windows application will be directed to Wine’s version
Implement Win32/NT API • Three examples • CreateProcess • OpenFile • WriteFile • Most of them are implement through POSIX API with emulation • Some of them call POSIX API at client side, others are at wineserver side
CreateProcess Windows App wineserver CreateProcessW (dlls/kernel32/process.c) create_process_impl (dlls/kernel32/process.c) create_process (dlls/kernel32/process.c) req_new_process (server/process.c) create_process (server/process.c) exec_loader (dlls/kernel32/process.c) fork →wine_exec_wine_binary
OpenFile Windows App wineserver OpenFile (dlls/kernel32/file.c) req_create_file (server/file.c) create_file (server/file.c) NtCreateFile (dlls/ntdll/file.c) struct fd *open_fd (server/fd.c) FILE_CreateFile (dlls/ntdll/file.c) fd->unix_fd = open( … ); reply->handle = alloc_handle( … );
File • Windows app does not own the file it creates by using WinAPI like OpenFile/CreateFile • OpenFile/CreateFile send request to wineserver • wineserver uses open to create a UNIX file descriptor, associated it with <windows process, handle> pair • Windows app only see a fake Windows file handle returned by wineserver
WriteFile Windows App wineserver WriteFile (dlls/kernel32/file.c) req_get_handle_fd (server/fd.c) NtWriteFile (dlls/ntdll/file.c) get_handle_fd_obj (server/fd.c) server_get_unix_fd (dlls/ntdll/server.c) send_client_fd (server/request.c) receive_fd (dlls/ntdll/server.c) write(fd …);
WriteFile Windows App wineserver wineserver gives the file descriptor access right temporarily User space Kernel space file
Cygwin Overview C library which provides a POSIX-style API
Cygwin Overview UNIX App cygwin1.dll newlibc (C runtime) Kernel32.DLL NTDLL.DLL
What Cygwin Is? • Cygwin includes two parts • Provide tools like gcc, make, … etc, let you compile UNIX source code into Windows executable • Provide cygwin1.dll which acts as a Linux API layer on Windows
fork fork (cygwin/fork.cc) frok:: parent (cygwin/fork.cc) CreateProcessW (Win32 API) • Win32 API receive more parameters then POSIX API, make up those • parameters
open • UNIX provides uniform interfaces like open/close/read/write to access devices • Windows provides various interfaces for different devices • cygwin glue them by using Class fhandler_base open (cygwin/syscalls.cc) build_fh_name (cygwin/dtable.cc)
open • cygwin glue them by providing a abstract layer: class fhandler_base virtual int ioctl (unsigned int cmd, void *); virtual int fcntl (int cmd, void *); virtual char const *ttyname () { return get_name (); } virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); virtual ssize_t __stdcall write (const void *ptr, size_t len);
open • cygwin glue them by providing a abstract layer: class fhandler_base virtual int ioctl (unsigned int cmd, void *); virtual int fcntl (int cmd, void *); virtual char const *ttyname () { return get_name (); } virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); virtual ssize_t __stdcall write (const void *ptr, size_t len);
open open (cygwin/syscalls.cc) build_fh_name (cygwin/dtable.cc) fhandler_disk_file::open (cygwin/ fhandler_disk_file.cc) NtCreateFile fhandler_base::open_fs (cygwin/ fhandler_disk_file.cc) fhandler_base::open (cygwin/fhandler.cc) Need to deal with different path convention between UNIX and Windows
Design & Implementation Strategy • Both WINE and Cygwin are API compatibility layers, WinAPI-to-POSIX or vise versa (with a little different) • WINE provides binary level compatibility • You don’t have to compile Windows source code • Since you usually can’t get the source code • Cygwin provides source level compatibility • You use GCC (Windows port) provided by Cygwin to compile UNIX source code
Design & Implementation Strategy • Both implement their own .so or DLL, which do API conversion, or vise versa • Wine need to implement its own PE loader/dynamic linker, since it achieve binary level compatibility
Goal • Thedesign and implementation strategy of these systems • The whole procedure from inputting guest app all the way to generating the host code • One process management example • One memory management example (or file system, network, device) to explain the procedure