13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; $Id$
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;; @file
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; VirtualBox Support Library - Hardened main(), Windows assembly bits.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; Copyright (C) 2012-2014 Oracle Corporation
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; available from http://www.virtualbox.org. This file is free software;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; you can redistribute it and/or modify it under the terms of the GNU
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; General Public License (GPL) as published by the Free Software
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; The contents of this file may alternatively be used under the terms
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; of the Common Development and Distribution License Version 1.0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; VirtualBox OSE distribution, in which case the provisions of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; CDDL are applicable instead of those of the GPL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; You may elect to license modified versions of this file under the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync; terms and conditions of either the GPL or the CDDL or both.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;* Header Files *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync;*******************************************************************************
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync%define RT_ASM_WITH_SEH64
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync%include "iprt/asmdefs.mac"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync; External code.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsyncextern NAME(supR3HardenedEarlyProcessInit)
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncBEGINCODE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync;;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync; Alternative code for LdrInitializeThunk that performs the early process startup
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync; for the Stub and VM processes.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync; This does not concern itself with any arguments on stack or in registers that
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync; may be passed to the LdrIntializeThunk routine as we just save and restore
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync; them all before we restart the restored LdrInitializeThunk routine.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync; @sa supR3HardenedEarlyProcessInit
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsyncBEGINPROC supR3HardenedEarlyProcessInitThunk
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Prologue.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Reserve space for the "return" address.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push 0
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Create a stack frame, saving xBP.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push xBP
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync SEH64_PUSH_xBP
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov xBP, xSP
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync SEH64_SET_FRAME_xBP 0 ; probably wrong...
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Save all volatile registers.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push xAX
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push xCX
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push xDX
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync%ifdef RT_ARCH_AMD64
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push r8
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push r9
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push r10
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync push r11
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync%endif
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Reserve spill space and align the stack.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync sub xSP, 20h
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync and xSP, ~0fh
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync SEH64_END_PROLOGUE
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Call the C/C++ code that does the actual work. This returns the
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; resume address in xAX, which we put in the "return" stack position.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync call NAME(supR3HardenedEarlyProcessInit)
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov [xBP + xCB], xAX
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Restore volatile registers.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov xAX, [xBP - xCB*1]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov xCX, [xBP - xCB*2]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov xDX, [xBP - xCB*3]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync%ifdef RT_ARCH_AMD64
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov r8, [xBP - xCB*4]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov r9, [xBP - xCB*5]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov r10, [xBP - xCB*6]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync mov r11, [xBP - xCB*7]
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync%endif
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; Use the leave instruction to restore xBP and set up xSP to point at
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; the resume address. Then use the 'ret' instruction to resume process
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ; initializaton.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync leave
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync ret
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsyncENDPROC supR3HardenedEarlyProcessInitThunk
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync;;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync; Composes a standard call name.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%ifdef RT_ARCH_X86
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync %define SUPHNTIMP_STDCALL_NAME(a,b) _ %+ a %+ @ %+ b
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%else
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync %define SUPHNTIMP_STDCALL_NAME(a,b) NAME(a)
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%endif
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
d6774203fd1e13a9d1787611e48adfdd4a2d6834vboxsync;; Concats two litterals.
d6774203fd1e13a9d1787611e48adfdd4a2d6834vboxsync%define SUPHNTIMP_CONCAT(a,b) a %+ b
d6774203fd1e13a9d1787611e48adfdd4a2d6834vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync;;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync; Import data and code for an API call.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync; @param 1 The plain API name.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync; @param 2 The parameter frame size on x86. Multiple of dword.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync; @param 3 Non-zero expression if system call.
30f07af559efcbd967e801903746fc21f81ee533vboxsync; @param 4 Non-zero expression if early available call
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%define SUPHNTIMP_SYSCALL 1
30f07af559efcbd967e801903746fc21f81ee533vboxsync%macro SupHardNtImport 4
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ; The data.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncBEGINDATA
74f7805911fff84c2dec0fb3b727ef9ddc4df8b0vboxsyncglobal __imp_ %+ SUPHNTIMP_STDCALL_NAME(%1,%2) ; The import name used via dllimport.
74f7805911fff84c2dec0fb3b727ef9ddc4df8b0vboxsync__imp_ %+ SUPHNTIMP_STDCALL_NAME(%1,%2):
74f7805911fff84c2dec0fb3b727ef9ddc4df8b0vboxsyncGLOBALNAME g_pfn %+ %1 ; The name we like to refer to.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync RTCCPTR_DEF 0
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%if %3
74f7805911fff84c2dec0fb3b727ef9ddc4df8b0vboxsyncGLOBALNAME g_uApiNo %+ %1
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync RTCCPTR_DEF 0
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%endif
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ; The code: First a call stub.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncBEGINCODE
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncglobal SUPHNTIMP_STDCALL_NAME(%1, %2)
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncSUPHNTIMP_STDCALL_NAME(%1, %2):
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync jmp RTCCPTR_PRE [NAME(g_pfn %+ %1) xWrtRIP]
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%if %3
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ; Make system calls.
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ;
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync %ifdef RT_ARCH_AMD64
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncBEGINPROC %1 %+ _SyscallType1
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync SEH64_END_PROLOGUE
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov r10, rcx
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync syscall
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ret
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncENDPROC %1 %+ _SyscallType1
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync %else
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncBEGINPROC %1 %+ _SyscallType1
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov edx, 07ffe0300h ; SharedUserData!SystemCallStub
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
0b8ed19cf8df49d6fcd144b43ae4af5c21316ce9vboxsync call dword [edx]
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ret %2
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncENDPROC %1 %+ _SyscallType1
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncBEGINPROC %1 %+ _SyscallType2
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync push .return
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov edx, esp
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync sysenter
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync add esp, 4
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync.return:
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync ret %2
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsyncENDPROC %1 %+ _SyscallType2
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync %endif
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%endif
30f07af559efcbd967e801903746fc21f81ee533vboxsync
30f07af559efcbd967e801903746fc21f81ee533vboxsync%if %4 == 0
4b54bc4334bafab3a2fb62746e675703dcb19f00vboxsyncglobal NAME(SUPHNTIMP_CONCAT(%1,_Early))
4b54bc4334bafab3a2fb62746e675703dcb19f00vboxsyncNAME(SUPHNTIMP_CONCAT(%1,_Early)):
30f07af559efcbd967e801903746fc21f81ee533vboxsync int3
30f07af559efcbd967e801903746fc21f81ee533vboxsync %ifdef RT_ARCH_AMD64
30f07af559efcbd967e801903746fc21f81ee533vboxsync ret
30f07af559efcbd967e801903746fc21f81ee533vboxsync %else
30f07af559efcbd967e801903746fc21f81ee533vboxsync ret %2
30f07af559efcbd967e801903746fc21f81ee533vboxsync %endif
30f07af559efcbd967e801903746fc21f81ee533vboxsync%endif
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%endmacro
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%define SUPHARNT_COMMENT(a_Comment)
30f07af559efcbd967e801903746fc21f81ee533vboxsync%define SUPHARNT_IMPORT_SYSCALL(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, SUPHNTIMP_SYSCALL, 1
79a6b20f984859d9cc49305172355d6c3901f1c5vboxsync%define SUPHARNT_IMPORT_STDCALL(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, 0, 0
79a6b20f984859d9cc49305172355d6c3901f1c5vboxsync%define SUPHARNT_IMPORT_STDCALL_EARLY(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, 0, 1
79a6b20f984859d9cc49305172355d6c3901f1c5vboxsync%define SUPHARNT_IMPORT_STDCALL_EARLY_OPTIONAL(a_Name, a_cbParamsX86) SUPHARNT_IMPORT_STDCALL_EARLY(a_Name, a_cbParamsX86)
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%include "import-template-ntdll.h"
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync%include "import-template-kernel32.h"
d1e6154d21dcc739e31ac7d8b139ee0fdfe60d45vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync; For simplified LdrLoadDll patching we define a special writable, readable and
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync; exectuable section of 4KB where we can put jump back code.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsyncsection .rwxpg bss execute read write align=4096
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsyncGLOBALNAME g_abSupHardReadWriteExecPage
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync resb 4096
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync