SUPDrv-win.cpp revision 0bb0cb486421e43139aebdcd234cf9a219f16531
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VBoxDrv - The VirtualBox Support Driver - Windows NT specifics.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (C) 2006-2012 Oracle Corporation
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * available from http://www.virtualbox.org. This file is free software;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * General Public License (GPL) as published by the Free Software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The contents of this file may alternatively be used under the terms
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * of the Common Development and Distribution License Version 1.0
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution, in which case the provisions of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * CDDL are applicable instead of those of the GPL.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * You may elect to license modified versions of this file under the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * terms and conditions of either the GPL or the CDDL or both.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Header Files *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Defined Constants And Macros *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** The support service name. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** The Pool tag (VBox). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** NT device name for system access. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** NT device name for user access. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** NT device name for hardened stub access. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync# define DEVICE_NAME_NT_STUB L"\\Device\\VBoxDrvStub"
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Macro for checking for deflecting calls to the stub device. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) \
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync do { if ((a_pDevObj) == g_pDevObjStub) supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); } while (0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) do {} while (0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Enables the fast I/O control code path. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync* Structures and Typedefs *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * Device extension used by VBoxDrvU.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Global cookie (same location as in SUPDRVDEVEXT, different value). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Pointer to the main driver extension. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncAssertCompileMembersAtSameOffset(SUPDRVDEVEXT, u32Cookie, SUPDRVDEVEXTUSR, u32Cookie);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to the VBoxDrvU device extension. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/** Value of SUPDRVDEVEXTUSR::u32Cookie. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Get the main device extension. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync : ((PSUPDRVDEVEXTUSR)pDevObj->DeviceExtension)->pMainDrvExt )
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Device extension used by VBoxDrvS.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Common header. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to the VBoxDrvS device extension. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Value of SUPDRVDEVEXTSTUB::Common.u32Cookie. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define SUPDRVDEVEXTSTUB_COOKIE UINT32_C(0x90abcdef)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The kind of process we're protecting.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Stub process protection while performing process verification.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Next: StubSpawning (or free) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Stub process protection before it creates the VM process.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Next: StubParent, StubDead. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Stub process protection while having a VM process as child.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Next: StubDead */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Dead stub process. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** Potential VM process.
a2179871c3ee5a00079f273fbc72b6e2d704c68dvboxsync * Next: VmProcessConfirmed, VmProcessDead. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** Confirmed VM process.
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * Next: VmProcessDead. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** Dead VM process. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** End of valid protection kinds. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * A NT process protection structure.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** The AVL node core structure. The process ID is the pid. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Magic value (SUPDRVNTPROTECT_MAGIC). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Reference counter. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** The kind of process we're protecting. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle returned by
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle returned by
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** 8.1: Hack to allow more rights to the handle returned by
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle duplicated by CSR
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * during process creation. Only applicable to VmProcessUnconfirmed. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** 7,: Hack to allow the supid themes service duplicate handle privileges to
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * our process. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** The parent PID for VM processes, otherwise NULL. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** The PID of the CSRSS process associated with this process. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** Pointer to the CSRSS process structure (referenced). */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** State dependent data. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** A stub process in the StubParent state will keep a reference to a child
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * while it's in the VmProcessUnconfirmed state so that it can be cleaned up
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * correctly if things doesn't work out. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync /** A process in the VmProcessUnconfirmed state will keep a weak
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * reference to the parent's protection structure so it can clean up the pChild
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync * refernece the parent has to it. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/** Pointer to a NT process protection record. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/** The SUPDRVNTPROTECT::u32Magic value (Robert A. Heinlein). */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/** The SUPDRVNTPROTECT::u32Magic value of a dead structure. */
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync# define SUPDRVNTPROTECT_MAGIC_DEAD UINT32_C(0x19880508)
1e29d016a09a61485fda74f7fca39e171ff5dda8vboxsync/** Pointer to ObGetObjectType. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef POBJECT_TYPE (NTAPI *PFNOBGETOBJECTTYPE)(PVOID);
31771163041e3661403a806eb3382d2a165c003bvboxsync/** Pointer to ObRegisterCallbacks. */
e3ddc294f1a80edb513f054d4c24ab79d7dfd3ddvboxsynctypedef NTSTATUS (NTAPI *PFNOBREGISTERCALLBACKS)(POB_CALLBACK_REGISTRATION, PVOID *);
e3ddc294f1a80edb513f054d4c24ab79d7dfd3ddvboxsync/** Pointer to ObUnregisterCallbacks. */
31771163041e3661403a806eb3382d2a165c003bvboxsynctypedef VOID (NTAPI *PFNOBUNREGISTERCALLBACKS)(PVOID);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to PsSetCreateProcessNotifyRoutineEx. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef NTSTATUS (NTAPI *PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)(PCREATE_PROCESS_NOTIFY_ROUTINE_EX, BOOLEAN);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to PsReferenceProcessFilePointer. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef NTSTATUS (NTAPI *PFNPSREFERENCEPROCESSFILEPOINTER)(PEPROCESS, PFILE_OBJECT *);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to PsIsProtectedProcessLight. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef BOOLEAN (NTAPI *PFNPSISPROTECTEDPROCESSLIGHT)(PEPROCESS);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to ZwAlpcCreatePort. */
7220367ea1944fa8a7694534401321ad86eb70c6vboxsynctypedef NTSTATUS (NTAPI *PFNZWALPCCREATEPORT)(PHANDLE, POBJECT_ATTRIBUTES, struct _ALPC_PORT_ATTRIBUTES *);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#endif /* VBOX_WITH_HARDENINIG */
#ifdef VBOXDRV_WITH_FAST_IO
static BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput,
static int VBoxDrvNtDeviceControlSlow(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PIRP pIrp, PIO_STACK_LOCATION pStack);
static VOID _stdcall VBoxPowerDispatchCallback(PVOID pCallbackContext, PVOID pArgument1, PVOID pArgument2);
#ifdef VBOX_WITH_HARDENING
static void supdrvNtProtectTerm(void);
static bool supdrvNtIsDebuggerAttached(void);
#ifdef VBOXDRV_WITH_FAST_IO
#ifdef VBOX_WITH_HARDENING
# ifdef RT_ARCH_AMD64
NTSTATUS rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjSys);
rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTUSR), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjUsr);
#ifdef VBOX_WITH_HARDENING
rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTSTUB), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjStub);
return rcNt;
#ifdef VBOX_WITH_HARDENING
return rcNt;
static void vboxdrvNtDestroyDevices(void)
if (g_pDevObjUsr)
#ifdef VBOX_WITH_HARDENING
if (g_pDevObjStub)
#ifdef VBOX_WITH_HARDENING
#ifdef VBOXDRV_WITH_FAST_IO
return STATUS_INTERNAL_ERROR;
#ifdef VBOX_WITH_HARDENING
if (!vrc)
#ifdef VBOXDRV_WITH_FAST_IO
return STATUS_SUCCESS;
#ifdef VBOX_WITH_HARDENING
RTR0Term();
return rcNt;
#ifdef VBOX_WITH_HARDENING
RTR0Term();
return rcNt;
#ifdef VBOX_WITH_HARDENING
LogRel(("vboxdrv: Declined %p access to VBoxDrvStub: rc=%d\n", PsGetProcessId(PsGetCurrentProcess()), rc));
if (pNtProtect)
&pSession);
rc = supdrvCreateSession(pDevExt, true /*fUser*/, pDevObj == g_pDevObjSys /*fUnrestricted*/, &pSession);
return supdrvNtCompleteRequest(rcNt, pIrp); /* Note. the IoStatus is completely ignored on error. */
#ifdef VBOX_WITH_HARDENING
if (pNtProtect)
if (pSession)
#ifdef VBOX_WITH_HARDENING
if (pNtProtect)
if (pSession)
#ifdef VBOXDRV_WITH_FAST_IO
static BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput,
if (!pSession)
return TRUE;
if (supdrvNtIsDebuggerAttached())
return TRUE;
return TRUE;
unsigned cbOut = 0;
int rc = 0;
Log2(("VBoxDrvNtFastIoDeviceControl(%p): ioctl=%#x pvIn=%p cbIn=%#x pvOut=%p cbOut=%#x pSession=%p\n",
# ifdef RT_ARCH_AMD64
if (pHdr)
if (cbOut)
# ifdef RT_ARCH_AMD64
if (supdrvNtIsDebuggerAttached())
int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession);
static int VBoxDrvNtDeviceControlSlow(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PIRP pIrp, PIO_STACK_LOCATION pStack)
unsigned cbOut = 0;
int rc = 0;
#ifdef RT_ARCH_AMD64
if (!rc)
#ifdef RT_ARCH_AMD64
return rcNt;
unsigned cbOut = 0;
int rc = 0;
: !pSession
if (!rc)
return rcNt;
return STATUS_NOT_SUPPORTED;
if ((unsigned)pArgument2 == 0)
#ifdef VBOX_WITH_HARDENING
void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
typedef struct MYSYSTEMGDIDRIVERINFO
int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
# ifndef RT_ARCH_X86
return VERR_NOT_SUPPORTED;
return rc;
if (!pwcsFilename)
return VERR_NO_TMP_MEMORY;
NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemLoadGdiDriverInSystemSpaceInformation, &Info, sizeof(Info));
Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer));
# ifdef DEBUG_bird
Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer);
rc = RTR0MemObjLockKernel(&pImage->hMemLock, pImage->pvImage, pImage->cbImageBits, RTMEM_PROT_READ);
switch (rcNt)
# ifdef RT_ARCH_AMD64
return rc;
int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
return VINF_SUCCESS;
static int supdrvNtCompare(PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, uint32_t uRva, uint32_t cb)
if (iDiff)
return iDiff;
int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
return VINF_SUCCESS;
&& pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size >= sizeof(IMAGE_IMPORT_DESCRIPTOR)
&& pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress > sizeof(IMAGE_NT_HEADERS)
&& pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress < pImage->cbImageBits
struct MyRegion
unsigned cExcludeRgns = 0;
/ sizeof(IMAGE_IMPORT_DESCRIPTOR);
while ( cImpsLeft-- > 0
cThunks++;
for (; i < cExcludeRgns; i++)
if (i != cExcludeRgns)
cExcludeRgns++;
pImp++;
int iDiff = 0;
if (!iDiff)
return VINF_SUCCESS;
return VERR_LDR_MISMATCH_NATIVE;
return VERR_INTERNAL_ERROR_4;
#ifdef SUPDRV_WITH_MSR_PROBER
typedef struct SUPDRVNTMSPROBERARGS
bool fGp;
return rc;
return VERR_ACCESS_DENIED;
return VINF_SUCCESS;
return rc;
return VERR_ACCESS_DENIED;
return VINF_SUCCESS;
bool fBeforeGp = true;
bool fModifyGp = true;
bool fAfterGp = true;
bool fRestoreGp = true;
if (!fFaster)
fBeforeGp = false;
fBeforeGp = true;
if (!fBeforeGp)
fModifyGp = false;
fModifyGp = true;
fAfterGp = false;
fAfterGp = true;
fRestoreGp = false;
fRestoreGp = true;
if (!fFaster)
ASMReloadCR3();
ASMNopPause();
return VINF_SUCCESS;
switch (rc)
if (rc < 0)
return STATUS_UNSUCCESSFUL;
#ifdef VBOX_WITH_HARDENING
if (!pszImageFile)
} Buf;
if (!chRight)
bool fDone = false;
InitializeObjectAttributes(&ObjAttr, &UniStrPortNm, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
if (pObjType)
fDone = true;
return fDone;
static POBJECT_TYPE supdrvNtProtectGetAlpcPortObjectType(uint32_t uSessionId, const char *pszSessionId)
int rc;
cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
if (!fDone)
if (!fDone)
if (uSessionId == 0)
cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
if (!fDone)
&& fDone)
return pObjType;
int rc;
if (uSessionId == 0)
&pvApiPortObj);
&pvApiPortObj);
&pvApiPortObj);
return rcNt == STATUS_OBJECT_TYPE_MISMATCH ? VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE : VERR_SUPDRV_APIPORT_OPEN_ERROR;
if (!pbBuf)
cbNeeded = 0;
if ( pbBuf
bool fThatsIt = false;
ppPortProc++;
fThatsIt = false;
if (fThatsIt)
return rc;
static bool supdrvNtProtectIsFrigginThemesService(PSUPDRVNTPROTECT pNtProtect, PEPROCESS pAnnoyingProcess)
#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
if (!pszImageFile)
static bool supdrvNtProtectIsSpawningStubProcess(PSUPDRVNTPROTECT pNtStub, HANDLE hParentPid, HANDLE hChildPid)
bool fRc = false;
return fRc;
int rc = supdrvNtProtectCreate(&pNtChild, hChildPid, kSupDrvNtProtectKind_VmProcessUnconfirmed, false /*fLink*/);
if (fSuccess)
return VINF_SUCCESS;
return rc;
if (pNtProtect)
if (g_pDevObjSys)
if (pSession)
static void supdrvNtProtectVerifyNewChildProtection(PSUPDRVNTPROTECT pNtStub, PSUPDRVNTPROTECT pNtVm, bool fCallerChecks)
if ( fCallerChecks
LogRel(("vboxdrv: Misdetected vm stub; hParentPid=%p hChildPid=%p\n", pNtStub->AvlCore.Key, pNtVm->AvlCore.Key));
if (fCreated)
if (pNtStub)
if (!pNtVm)
supdrvNtProtectCallback_ProcessCreateNotifyEx(PEPROCESS pNewProcess, HANDLE hNewPid, PPS_CREATE_NOTIFY_INFO pInfo)
if (pInfo)
pInfo->FileOpenNameAvailable && pInfo->ImageFileName ? (size_t)pInfo->ImageFileName->Length / 2 : 0,
if (pNtStub)
if (!pNtVm)
# define SUPDRV_NT_ALLOW_PROCESS_RIGHTS \
| PROCESS_VM_READ \
| DELETE \
| READ_CONTROL \
| SYNCHRONIZE)
# define SUPDRV_NT_EVIL_PROCESS_RIGHTS \
| PROCESS_VM_WRITE \
Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
if (!pNtProtect)
if (pNtStub)
if (pNtProtect)
#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
&& pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == 0x1478 /* 6.1.7600.16385 (win7_rtm.090713-1255) */
Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p wants %#x to %p/pid=%04zx [%d], allow %#x => %#x; %s [prev=%#x]\n",
Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n",
Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n",
return OB_PREOP_SUCCESS;
Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
/* From ntifs.h */
# define SUPDRV_NT_ALLOWED_THREAD_RIGHTS \
( THREAD_TERMINATE \
| DELETE \
| READ_CONTROL \
| SYNCHRONIZE)
# define SUPDRV_NT_EVIL_THREAD_RIGHTS \
Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
if (pNtProtect)
#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s [prev=%#x]\n",
Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] self\n",
Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s\n",
return OB_PREOP_SUCCESS;
Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
fGrantedAccess, SUPDRV_NT_ALLOWED_THREAD_RIGHTS, fGrantedAccess & ~SUPDRV_NT_ALLOWED_THREAD_RIGHTS));
static int supdrvNtProtectCreate(PSUPDRVNTPROTECT *ppNtProtect, HANDLE hPid, SUPDRVNTPROTECTKIND enmProcessKind, bool fLink)
if (!pNtProtect)
return VERR_NO_MEMORY;
if (fLink)
if (!fSuccess)
return VERR_DUPLICATE;
return VINF_SUCCESS;
if (!pNtProtect)
if (cRefs != 0)
PSUPDRVNTPROTECT pRemoved = (PSUPDRVNTPROTECT)RTAvlPVRemove(&g_NtProtectTree, pNtProtect->AvlCore.Key);
if (pChild)
if (!cChildRefs)
if (pChild)
if (pFound)
return pFound;
if (!pbBuf)
return VERR_NO_MEMORY;
# ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
const char *pszType;
# ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
if (fIsDebugger)
# ifndef VBOX_WITH_VISTA_NO_SP
return rc;
AssertReturn(PsGetProcessId(PsGetCurrentProcess()) == pNtProtect->AvlCore.Key, VERR_INTERNAL_ERROR_3);
rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
pNtProtect->enmProcessKind = RT_SUCCESS(rc) ? kSupDrvNtProtectKind_StubSpawning : kSupDrvNtProtectKind_StubDead;
return rc;
# ifndef VBOX_WITHOUT_DEBUGGER_CHECKS
static bool supdrvNtIsDebuggerAttached(void)
static void supdrvNtProtectTerm(void)
rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/);
# ifdef RT_ARCH_X86
g_pfnPsSetCreateProcessNotifyRoutineEx = (PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)MmGetSystemRoutineAddress(&RoutineName);
g_pfnPsReferenceProcessFilePointer = (PFNPSREFERENCEPROCESSFILEPOINTER)MmGetSystemRoutineAddress(&RoutineName);
g_pfnPsIsProtectedProcessLight = (PFNPSISPROTECTEDPROCESSLIGHT)MmGetSystemRoutineAddress(&RoutineName);
# ifdef RT_ARCH_X86
case 0xb0: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xAF; break; /* just in case */
case 0xb1: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB0; break; /* just in case */
case 0xb2: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB1; break; /* just in case */
case 0xb3: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* XP SP3 */
case 0xb4: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* just in case */
case 0xb5: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB3; break; /* just in case */
case 0xb6: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB4; break; /* just in case */
case 0xb7: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB5; break; /* just in case */
case 0xb8: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB6; break; /* just in case */
case 0xb9: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB7; break; /* just in case */
case 0xba: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB8; break; /* just in case */
case 0xbb: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBA; break; /* W2K3 R2 SP2 */
case 0xbc: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBB; break; /* just in case */
case 0xbd: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBC; break; /* just in case */
case 0xbe: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBD; break; /* just in case */
case 0xbf: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBE; break; /* just in case */
case 0x1e: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x1F; break;
case 0x1f: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x20; break;
case 0x20: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x21; break;
case 0x21: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x22; break;
case 0x22: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x23; break;
LogRel(("vboxdrv: Cannot locate ZwQueryVirtualMemory in ntoskrnl, nor were we able to cook up a replacement.\n"));
return STATUS_PROCEDURE_NOT_FOUND;
# ifdef VBOX_STRICT
LogRel(("vboxdrv: g_pfnObGetObjectType=%p g_pfnZwAlpcCreatePort=%p.\n", g_pfnObGetObjectType, g_pfnZwAlpcCreatePort));
return STATUS_PROCEDURE_NOT_FOUND;
rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, FALSE /*fRemove*/);
rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, FALSE /*fRemove*/);
for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszAltitudes) && rcNt == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; i++)
return STATUS_SUCCESS;
# ifndef VBOX_WITH_VISTA_NO_SP
DbgPrint("vboxdrv: ObRegisterCallbacks was not found. Please make sure you got the latest updates and service packs installed\n");
g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
return rcNt;