SUPDrv-win.cpp revision 9c3f9ad981f048b8343f47ec6155a91f6b740624
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync/* $Id$ */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @file
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * VBoxDrv - The VirtualBox Support Driver - Windows NT specifics.
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync */
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync/*
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * Copyright (C) 2006-2012 Oracle Corporation
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync *
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * General Public License (GPL) as published by the Free Software
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * The contents of this file may alternatively be used under the terms
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * of the Common Development and Distribution License Version 1.0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * VirtualBox OSE distribution, in which case the provisions of the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * CDDL are applicable instead of those of the GPL.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * You may elect to license modified versions of this file under the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * terms and conditions of either the GPL or the CDDL or both.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/*******************************************************************************
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync* Header Files *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync*******************************************************************************/
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define IPRT_NT_MAP_TO_ZW
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define LOG_GROUP LOG_GROUP_SUP_DRV
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include "../SUPDrvInternal.h"
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <excpt.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <ntimage.h>
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/assert.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/avl.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/ctype.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/initterm.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/mem.h>
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync#include <iprt/process.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/power.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/rand.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/spinlock.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/string.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <VBox/log.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <VBox/err.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#include <iprt/asm-amd64-x86.h>
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# include "SUPHardenedVerify-win.h"
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/*******************************************************************************
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync* Defined Constants And Macros *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync*******************************************************************************/
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** The support service name. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define SERVICE_NAME "VBoxDrv"
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** The Pool tag (VBox). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define SUPDRV_NT_POOL_TAG 'xoBV'
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** NT device name for system access. */
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync#define DEVICE_NAME_NT_SYS L"\\Device\\VBoxDrv"
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** NT device name for user access. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define DEVICE_NAME_NT_USR L"\\Device\\VBoxDrvU"
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync#ifdef VBOX_WITH_HARDENING
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync/** NT device name for hardened stub access. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync# define DEVICE_NAME_NT_STUB L"\\Device\\VBoxDrvStub"
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync/** Macro for checking for deflecting calls to the stub device. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) \
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync do { if ((a_pDevObj) == g_pDevObjStub) supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); } while (0)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync#else
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) do {} while (0)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync#endif
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync/** Enables the fast I/O control code path. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync#define VBOXDRV_WITH_FAST_IO
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/*******************************************************************************
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync* Structures and Typedefs *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync*******************************************************************************/
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Device extension used by VBoxDrvU.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsynctypedef struct SUPDRVDEVEXTUSR
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Global cookie (same location as in SUPDRVDEVEXT, different value). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t u32Cookie;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Pointer to the main driver extension. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pMainDrvExt;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync} SUPDRVDEVEXTUSR;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncAssertCompileMembersAtSameOffset(SUPDRVDEVEXT, u32Cookie, SUPDRVDEVEXTUSR, u32Cookie);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to the VBoxDrvU device extension. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsynctypedef SUPDRVDEVEXTUSR *PSUPDRVDEVEXTUSR;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Value of SUPDRVDEVEXTUSR::u32Cookie. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define SUPDRVDEVEXTUSR_COOKIE UINT32_C(0x12345678)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Get the main device extension. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define SUPDRVNT_GET_DEVEXT(pDevObj) \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ( pDevObj != g_pDevObjUsr \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ? (PSUPDRVDEVEXT)pDevObj->DeviceExtension \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync : ((PSUPDRVDEVEXTUSR)pDevObj->DeviceExtension)->pMainDrvExt )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync * Device extension used by VBoxDrvS.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef struct SUPDRVDEVEXTSTUB
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Common header. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SUPDRVDEVEXTUSR Common;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync} SUPDRVDEVEXTSTUB;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to the VBoxDrvS device extension. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef SUPDRVDEVEXTSTUB *PSUPDRVDEVEXTSTUB;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Value of SUPDRVDEVEXTSTUB::Common.u32Cookie. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define SUPDRVDEVEXTSTUB_COOKIE UINT32_C(0x90abcdef)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync/**
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * The kind of process we're protecting.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsynctypedef enum SUPDRVNTPROTECTKIND
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync{
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync kSupDrvNtProtectKind_Invalid = 0,
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Stub process protection while performing process verification.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Next: StubSpawning (or free) */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_StubUnverified,
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync /** Stub process protection before it creates the VM process.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * Next: StubParent, StubDead. */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync kSupDrvNtProtectKind_StubSpawning,
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync /** Stub process protection while having a VM process as child.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * Next: StubDead */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync kSupDrvNtProtectKind_StubParent,
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync /** Dead stub process. */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync kSupDrvNtProtectKind_StubDead,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Potential VM process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Next: VmProcessConfirmed, VmProcessDead. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_VmProcessUnconfirmed,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Confirmed VM process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Next: VmProcessDead. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_VmProcessConfirmed,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Dead VM process. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_VmProcessDead,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** End of valid protection kinds. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_End
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync} SUPDRVNTPROTECTKIND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * A NT process protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsynctypedef struct SUPDRVNTPROTECT
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The AVL node core structure. The process ID is the pid. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AVLPVNODECORE AvlCore;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Magic value (SUPDRVNTPROTECT_MAGIC). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t volatile u32Magic;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Reference counter. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t volatile cRefs;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** The kind of process we're protecting. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTPROTECTKIND volatile enmProcessKind;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle returned by
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fFirstProcessCreateHandle : 1;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle returned by
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fFirstThreadCreateHandle : 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** 8.1: Hack to allow more rights to the handle returned by
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fCsrssFirstProcessCreateHandle : 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Vista, 7 & 8: Hack to allow more rights to the handle duplicated by CSR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * during process creation. Only applicable to VmProcessUnconfirmed. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fCsrssFirstProcessDuplicateHandle : 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** 7,: Hack to allow the supid themes service duplicate handle privileges to
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * our process. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync bool fThemesFirstProcessCreateHandle : 1;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /** The parent PID for VM processes, otherwise NULL. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE hParentPid;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** The PID of the CSRSS process associated with this process. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE hCsrssPid;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /** Pointer to the CSRSS process structure (referenced). */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync PEPROCESS pCsrssProcess;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /** State dependent data. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync union
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /** A stub process in the StubParent state will keep a reference to a child
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * while it's in the VmProcessUnconfirmed state so that it can be cleaned up
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * correctly if things doesn't work out. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync struct SUPDRVNTPROTECT *pChild;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /** A process in the VmProcessUnconfirmed state will keep a weak
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * reference to the parent's protection structure so it can clean up the pChild
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * refernece the parent has to it. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync struct SUPDRVNTPROTECT *pParent;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync } u;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync} SUPDRVNTPROTECT;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to a NT process protection record. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef SUPDRVNTPROTECT *PSUPDRVNTPROTECT;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** The SUPDRVNTPROTECT::u32Magic value (Robert A. Heinlein). */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# define SUPDRVNTPROTECT_MAGIC UINT32_C(0x19070707)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** The SUPDRVNTPROTECT::u32Magic value of a dead structure. */
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync# define SUPDRVNTPROTECT_MAGIC_DEAD UINT32_C(0x19880508)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to ObGetObjectType. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef POBJECT_TYPE (NTAPI *PFNOBGETOBJECTTYPE)(PVOID);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to ObRegisterCallbacks. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef NTSTATUS (NTAPI *PFNOBREGISTERCALLBACKS)(POB_CALLBACK_REGISTRATION, PVOID *);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to ObUnregisterCallbacks. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef VOID (NTAPI *PFNOBUNREGISTERCALLBACKS)(PVOID);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to PsSetCreateProcessNotifyRoutineEx. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef NTSTATUS (NTAPI *PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)(PCREATE_PROCESS_NOTIFY_ROUTINE_EX, BOOLEAN);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to PsReferenceProcessFilePointer. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef NTSTATUS (NTAPI *PFNPSREFERENCEPROCESSFILEPOINTER)(PEPROCESS, PFILE_OBJECT *);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to PsIsProtectedProcessLight. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef BOOLEAN (NTAPI *PFNPSISPROTECTEDPROCESSLIGHT)(PEPROCESS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to ZwAlpcCreatePort. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef NTSTATUS (NTAPI *PFNZWALPCCREATEPORT)(PHANDLE, POBJECT_ATTRIBUTES, struct _ALPC_PORT_ATTRIBUTES *);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif /* VBOX_WITH_HARDENINIG */
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Internal Functions *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#ifdef VBOXDRV_WITH_FAST_IO
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PVOID pvOutput, ULONG cbOutput, ULONG uCmd,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PIO_STATUS_BLOCK pIoStatus, PDEVICE_OBJECT pDevObj);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int VBoxDrvNtDeviceControlSlow(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PIRP pIrp, PIO_STACK_LOCATION pStack);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic VOID _stdcall VBoxPowerDispatchCallback(PVOID pCallbackContext, PVOID pArgument1, PVOID pArgument2);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic NTSTATUS _stdcall VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsyncstatic NTSTATUS VBoxDrvNtErr2NtStatus(int rc);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic NTSTATUS supdrvNtProtectInit(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void supdrvNtProtectTerm(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int supdrvNtProtectCreate(PSUPDRVNTPROTECT *ppNtProtect, HANDLE hPid,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTPROTECTKIND enmProcessKind, bool fLink);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void supdrvNtProtectRelease(PSUPDRVNTPROTECT pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PSUPDRVNTPROTECT supdrvNtProtectLookup(HANDLE hPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int supdrvNtProtectFindAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int supdrvNtProtectVerifyProcess(PSUPDRVNTPROTECT pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic bool supdrvNtIsDebuggerAttached(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/*******************************************************************************
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync* Exported Functions *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync*******************************************************************************/
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncRT_C_DECLS_BEGIN
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncRT_C_DECLS_END
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/*******************************************************************************
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync* Global Variables *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync*******************************************************************************/
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to the system device instance. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PDEVICE_OBJECT g_pDevObjSys = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to the user device instance. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PDEVICE_OBJECT g_pDevObjUsr = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOXDRV_WITH_FAST_IO
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Fast I/O dispatch table. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic FAST_IO_DISPATCH const g_VBoxDrvFastIoDispatch =
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .SizeOfFastIoDispatch = */ sizeof(g_VBoxDrvFastIoDispatch),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoCheckIfPossible = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoRead = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoWrite = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoQueryBasicInfo = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoQueryStandardInfo = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoLock = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoUnlockSingle = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoUnlockAll = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoUnlockAllByKey = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoDeviceControl = */ VBoxDrvNtFastIoDeviceControl,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .AcquireFileForNtCreateSection = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .ReleaseFileForNtCreateSection = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoDetachDevice = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoQueryNetworkOpenInfo = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .AcquireForModWrite = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .MdlRead = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .MdlReadComplete = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .PrepareMdlWrite = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .MdlWriteComplete = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoReadCompressed = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoWriteCompressed = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .MdlReadCompleteCompressed = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .MdlWriteCompleteCompressed = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .FastIoQueryOpen = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .ReleaseForModWrite = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .AcquireForCcFlush = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .ReleaseForCcFlush = */ NULL,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync};
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif /* VBOXDRV_WITH_FAST_IO */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to the stub device instance. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PDEVICE_OBJECT g_pDevObjStub = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Spinlock protecting g_NtProtectTree as well as the releasing of protection
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * structures. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic RTSPINLOCK g_hNtProtectLock = NIL_RTSPINLOCK;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** AVL tree of SUPDRVNTPROTECT structures. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic AVLPVTREE g_NtProtectTree = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Cookie returned by ObRegisterCallbacks for the callbacks. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PVOID g_pvObCallbacksCookie = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Combined windows NT version number. See SUP_MAKE_NT_VER_COMBINED. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncuint32_t g_uNtVerCombined = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to ObGetObjectType if available.. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNOBGETOBJECTTYPE g_pfnObGetObjectType = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to ObRegisterCallbacks if available.. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNOBREGISTERCALLBACKS g_pfnObRegisterCallbacks = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to ObUnregisterCallbacks if available.. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNOBUNREGISTERCALLBACKS g_pfnObUnRegisterCallbacks = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to PsSetCreateProcessNotifyRoutineEx if available.. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNPSSETCREATEPROCESSNOTIFYROUTINEEX g_pfnPsSetCreateProcessNotifyRoutineEx = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to PsReferenceProcessFilePointer if available. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNPSREFERENCEPROCESSFILEPOINTER g_pfnPsReferenceProcessFilePointer = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to PsIsProtectedProcessLight. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNPSISPROTECTEDPROCESSLIGHT g_pfnPsIsProtectedProcessLight = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to ZwAlpcCreatePort. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic PFNZWALPCCREATEPORT g_pfnZwAlpcCreatePort = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef RT_ARCH_AMD64
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncextern "C" {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to KiServiceLinkage (used to fake missing ZwQueryVirtualMemory on
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * XP64 / W2K3-64). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncPFNRT g_pfnKiServiceLinkage = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Pointer to KiServiceInternal (used to fake missing ZwQueryVirtualMemory on
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * XP64 / W2K3-64) */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncPFNRT g_pfnKiServiceInternal = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** The primary ALPC port object type. (LpcPortObjectType at init time.) */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic POBJECT_TYPE g_pAlpcPortObjectType1 = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** The secondary ALPC port object type. (Sampled at runtime.) */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic POBJECT_TYPE volatile g_pAlpcPortObjectType2 = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Takes care of creating the devices and their symbolic links.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns NT status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDrvObj Pointer to driver object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
de8636fc8bdeb02161ee5b329c407dd0c48b0885vboxsyncstatic NTSTATUS vboxdrvNtCreateDevices(PDRIVER_OBJECT pDrvObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
de8636fc8bdeb02161ee5b329c407dd0c48b0885vboxsync /*
de8636fc8bdeb02161ee5b329c407dd0c48b0885vboxsync * System device.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UNICODE_STRING DevName;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_SYS);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjSys);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * User device.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_USR);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTUSR), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjUsr);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtUsr->pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtUsr->u32Cookie = SUPDRVDEVEXTUSR_COOKIE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Hardened stub device.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_STUB);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTSTUB), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjStub);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXTSTUB pDevExtStub = (PSUPDRVDEVEXTSTUB)g_pDevObjStub->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtStub->Common.pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtStub->Common.u32Cookie = SUPDRVDEVEXTSTUB_COOKIE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Done. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Bail out. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjStub);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjUsr = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjUsr);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjUsr = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjSys);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjSys = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Destroys the devices and links created by vboxdrvNtCreateDevices.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void vboxdrvNtDestroyDevices(void)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pDevObjUsr)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtUsr->pMainDrvExt = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pDevObjStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXTSTUB pDevExtStub = (PSUPDRVDEVEXTSTUB)g_pDevObjStub->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExtStub->Common.pMainDrvExt = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjStub);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjStub = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjUsr);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjUsr = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoDeleteDevice(g_pDevObjSys);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjSys = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Driver entry point.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns appropriate status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDrvObj Pointer to driver object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pRegPath Registry base path.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Sanity checks.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOXDRV_WITH_FAST_IO
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_VBoxDrvFastIoDispatch.FastIoDeviceControl != VBoxDrvNtFastIoDeviceControl)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync DbgPrint("VBoxDrv: FastIoDeviceControl=%p instead of %p\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_VBoxDrvFastIoDispatch.FastIoDeviceControl, VBoxDrvNtFastIoDeviceControl);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return STATUS_INTERNAL_ERROR;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Initialize the runtime (IPRT).
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int vrc = RTR0Init(0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(vrc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrv::DriverEntry\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Initialize process protection.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = supdrvNtProtectInit();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Create device.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * (That means creating a device object and a symbolic link so the DOS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * subsystems (OS/2, win32, ++) can access the device.)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = vboxdrvNtCreateDevices(pDrvObj);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (NT_SUCCESS(rcNt))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Initialize the device extension.
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync memset(pDevExt, 0, sizeof(*pDevExt));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!vrc)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Setup the driver entry points in pDrvObj.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
8f8e1c3bab8eabbad1cddcd165f3e30cc2011a33vboxsync pDrvObj->DriverUnload = VBoxDrvNtUnload;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_CLEANUP] = VBoxDrvNtCleanup;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxDrvNtInternalDeviceControl;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#ifdef VBOXDRV_WITH_FAST_IO
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Fast I/O to speed up guest execution roundtrips. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDrvObj->FastIoDispatch = (PFAST_IO_DISPATCH)&g_VBoxDrvFastIoDispatch;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Register ourselves for power state changes. We don't
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * currently care if this fails.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UNICODE_STRING CallbackName;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OBJECT_ATTRIBUTES Attr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (rcNt == STATUS_SUCCESS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync VBoxPowerDispatchCallback,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pDevObjSys);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Done! Returning success!
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return STATUS_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rcNt = VBoxDrvNtErr2NtStatus(vrc);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync vboxdrvNtDestroyDevices();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectTerm();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTTermRunCallbacks(RTTERMREASON_UNLOAD, 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTR0Term();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("RTR0Init failed with vrc=%d!\n", vrc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = VBoxDrvNtErr2NtStatus(vrc);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Unload the driver.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDrvObj Driver object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtUnload at irql %d\n", KeGetCurrentIrql()));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Clean up the power callback registration. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevExt->hPowerCallback)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ExUnregisterCallback(pDevExt->hPowerCallback);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevExt->pObjPowerCallback)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObDereferenceObject(pDevExt->pObjPowerCallback);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * We ASSUME that it's not possible to unload a driver with open handles.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvDeleteDevExt(pDevExt);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectTerm();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTermRunCallbacks(RTTERMREASON_UNLOAD, 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTR0Term();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync vboxdrvNtDestroyDevices();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDrvObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * For simplifying request completion into a simple return statement, extended
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * version.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns rcNt
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param rcNt The status code.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param uInfo Extra info value.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp The IRP.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLINLINE(NTSTATUS) supdrvNtCompleteRequestEx(NTSTATUS rcNt, ULONG_PTR uInfo, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Status = rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Information = uInfo;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * For simplifying request completion into a simple return statement.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns rcNt
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param rcNt The status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp The IRP.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLINLINE(NTSTATUS) supdrvNtCompleteRequest(NTSTATUS rcNt, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequestEx(rcNt, 0 /*uInfo*/, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Create (i.e. Open) file entry point.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp Request packet.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncNTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtCreate: RequestorMode=%d\n", pIrp->RequestorMode));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PFILE_OBJECT pFileObj = pStack->FileObject;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * We are not remotely similar to a directory...
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * (But this is possible.)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequest(STATUS_NOT_A_DIRECTORY, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Don't create a session for kernel clients, they'll close the handle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * immediately and work with the file object via
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * VBoxDrvNtInternalDeviceControl. The first request will be one to
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * create a session.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pIrp->RequestorMode == KernelMode)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevObj == g_pDevObjSys)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_ACCESS_DENIED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Make sure no debuggers are attached to non-user processes.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pDevObj != g_pDevObjUsr
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtIsDebuggerAttached())
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Process %p is being debugged, access to vboxdrv / vboxdrvu declined.\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess())));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_TRUST_FAILURE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Access to the stub device is only granted to processes which
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * passes verification.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! The stub device has no need for a SUPDRVSESSION structure,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * so the it uses the SUPDRVNTPROTECT directly instead.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevObj == g_pDevObjStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvNtProtectCreate(&pNtProtect, PsGetProcessId(PsGetCurrentProcess()),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync kSupDrvNtProtectKind_StubUnverified, true /*fLink*/);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvNtProtectFindAssociatedCsrss(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvNtProtectVerifyProcess(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = pNtProtect; /* Keeps reference. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Declined %p access to VBoxDrvStub: rc=%d\n", PsGetProcessId(PsGetCurrentProcess()), rc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Unrestricted access is only granted to a process in the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * VmProcessUnconfirmed state that checks out correctly and is
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * allowed to transition to VmProcessConfirmed. Again, only one
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * session per process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else if (pDevObj != g_pDevObjUsr)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(PsGetProcessId(PsGetCurrentProcess()));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvNtProtectVerifyProcess(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Create a session. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvCreateSession(pDevExt, true /*fUser*/, pDevObj == g_pDevObjSys /*fUnrestricted*/,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync &pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pSession->pNtProtect = pNtProtect; /* Keeps reference. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* No second attempt. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSpinlockAcquire(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessConfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: supdrvCreateSession failed for process %p: rc=%d.\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess()), rc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Process %p failed process verification: rc=%d.\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess()), rc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: %p is not a budding VM process (enmProcessKind=%d).\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess()), pNtProtect->enmProcessKind));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_ACCESS_DENIED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: %p is not a budding VM process.\n", PsGetProcessId(PsGetCurrentProcess())));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_ACCESS_DENIED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Call common code to create an unprivileged session.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvCreateSession(pDevExt, true /*fUser*/, false /*fUnrestricted*/, &pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pFileObj->FsContext = pSession; /* Keeps reference. No race. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pSession->pNtProtect = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync#else /* !VBOX_WITH_HARDENING */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /*
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * Call common code to create a session.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pFileObj->FsContext = NULL;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync PSUPDRVSESSION pSession;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rc = supdrvCreateSession(pDevExt, true /*fUser*/, pDevObj == g_pDevObjSys /*fUnrestricted*/, &pSession);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync if (RT_SUCCESS(rc))
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL);
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync supdrvSessionRelease(pSession);
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync if (RT_SUCCESS(rc))
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync }
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync#endif /* !VBOX_WITH_HARDENING */
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync /* bail out */
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync rcNt = VBoxDrvNtErr2NtStatus(rc);
326ffe46af8b56e4a0b9648193c1c0681104f127vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync Assert(!NT_SUCCESS(rcNt));
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pFileObj->FsContext = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequest(rcNt, pIrp); /* Note. the IoStatus is completely ignored on error. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Clean up file handle entry point.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp Request packet.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncNTSTATUS _stdcall VBoxDrvNtCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PFILE_OBJECT pFileObj = pStack->FileObject;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevObj == g_pDevObjStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)pFileObj->FsContext;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pNtProtect=%p\n", pDevExt, pFileObj, pNtProtect));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync (PSUPDRVSESSION *)&pFileObj->FsContext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionHashTabRemove(pDevExt, pSession, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequest(STATUS_SUCCESS, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Close file entry point.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp Request packet.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncNTSTATUS _stdcall VBoxDrvNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PFILE_OBJECT pFileObj = pStack->FileObject;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pDevObj == g_pDevObjStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)pFileObj->FsContext;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtClose: pDevExt=%p pFileObj=%p pNtProtect=%p\n", pDevExt, pFileObj, pNtProtect));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync (PSUPDRVSESSION *)&pFileObj->FsContext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionHashTabRemove(pDevExt, pSession, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequest(STATUS_SUCCESS, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOXDRV_WITH_FAST_IO
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Fast I/O device control callback.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * This performs no buffering, neither on the way in or out.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns TRUE if handled, FALSE if the normal I/O control routine should be
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * called.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pFileObj The file object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param fWait Whether it's a blocking call
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pvInput The input buffer as specified by the user.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param cbInput The size of the input buffer.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pvOutput The output buffer as specfied by the user.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param cbOutput The size of the output buffer.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param uFunction The function.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIoStatus Where to return the status of the operation.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj The device object..
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PVOID pvOutput, ULONG cbOutput, ULONG uCmd,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PIO_STATUS_BLOCK pIoStatus, PDEVICE_OBJECT pDevObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Check the input a little bit and get a the session references.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync (PSUPDRVSESSION *)&pFileObj->FsContext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIoStatus->Status = STATUS_TRUST_FAILURE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pIoStatus->Information = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return TRUE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession->fUnrestricted)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (supdrvNtIsDebuggerAttached())
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pIoStatus->Status = STATUS_TRUST_FAILURE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pIoStatus->Information = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync supdrvSessionRelease(pSession);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return TRUE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Deal with the 2-3 high-speed IOCtl that takes their arguments from
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * the session and iCmd, and does not return anything.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || uCmd == SUP_IOCTL_FAST_DO_HM_RUN
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || uCmd == SUP_IOCTL_FAST_DO_NOP)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = supdrvIOCtlFast(uCmd, (unsigned)(uintptr_t)pvOutput/* VMCPU id */, pDevExt, pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIoStatus->Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIoStatus->Information = 0; /* Could be used to pass rc if we liked. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return TRUE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * The normal path.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unsigned cbOut = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log2(("VBoxDrvNtFastIoDeviceControl(%p): ioctl=%#x pvIn=%p cbIn=%#x pvOut=%p cbOut=%#x pSession=%p\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDevExt, uCmd, pvInput, cbInput, pvOutput, cbOutput, pSession));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Don't allow 32-bit processes to do any I/O controls. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!IoIs32bitProcess(NULL))
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * In this fast I/O device control path we have to do our own buffering.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Verify that the I/O control function matches our pattern. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ((uCmd & 0x3) == METHOD_BUFFERED)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Get the header so we can validate it a little bit against the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync parameters before allocating any memory kernel for the reqest. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPREQHDR Hdr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (cbInput >= sizeof(Hdr) && cbOutput >= sizeof(Hdr))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync RtlCopyMemory(&Hdr, pvInput, sizeof(Hdr));
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rcNt = STATUS_SUCCESS;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync __except(EXCEPTION_EXECUTE_HANDLER)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rcNt = GetExceptionCode();
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync else
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rcNt = STATUS_INVALID_PARAMETER;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync if (NT_SUCCESS(rcNt))
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /* Verify that the sizes in the request header are correct. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync ULONG cbBuf = RT_MAX(cbInput, cbOutput);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync if ( cbInput == Hdr.cbIn
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync && cbOutput == Hdr.cbOut
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync && cbBuf < _1M*16)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /* Allocate a buffer and copy all the input into it. */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync PSUPREQHDR pHdr = (PSUPREQHDR)ExAllocatePoolWithTag(NonPagedPool, cbBuf, 'VBox');
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync if (pHdr)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync __try
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlCopyMemory(pHdr, pvInput, cbInput);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (cbInput < cbBuf)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlZeroMemory((uint8_t *)pHdr + cbInput, cbBuf - cbInput);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = GetExceptionCode();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NO_MEMORY;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Now call the common code to do the real work.
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvIOCtl(uCmd, pDevExt, pSession, pHdr, cbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Copy back the result.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cbOut = pHdr->cbOut;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (cbOut > cbOutput)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cbOut = cbOutput;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync OSDBGPRINT(("VBoxDrvNtFastIoDeviceControl: too much output! %#x > %#x; uCmd=%#x!\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pHdr->cbOut, cbOut, uCmd));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (cbOut)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync RtlCopyMemory(pvOutput, pHdr, cbOut);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = GetExceptionCode();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_SUCCESS;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else if (rc == VERR_INVALID_PARAMETER)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ExFreePoolWithTag(pHdr, 'VBox');
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Log(("VBoxDrvNtFastIoDeviceControl: Mismatching sizes (%#x) - Hdr=%#lx/%#lx Irp=%#lx/%#lx!\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uCmd, Hdr.cbIn, Hdr.cbOut, cbInput, cbOutput));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtFastIoDeviceControl: not buffered request (%#x) - not supported\n", uCmd));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef RT_ARCH_AMD64
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtFastIoDeviceControl: WOW64 req - not supported\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* complete the request. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIoStatus->Status = rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIoStatus->Information = cbOut;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return TRUE; /* handled. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif /* VBOXDRV_WITH_FAST_IO */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Device I/O Control entry point.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @param pIrp Request packet.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
0802b726efeabba46f90cb2b285de4dadaac9507vboxsyncNTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync (PSUPDRVSESSION *)&pStack->FileObject->FsContext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if (!RT_VALID_PTR(pSession))
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync return supdrvNtCompleteRequest(STATUS_TRUST_FAILURE, pIrp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * Deal with the 2-3 high-speed IOCtl that takes their arguments from
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * the session and iCmd, and does not return anything.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession->fUnrestricted)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if (supdrvNtIsDebuggerAttached())
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync return supdrvNtCompleteRequest(STATUS_TRUST_FAILURE, pIrp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync ULONG ulCmd = pStack->Parameters.DeviceIoControl.IoControlCode;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync || ulCmd == SUP_IOCTL_FAST_DO_HM_RUN
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync || ulCmd == SUP_IOCTL_FAST_DO_NOP)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Complete the I/O request. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return supdrvNtCompleteRequest(RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER, pIrp);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VBoxDrvNtDeviceControlSlow(pDevExt, pSession, pIrp, pStack);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Worker for VBoxDrvNtDeviceControl that takes the slow IOCtl functions.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync *
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @returns NT status code.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @param pSession The session.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp Request packet.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @param pStack The stack location containing the DeviceControl parameters.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync */
0802b726efeabba46f90cb2b285de4dadaac9507vboxsyncstatic int VBoxDrvNtDeviceControlSlow(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PIRP pIrp, PIO_STACK_LOCATION pStack)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unsigned cbOut = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log2(("VBoxDrvNtDeviceControlSlow(%p,%p): ioctl=%#x pBuf=%p cbIn=%#x cbOut=%#x pSession=%p\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExt, pIrp, pStack->Parameters.DeviceIoControl.IoControlCode,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->AssociatedIrp.SystemBuffer, pStack->Parameters.DeviceIoControl.InputBufferLength,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.OutputBufferLength, pSession));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef RT_ARCH_AMD64
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Don't allow 32-bit processes to do any I/O controls. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!IoIs32bitProcess(pIrp))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Verify that it's a buffered CTL. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ((pStack->Parameters.DeviceIoControl.IoControlCode & 0x3) == METHOD_BUFFERED)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Verify that the sizes in the request header are correct. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPREQHDR pHdr = (PSUPREQHDR)pIrp->AssociatedIrp.SystemBuffer;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(*pHdr)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pStack->Parameters.DeviceIoControl.InputBufferLength == pHdr->cbIn
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pStack->Parameters.DeviceIoControl.OutputBufferLength == pHdr->cbOut)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Zero extra output bytes to make sure we don't leak anything. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pHdr->cbIn < pHdr->cbOut)
cb39011e69667689c166f1cdf95247b46fff324dvboxsync RtlZeroMemory((uint8_t *)pHdr + pHdr->cbIn, pHdr->cbOut - pHdr->cbIn);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /*
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * Do the job.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvIOCtl(pStack->Parameters.DeviceIoControl.IoControlCode, pDevExt, pSession, pHdr,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RT_MAX(pHdr->cbIn, pHdr->cbOut));
cb39011e69667689c166f1cdf95247b46fff324dvboxsync if (!rc)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cbOut = pHdr->cbOut;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (cbOut > pStack->Parameters.DeviceIoControl.OutputBufferLength)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cbOut = pStack->Parameters.DeviceIoControl.OutputBufferLength;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OSDBGPRINT(("VBoxDrvLinuxIOCtl: too much output! %#x > %#x; uCmd=%#x!\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pHdr->cbOut, cbOut, pStack->Parameters.DeviceIoControl.IoControlCode));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log2(("VBoxDrvNtDeviceControlSlow: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtDeviceControlSlow: Mismatching sizes (%#x) - Hdr=%#lx/%#lx Irp=%#lx/%#lx!\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.IoControlCode,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(*pHdr) ? pHdr->cbIn : 0,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(*pHdr) ? pHdr->cbOut : 0,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.OutputBufferLength));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtDeviceControlSlow: not buffered request (%#x) - not supported\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.IoControlCode));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef RT_ARCH_AMD64
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtDeviceControlSlow: WOW64 req - not supported\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* complete the request. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Status = rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Information = cbOut;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Internal Device I/O Control entry point, used for IDC.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp Request packet.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncNTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PFILE_OBJECT pFileObj = pStack ? pStack->FileObject : NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = pFileObj ? (PSUPDRVSESSION)pFileObj->FsContext : NULL;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unsigned cbOut = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = 0;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync Log2(("VBoxDrvNtInternalDeviceControl(%p,%p): ioctl=%#x pBuf=%p cbIn=%#x cbOut=%#x pSession=%p\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pDevExt, pIrp, pStack->Parameters.DeviceIoControl.IoControlCode,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->AssociatedIrp.SystemBuffer, pStack->Parameters.DeviceIoControl.InputBufferLength,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.OutputBufferLength, pSession));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Verify that it's a buffered CTL. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ((pStack->Parameters.DeviceIoControl.IoControlCode & 0x3) == METHOD_BUFFERED)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Verify the pDevExt in the session. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pStack->Parameters.DeviceIoControl.IoControlCode != SUPDRV_IDC_REQ_CONNECT
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ? VALID_PTR(pSession) && pSession->pDevExt == pDevExt
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync : !pSession
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Verify that the size in the request header is correct. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVIDCREQHDR pHdr = (PSUPDRVIDCREQHDR)pIrp->AssociatedIrp.SystemBuffer;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(*pHdr)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pStack->Parameters.DeviceIoControl.InputBufferLength == pHdr->cb
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pStack->Parameters.DeviceIoControl.OutputBufferLength == pHdr->cb)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Call the generic code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! Connect and disconnect requires some extra attention
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * in order to get the session handling right.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pStack->Parameters.DeviceIoControl.IoControlCode == SUPDRV_IDC_REQ_DISCONNECT)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvIDC(pStack->Parameters.DeviceIoControl.IoControlCode, pDevExt, pSession, pHdr);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!rc)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pStack->Parameters.DeviceIoControl.IoControlCode == SUPDRV_IDC_REQ_CONNECT)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = ((PSUPDRVIDCREQCONNECT)pHdr)->u.Out.pSession;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cbOut = pHdr->cb;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pStack->Parameters.DeviceIoControl.IoControlCode == SUPDRV_IDC_REQ_DISCONNECT)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pFileObj->FsContext = pSession;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log2(("VBoxDrvNtInternalDeviceControl: returns %#x/rc=%#x\n", rcNt, rc));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtInternalDeviceControl: Mismatching sizes (%#x) - Hdr=%#lx Irp=%#lx/%#lx!\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.IoControlCode,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(*pHdr) ? pHdr->cb : 0,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.OutputBufferLength));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_INVALID_PARAMETER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtInternalDeviceControl: not buffered request (%#x) - not supported\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pStack->Parameters.DeviceIoControl.IoControlCode));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* complete the request. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Status = rcNt;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync pIrp->IoStatus.Information = cbOut;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync * Stub function for functions we don't implemented.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns STATUS_NOT_SUPPORTED
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevObj Device object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pIrp IRP.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncNTSTATUS _stdcall VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxDrvNtNotSupportedStub\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Information = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return STATUS_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * ExRegisterCallback handler for power events
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pCallbackContext User supplied parameter (pDevObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pArgument1 First argument
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pArgument2 Second argument
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncVOID _stdcall VBoxPowerDispatchCallback(PVOID pCallbackContext, PVOID pArgument1, PVOID pArgument2)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pCallbackContext;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxPowerDispatchCallback: %x %x\n", pArgument1, pArgument2));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Power change imminent? */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ((unsigned)pArgument1 == PO_CB_SYSTEM_STATE_LOCK)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ((unsigned)pArgument2 == 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxPowerDispatchCallback: about to go into suspend mode!\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("VBoxPowerDispatchCallback: resumed!\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Inform any clients that have registered themselves with IPRT. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTPowerSignalEvent(((unsigned)pArgument2 == 0) ? RTPOWEREVENT_SUSPEND : RTPOWEREVENT_RESUME);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Called to clean up the session structure before it's freed.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pDevExt The device globals.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pSession The session that's being cleaned up.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITH_HARDENING
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession->pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pSession->pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pSession->pNtProtect = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Initializes any OS specific object creator fields.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Checks if the session can access the object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns true if a decision has been made.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns false if the default access policy should be applied.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pObj The object in question.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pSession The session wanting to access the object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pszObjName The object name, can be NULL.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param prc Where to store the result when returning true.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncbool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pSession);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pszObjName);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(prc);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Force async tsc mode (stub).
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncbool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define MY_SystemLoadGdiDriverInSystemSpaceInformation 54
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#define MY_SystemUnloadGdiDriverInformation 27
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsynctypedef struct MYSYSTEMGDIDRIVERINFO
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UNICODE_STRING Name; /**< In: image file name. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PVOID ImageAddress; /**< Out: the load address. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PVOID SectionPointer; /**< Out: section object. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PVOID EntryPointer; /**< Out: entry point address. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PVOID ExportSectionPointer; /**< Out: export directory/section. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ULONG ImageLength; /**< Out: SizeOfImage. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync} MYSYSTEMGDIDRIVERINFO;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncextern "C" __declspec(dllimport) NTSTATUS NTAPI ZwSetSystemInformation(ULONG, PVOID, ULONG);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->pvNtSectionObj = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->hMemLock = NIL_RTR0MEMOBJ;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITHOUT_NATIVE_R0_LOADER
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifndef RT_ARCH_X86
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# error "VBOX_WITHOUT_NATIVE_R0_LOADER is only safe on x86."
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pszFilename); NOREF(pImage);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Convert the filename from DOS UTF-8 to NT UTF-16.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync size_t cwcFilename;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = RTStrCalcUtf16LenEx(pszFilename, RTSTR_MAX, &cwcFilename);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PRTUTF16 pwcsFilename = (PRTUTF16)RTMemTmpAlloc((4 + cwcFilename + 1) * sizeof(RTUTF16));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pwcsFilename)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_NO_TMP_MEMORY;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pwcsFilename[0] = '\\';
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pwcsFilename[1] = '?';
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pwcsFilename[2] = '?';
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pwcsFilename[3] = '\\';
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync PRTUTF16 pwcsTmp = &pwcsFilename[4];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = RTStrToUtf16Ex(pszFilename, RTSTR_MAX, &pwcsTmp, cwcFilename + 1, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Try load it.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync MYSYSTEMGDIDRIVERINFO Info;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&Info.Name, pwcsFilename);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.ImageAddress = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.SectionPointer = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.EntryPointer = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.ExportSectionPointer = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.ImageLength = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemLoadGdiDriverInSystemSpaceInformation, &Info, sizeof(Info));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->pvImage = Info.ImageAddress;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->pvNtSectionObj = Info.SectionPointer;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ls'\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef DEBUG_bird
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ws'\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pImage->cbImageBits == Info.ImageLength)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Lock down the entire image, just to be on the safe side.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = RTR0MemObjLockKernel(&pImage->hMemLock, pImage->pvImage, pImage->cbImageBits, RTMEM_PROT_READ);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->hMemLock = NIL_RTR0MEMOBJ;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvOSLdrUnload(pDevExt, pImage);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvOSLdrUnload(pDevExt, pImage);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_LDR_MISMATCH_NATIVE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("rcNt=%#x '%ls'\n", rcNt, pwcsFilename));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPR0Printf("VBoxDrv: rcNt=%x '%ws'\n", rcNt, pwcsFilename);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync switch (rcNt)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case /* 0xc0000003 */ STATUS_INVALID_INFO_CLASS:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef RT_ARCH_AMD64
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Unwind will crash and BSOD, so no fallback here! */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_NOT_IMPLEMENTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Use the old way of loading the modules.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! We do *NOT* try class 26 because it will probably
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * not work correctly on terminal servers and such.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_NOT_SUPPORTED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case /* 0xc0000034 */ STATUS_OBJECT_NAME_NOT_FOUND:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_MODULE_NOT_FOUND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case /* 0xC0000263 */ STATUS_DRIVER_ENTRYPOINT_NOT_FOUND:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case /* 0xC0000428 */ STATUS_INVALID_IMAGE_HASH:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_LDR_IMAGE_HASH;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case /* 0xC000010E */ STATUS_IMAGE_ALREADY_LOADED:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("WARNING: see @bugref{4853} for cause of this failure on Windows 7 x64\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_ALREADY_LOADED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync default:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_LDR_GENERAL_FAILURE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->pvNtSectionObj = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemTmpFree(pwcsFilename);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pImage);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * memcmp + log.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns Same as memcmp.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pImage The image.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pbImageBits The image bits ring-3 uploads.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param uRva The RVA to start comparing at.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param cb The number of bytes to compare.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int supdrvNtCompare(PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, uint32_t uRva, uint32_t cb)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int iDiff = memcmp((uint8_t const *)pImage->pvImage + uRva, pbImageBits + uRva, cb);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (iDiff)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cbLeft = cb;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync const uint8_t *pbNativeBits = (const uint8_t *)pImage->pvImage;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync for (size_t off = uRva; cbLeft > 0; off++, cbLeft--)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pbNativeBits[off] != pbImageBits[off])
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync char szBytes[128];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTStrPrintf(szBytes, sizeof(szBytes), "native: %.*Rhxs our: %.*Rhxs",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RT_MIN(12, cbLeft), &pbNativeBits[off],
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RT_MIN(12, cbLeft), &pbImageBits[off]);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPR0Printf("VBoxDrv: Mismatch at %#x of %s: %s\n", off, pImage->szName, szBytes);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return iDiff;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt); NOREF(pReq);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pImage->pvNtSectionObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Usually, the entire image matches exactly.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!memcmp(pImage->pvImage, pbImageBits, pImage->cbImageBits))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * However, on Windows Server 2003 (sp2 x86) both import thunk tables
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * are fixed up and we typically get a mismatch in the INIT section.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * So, lets see if everything matches when excluding the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * OriginalFirstThunk tables. To make life simpler, set the max number
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * of imports to 16 and just record and sort the locations that needs
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * to be excluded from the comparison.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IMAGE_NT_HEADERS const *pNtHdrs;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtHdrs = (IMAGE_NT_HEADERS const *)(pbImageBits
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync + ( *(uint16_t *)pbImageBits == IMAGE_DOS_SIGNATURE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ? ((IMAGE_DOS_HEADER const *)pbImageBits)->e_lfanew
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync : 0));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pNtHdrs->Signature == IMAGE_NT_SIGNATURE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size >= sizeof(IMAGE_IMPORT_DESCRIPTOR)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress > sizeof(IMAGE_NT_HEADERS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress < pImage->cbImageBits
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync struct MyRegion
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t uRva;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cb;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync } aExcludeRgns[16];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unsigned cExcludeRgns = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cImpsLeft = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync / sizeof(IMAGE_IMPORT_DESCRIPTOR);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IMAGE_IMPORT_DESCRIPTOR const *pImp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImp = (IMAGE_IMPORT_DESCRIPTOR const *)(pbImageBits
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync + pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync while ( cImpsLeft-- > 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && cExcludeRgns < RT_ELEMENTS(aExcludeRgns))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t uRvaThunk = pImp->OriginalFirstThunk;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( uRvaThunk > sizeof(IMAGE_NT_HEADERS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && uRvaThunk <= pImage->cbImageBits - sizeof(IMAGE_THUNK_DATA)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && uRvaThunk != pImp->FirstThunk)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Find the size of the thunk table. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync IMAGE_THUNK_DATA const *paThunk = (IMAGE_THUNK_DATA const *)(pbImageBits + uRvaThunk);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cMaxThunks = (pImage->cbImageBits - uRvaThunk) / sizeof(IMAGE_THUNK_DATA);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cThunks = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync while (cThunks < cMaxThunks && paThunk[cThunks].u1.Function != 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cThunks++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Ordered table insert. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unsigned i = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync for (; i < cExcludeRgns; i++)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (uRvaThunk < aExcludeRgns[i].uRva)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (i != cExcludeRgns)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync memmove(&aExcludeRgns[i + 1], &aExcludeRgns[i], (cExcludeRgns - i) * sizeof(aExcludeRgns[0]));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync aExcludeRgns[i].uRva = uRvaThunk;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync aExcludeRgns[i].cb = cThunks * sizeof(IMAGE_THUNK_DATA);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cExcludeRgns++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* advance */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImp++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Ok, do the comparison.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int iDiff = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t uRvaNext = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync for (unsigned i = 0; !iDiff && i < cExcludeRgns; i++)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (uRvaNext < aExcludeRgns[i].uRva)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync iDiff = supdrvNtCompare(pImage, pbImageBits, uRvaNext, aExcludeRgns[i].uRva - uRvaNext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uRvaNext = aExcludeRgns[i].uRva + aExcludeRgns[i].cb;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!iDiff && uRvaNext < pImage->cbImageBits)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync iDiff = supdrvNtCompare(pImage, pbImageBits, uRvaNext, pImage->cbImageBits - uRvaNext);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!iDiff)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtCompare(pImage, pbImageBits, 0, pImage->cbImageBits);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_LDR_MISMATCH_NATIVE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_INTERNAL_ERROR_4;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncvoid VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pImage->pvNtSectionObj)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pImage->hMemLock != NIL_RTR0MEMOBJ)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTR0MemObjFree(pImage->hMemLock, false /*fFreeMappings*/);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->hMemLock = NIL_RTR0MEMOBJ;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemUnloadGdiDriverInformation,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync &pImage->pvNtSectionObj, sizeof(pImage->pvNtSectionObj));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (rcNt != STATUS_SUCCESS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPR0Printf("VBoxDrv: failed to unload '%s', rcNt=%#x\n", pImage->szName, rcNt);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pImage->pvNtSectionObj = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NOREF(pDevExt);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef SUPDRV_WITH_MSR_PROBER
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#if 1
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @todo make this selectable. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define AMD_MSR_PASSCODE 0x9c5a203a
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define ASMRdMsrEx(a, b, c) ASMRdMsr(a)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define ASMWrMsrEx(a, b, c) ASMWrMsr(a,c)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Argument package used by supdrvOSMsrProberRead and supdrvOSMsrProberWrite.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsynctypedef struct SUPDRVNTMSPROBERARGS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t uMsr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint64_t uValue;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fGp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync} SUPDRVNTMSPROBERARGS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberRead.} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic DECLCALLBACK(void) supdrvNtMsProberReadOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * rdmsr and wrmsr faults can be caught even with interrupts disabled.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * (At least on 32-bit XP.)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTMSPROBERARGS *pArgs = (SUPDRVNTMSPROBERARGS *)pvUser1; NOREF(idCpu); NOREF(pvUser2);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTCCUINTREG fOldFlags = ASMIntDisableFlags();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->uValue = ASMRdMsrEx(pArgs->uMsr, AMD_MSR_PASSCODE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->fGp = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->fGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->uValue = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMSetFlags(fOldFlags);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTMSPROBERARGS Args;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.uMsr = uMsr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.uValue = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.fGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (idCpu == NIL_RTCPUID)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtMsProberReadOnCpu(idCpu, &Args, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = RTMpOnSpecific(idCpu, supdrvNtMsProberReadOnCpu, &Args, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (Args.fGp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_ACCESS_DENIED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *puValue = Args.uValue;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberWrite.} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic DECLCALLBACK(void) supdrvNtMsProberWriteOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * rdmsr and wrmsr faults can be caught even with interrupts disabled.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * (At least on 32-bit XP.)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTMSPROBERARGS *pArgs = (SUPDRVNTMSPROBERARGS *)pvUser1; NOREF(idCpu); NOREF(pvUser2);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTCCUINTREG fOldFlags = ASMIntDisableFlags();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMWrMsrEx(pArgs->uMsr, AMD_MSR_PASSCODE, pArgs->uValue);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->fGp = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pArgs->fGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMSetFlags(fOldFlags);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTMSPROBERARGS Args;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.uMsr = uMsr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.uValue = uValue;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Args.fGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (idCpu == NIL_RTCPUID)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtMsProberReadOnCpu(idCpu, &Args, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = RTMpOnSpecific(idCpu, supdrvNtMsProberReadOnCpu, &Args, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (Args.fGp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_ACCESS_DENIED;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberModify.} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic DECLCALLBACK(void) supdrvNtMsProberModifyOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPMSRPROBER pReq = (PSUPMSRPROBER)pvUser1;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync register uint32_t uMsr = pReq->u.In.uMsr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool const fFaster = pReq->u.In.enmOp == SUPMSRPROBEROP_MODIFY_FASTER;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint64_t uBefore = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint64_t uWritten = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint64_t uAfter = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fBeforeGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fModifyGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fAfterGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fRestoreGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTCCUINTREG fOldFlags;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Do the job.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fOldFlags = ASMIntDisableFlags();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMCompilerBarrier(); /* paranoia */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!fFaster)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMWriteBackAndInvalidateCaches();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uBefore = ASMRdMsrEx(uMsr, AMD_MSR_PASSCODE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fBeforeGp = false;
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fBeforeGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!fBeforeGp)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync register uint64_t uRestore = uBefore;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Modify. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uWritten = uRestore;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uWritten &= pReq->u.In.uArgs.Modify.fAndMask;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uWritten |= pReq->u.In.uArgs.Modify.fOrMask;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMWrMsrEx(uMsr, AMD_MSR_PASSCODE, uWritten);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fModifyGp = false;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fModifyGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Read modified value. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uAfter = ASMRdMsrEx(uMsr, AMD_MSR_PASSCODE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAfterGp = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAfterGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Restore original value. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMWrMsrEx(uMsr, AMD_MSR_PASSCODE, uRestore);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fRestoreGp = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fRestoreGp = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Invalid everything we can. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!fFaster)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMWriteBackAndInvalidateCaches();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMReloadCR3();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMNopPause();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMCompilerBarrier(); /* paranoia */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMSetFlags(fOldFlags);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Write out the results.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.uBefore = uBefore;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.uWritten = uWritten;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.uAfter = uAfter;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.fBeforeGp = fBeforeGp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.fModifyGp = fModifyGp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.fAfterGp = fAfterGp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pReq->u.Out.uResults.Modify.fRestoreGp = fRestoreGp;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RT_ZERO(pReq->u.Out.uResults.Modify.afReserved);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncint VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (idCpu == NIL_RTCPUID)
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtMsProberModifyOnCpu(idCpu, pReq, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return RTMpOnSpecific(idCpu, supdrvNtMsProberModifyOnCpu, pReq, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif /* SUPDRV_WITH_MSR_PROBER */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync/**
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * Converts an IPRT error code to an nt status code.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync *
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * @returns corresponding nt status code.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * @param rc IPRT error status code.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsyncstatic NTSTATUS VBoxDrvNtErr2NtStatus(int rc)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync{
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync switch (rc)
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VINF_SUCCESS: return STATUS_SUCCESS;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_GENERAL_FAILURE: return STATUS_NOT_SUPPORTED;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_INVALID_PARAMETER: return STATUS_INVALID_PARAMETER;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_INVALID_MAGIC: return STATUS_UNKNOWN_REVISION;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_INVALID_HANDLE: return STATUS_INVALID_HANDLE;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_INVALID_POINTER: return STATUS_INVALID_ADDRESS;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_LOCK_FAILED: return STATUS_NOT_LOCKED;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_ALREADY_LOADED: return STATUS_IMAGE_ALREADY_LOADED;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_PERMISSION_DENIED: return STATUS_ACCESS_DENIED;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case VERR_VERSION_MISMATCH: return STATUS_REVISION_MISMATCH;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (rc < 0)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (((uint32_t)rc & UINT32_C(0xffff0000)) == UINT32_C(0xffff0000))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return (NTSTATUS)( ((uint32_t)rc & UINT32_C(0xffff)) | SUP_NT_STATUS_BASE );
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return STATUS_UNSUCCESSFUL;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync#if 0 /* See alternative in SUPDrvA-win.asm */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Alternative version of SUPR0Printf for Windows.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * @returns 0.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * @param pszFormat The format string.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync */
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsyncSUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...)
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync{
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync va_list va;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync char szMsg[512];
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync va_start(va, pszFormat);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync size_t cch = RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync szMsg[sizeof(szMsg) - 1] = '\0';
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync va_end(va);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync RTLogWriteDebugger(szMsg, cch);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return 0;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync#endif
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Returns configuration flags of the host kernel.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncSUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return 0;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync#ifdef VBOX_WITH_HARDENING
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @name Identifying Special Processes: CSRSS.EXE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @{ */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Checks if the process is a system32 process by the given name.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync *
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * @returns true / false.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * @param pProcess The process to check.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * @param pszName The lower case process name (no path!).
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic bool supdrvNtProtectIsSystem32ProcessMatch(PEPROCESS pProcess, const char *pszName)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Assert(strlen(pszName) < 16); /* see buffer below */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * This test works on XP+.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync const char *pszImageFile = (const char *)PsGetProcessImageFileName(pProcess);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!pszImageFile)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (RTStrICmp(pszImageFile, pszName) != 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * This test requires a Vista+ API.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync if (g_pfnPsReferenceProcessFilePointer)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync PFILE_OBJECT pFile = NULL;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync NTSTATUS rcNt = g_pfnPsReferenceProcessFilePointer(pProcess, &pFile);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!NT_SUCCESS(rcNt))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync union
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OBJECT_NAME_INFORMATION Info;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync uint8_t abBuffer[sizeof(g_System32NtPath) + 16 * sizeof(WCHAR)];
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync } Buf;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ULONG cbIgn;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rcNt = ObQueryNameString(pFile, &Buf.Info, sizeof(Buf) - sizeof(WCHAR), &cbIgn);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ObDereferenceObject(pFile);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync if (!NT_SUCCESS(rcNt))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /* Terminate the name. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync PRTUTF16 pwszName = Buf.Info.Name.Buffer;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pwszName[Buf.Info.Name.Length / sizeof(RTUTF16)] = '\0';
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /* Match the name against the system32 directory path. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync uint32_t cbSystem32 = g_System32NtPath.UniStr.Length;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (Buf.Info.Name.Length < cbSystem32)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (memcmp(pwszName, g_System32NtPath.UniStr.Buffer, cbSystem32))
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync return false;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync pwszName += cbSystem32 / sizeof(RTUTF16);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (*pwszName++ != '\\')
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync /* Compare the name. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync const char *pszRight = pszName;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync for (;;)
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync {
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync WCHAR wchLeft = *pwszName++;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync char chRight = *pszRight++;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync Assert(chRight == RT_C_TO_LOWER(chRight));
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if ( wchLeft != chRight
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && RT_C_TO_LOWER(wchLeft) != chRight)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!chRight)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync break;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return true;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Checks if the current process is likely to be CSRSS.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * @returns true/false.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pProcess The process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic bool supdrvNtProtectIsCsrssByProcess(PEPROCESS pProcess)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * On Windows 8.1 CSRSS.EXE is a protected process.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (g_pfnPsIsProtectedProcessLight)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!g_pfnPsIsProtectedProcessLight(pProcess))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * The name tests.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!supdrvNtProtectIsSystem32ProcessMatch(pProcess, "csrss.exe"))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /** @todo Could extend the CSRSS.EXE check with that the TokenUser of the
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * current process must be "NT AUTHORITY\SYSTEM" (S-1-5-18). */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return true;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic bool supdrvNtProtectGetAlpcPortObjectType2(PCRTUTF16 pwszPortNm, POBJECT_TYPE *ppObjType)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fDone = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UNICODE_STRING UniStrPortNm;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UniStrPortNm.Buffer = (WCHAR *)pwszPortNm;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UniStrPortNm.Length = (USHORT)(RTUtf16Len(pwszPortNm) * sizeof(WCHAR));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UniStrPortNm.MaximumLength = UniStrPortNm.Length + sizeof(WCHAR);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OBJECT_ATTRIBUTES ObjAttr;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync InitializeObjectAttributes(&ObjAttr, &UniStrPortNm, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync HANDLE hPort;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync NTSTATUS rcNt = g_pfnZwAlpcCreatePort(&hPort, &ObjAttr, NULL /*pPortAttribs*/);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync if (NT_SUCCESS(rcNt))
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync {
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync PVOID pvObject;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rcNt = ObReferenceObjectByHandle(hPort, 0 /*DesiredAccess*/, NULL /*pObjectType*/,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync KernelMode, &pvObject, NULL /*pHandleInfo*/);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (NT_SUCCESS(rcNt))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync POBJECT_TYPE pObjType = g_pfnObGetObjectType(pvObject);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (pObjType)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPR0Printf("vboxdrv: ALPC Port Object Type %p (vs %p)\n", pObjType, *ppObjType);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *ppObjType = pObjType;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fDone = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObDereferenceObject(pvObject);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync NtClose(hPort);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync }
cb39011e69667689c166f1cdf95247b46fff324dvboxsync return fDone;
cb39011e69667689c166f1cdf95247b46fff324dvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic POBJECT_TYPE supdrvNtProtectGetAlpcPortObjectType(uint32_t uSessionId, const char *pszSessionId)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync POBJECT_TYPE pObjType = *LpcPortObjectType;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_pfnZwAlpcCreatePort
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && g_pfnObGetObjectType)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync int rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ssize_t cchTmp; NOREF(cchTmp);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync char szTmp[16];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTUTF16 wszPortNm[128];
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync size_t offRand;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * First attempt is in the session directory.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\Sessions\\");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), pszSessionId);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\VBoxDrv-");
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "-");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync offRand = RTUtf16Len(wszPortNm);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync AssertRCSuccess(rc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!fDone)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync wszPortNm[offRand] = '\0';
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0); Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertRCSuccess(rc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!fDone)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Try base names.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if (uSessionId == 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\BaseNamedObjects\\VBoxDrv-");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\Sessions\\");
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), pszSessionId);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\BaseNamedObjects\\VBoxDrv-");
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "-");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync offRand = RTUtf16Len(wszPortNm);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync AssertRCSuccess(rc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!fDone)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync wszPortNm[offRand] = '\0';
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(cchTmp > 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertRCSuccess(rc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /* Cache the result in g_pAlpcPortObjectType2. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_pAlpcPortObjectType2 == NULL
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pObjType != g_pAlpcPortObjectType1
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && fDone)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync g_pAlpcPortObjectType2 = pObjType;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return pObjType;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Called in the context of VBoxDrvNtCreate to determin the CSRSS for the
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * current process.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * The Client/Server Runtime Subsystem (CSRSS) process needs to be allowed some
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * additional access right so we need to make 101% sure we correctly identify
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * the CSRSS process a process is associated with.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns IPRT status code.
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * @param pNtProtect The NT protected process structure. The
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync * hCsrssPid member will be updated on success.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic int supdrvNtProtectFindAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Assert(pNtProtect->AvlCore.Key == PsGetCurrentProcessId());
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pNtProtect->pCsrssProcess == NULL);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync Assert(pNtProtect->hCsrssPid == NULL);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * We'll try use the ApiPort LPC object for the session we're in to track
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * down the CSRSS process. So, we start by constructing a path to it.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync int rc;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync uint32_t uSessionId = PsGetProcessSessionId(PsGetCurrentProcess());
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync char szSessionId[16];
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync WCHAR wszApiPort[48];
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (uSessionId == 0)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync szSessionId[0] = '0';
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync szSessionId[1] = '\0';
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort");
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync else
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ssize_t cchTmp = RTStrFormatU32(szSessionId, sizeof(szSessionId), uSessionId, 10, 0, 0, 0);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync AssertReturn(cchTmp > 0, (int)cchTmp);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Sessions\\");
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (RT_SUCCESS(rc))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), szSessionId);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (RT_SUCCESS(rc))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort");
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync AssertRCReturn(rc, rc);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync UNICODE_STRING ApiPortStr;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ApiPortStr.Buffer = wszApiPort;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ApiPortStr.Length = (USHORT)(RTUtf16Len(wszApiPort) * sizeof(RTUTF16));
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ApiPortStr.MaximumLength = ApiPortStr.Length + sizeof(RTUTF16);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * The object cannot be opened, but we can reference it by name.
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync void *pvApiPortObj = NULL;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync NTSTATUS rcNt = ObReferenceObjectByName(&ApiPortStr,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync 0,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync NULL /*pAccessState*/,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync STANDARD_RIGHTS_READ,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync g_pAlpcPortObjectType1,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync KernelMode,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync NULL /*pvParseContext*/,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync &pvApiPortObj);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if ( rcNt == STATUS_OBJECT_TYPE_MISMATCH
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && g_pAlpcPortObjectType2 != NULL)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rcNt = ObReferenceObjectByName(&ApiPortStr,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync 0,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NULL /*pAccessState*/,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync STANDARD_RIGHTS_READ,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync g_pAlpcPortObjectType2,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync KernelMode,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NULL /*pvParseContext*/,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync &pvApiPortObj);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if ( rcNt == STATUS_OBJECT_TYPE_MISMATCH
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && g_pfnObGetObjectType
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync && g_pfnZwAlpcCreatePort)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync rcNt = ObReferenceObjectByName(&ApiPortStr,
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync 0,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NULL /*pAccessState*/,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync STANDARD_RIGHTS_READ,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync supdrvNtProtectGetAlpcPortObjectType(uSessionId, szSessionId),
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync KernelMode,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync NULL /*pvParseContext*/,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync &pvApiPortObj);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!NT_SUCCESS(rcNt))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync SUPR0Printf("vboxdrv: Error opening '%ls': %#x\n", wszApiPort, rcNt);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return rcNt == STATUS_OBJECT_TYPE_MISMATCH ? VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE : VERR_SUPDRV_APIPORT_OPEN_ERROR;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Query the processes in the system so we can locate CSRSS.EXE candidates.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! Attempts at using SystemSessionProcessInformation failed with
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * STATUS_ACCESS_VIOLATION.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! The 32 bytes on the size of to counteract the allocation header
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync * that rtR0MemAllocEx slaps on everything.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ULONG cbNeeded = _64K - 32;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync uint32_t cbBuf;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint8_t *pbBuf = NULL;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync do
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync cbBuf = RT_ALIGN(cbNeeded + _4K, _64K) - 32;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pbBuf = (uint8_t *)RTMemAlloc(cbBuf);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!pbBuf)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync break;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync cbNeeded = 0;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync#if 0 /* doesn't work. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync SYSTEM_SESSION_PROCESS_INFORMATION Req;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Req.SessionId = uSessionId;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Req.BufferLength = cbBuf;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Req.Buffer = pbBuf;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rcNt = NtQuerySystemInformation(SystemSessionProcessInformation, &Req, sizeof(Req), &cbNeeded);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync#else
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync rcNt = NtQuerySystemInformation(SystemProcessInformation, pbBuf, cbBuf, &cbNeeded);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemFree(pbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pbBuf = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync } while ( rcNt == STATUS_INFO_LENGTH_MISMATCH
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && cbNeeded > cbBuf
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && cbNeeded < 32U*_1M);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pbBuf
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && NT_SUCCESS(rcNt)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && cbNeeded >= sizeof(SYSTEM_PROCESS_INFORMATION))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Walk the returned data and look for the process associated with the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * ApiPort object. The ApiPort object keeps the EPROCESS address of
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * the owner process (i.e. CSRSS) relatively early in the structure. On
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * 64-bit windows 8.1 it's at offset 0x18. So, obtain the EPROCESS
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * pointer to likely CSRSS processes and check for a match in the first
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * 0x40 bytes of the ApiPort object.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_SUPDRV_CSRSS_NOT_FOUND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync for (uint32_t offBuf = 0; offBuf <= cbNeeded - sizeof(SYSTEM_PROCESS_INFORMATION);)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PRTNT_SYSTEM_PROCESS_INFORMATION pProcInfo = (PRTNT_SYSTEM_PROCESS_INFORMATION)&pbBuf[offBuf];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pProcInfo->ProcessName.Length == 9 * sizeof(WCHAR)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pProcInfo->NumberOfThreads > 2 /* Very low guess. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pProcInfo->HandleCount > 32 /* Very low guess, I hope. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && (uintptr_t)pProcInfo->ProcessName.Buffer - (uintptr_t)pbBuf < cbNeeded
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[0]) == 'c'
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[1]) == 's'
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[2]) == 'r'
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[3]) == 's'
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[4]) == 's'
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pProcInfo->ProcessName.Buffer[5] == '.'
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[6]) == 'e'
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[7]) == 'x'
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[8]) == 'e' )
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /* Get the process structure and perform some more thorough
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync process checks. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS pProcess;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = PsLookupProcessByProcessId(pProcInfo->UniqueProcessId, &pProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (supdrvNtProtectIsCsrssByProcess(pProcess))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (PsGetProcessSessionId(pProcess) == uSessionId)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Final test, check the ApiPort.
c6ade8a5a12fad69394e7223b7ea170bd729f0f4vboxsync Note! The old LPC (pre Vista) objects has the PID
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync much earlier in the structure. Might be
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync worth looking for it instead. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fThatsIt = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __try
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS *ppPortProc = (PEPROCESS *)pvApiPortObj;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cTests = g_uNtVerCombined >= SUP_NT_VER_VISTA ? 16 : 38; /* ALPC since Vista. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync do
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fThatsIt = *ppPortProc == pProcess;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ppPortProc++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync } while (!fThatsIt && --cTests > 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fThatsIt = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (fThatsIt)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Ok, we found it! Keep the process structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync reference as well as the PID so we can
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync safely identify it later on. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->hCsrssPid = pProcInfo->UniqueProcessId;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->pCsrssProcess = pProcess;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = VINF_SUCCESS;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync break;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObDereferenceObject(pProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Advance. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pProcInfo->NextEntryOffset)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync break;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync offBuf += pProcInfo->NextEntryOffset;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_SUPDRV_SESSION_PROCESS_ENUM_ERROR;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync RTMemFree(pbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObDereferenceObject(pvApiPortObj);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Checks that the given process is the CSRSS process associated with protected
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * process.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns true / false.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNtProtect The NT protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pCsrss The process structure of the alleged CSRSS.EXE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic bool supdrvNtProtectIsAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect, PEPROCESS pCsrss)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->pCsrssProcess == pCsrss)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->hCsrssPid == PsGetProcessId(pCsrss))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return true;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Checks if the given process is the stupid themes service.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * The caller does some screening of access masks and what not. We do the rest.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns true / false.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNtProtect The NT protection structure.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * @param pAnnoyingProcess The process structure of an process that might
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * happen to be the annoying themes process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic bool supdrvNtProtectIsFrigginThemesService(PSUPDRVNTPROTECT pNtProtect, PEPROCESS pAnnoyingProcess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Check the process name.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!supdrvNtProtectIsSystem32ProcessMatch(pAnnoyingProcess, "svchost.exe"))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** @todo Come up with more checks. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return true;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Checks if the given process is one of the whitelisted debuggers.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns true / false.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pProcess The process to check.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic bool supdrvNtProtectIsWhitelistedDebugger(PEPROCESS pProcess)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync const char *pszImageFile = (const char *)PsGetProcessImageFileName(pProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pszImageFile)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pszImageFile[0] == 'w' || pszImageFile[0] == 'W')
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RTStrICmp(pszImageFile, "windbg.exe") == 0)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RTStrICmp(pszImageFile, "werfault.exe") == 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RTStrICmp(pszImageFile, "werfaultsecure.exe") == 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else if (pszImageFile[0] == 'd' || pszImageFile[0] == 'D')
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RTStrICmp(pszImageFile, "drwtsn32.exe") == 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RTStrICmp(pszImageFile, "dwwin.exe") == 0)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return true;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return false;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif /* VBOX_WITHOUT_DEBUGGER_CHECKS */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/** @} */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** @name Process Creation Callbacks.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @{ */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Common worker used by the process creation hooks as well as the process
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * handle creation hooks to check if a VM process is being created.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns true if likely to be a VM process, false if not.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pNtStub The NT protection structure for the possible
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * stub process.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param hParentPid The parent pid.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param hChildPid The child pid.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool supdrvNtProtectIsSpawningStubProcess(PSUPDRVNTPROTECT pNtStub, HANDLE hParentPid, HANDLE hChildPid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fRc = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pNtStub->AvlCore.Key == hParentPid) /* paranoia */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtStub->enmProcessKind == kSupDrvNtProtectKind_StubSpawning)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Compare short names. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS pStubProcess;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS rcNt = PsLookupProcessByProcessId(hParentPid, &pStubProcess);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS pChildProcess;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = PsLookupProcessByProcessId(hChildPid, &pChildProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync const char *pszStub = (const char *)PsGetProcessImageFileName(pStubProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync const char *pszChild = (const char *)PsGetProcessImageFileName(pChildProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fRc = pszStub != NULL
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pszChild != NULL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && strcmp(pszStub, pszChild) == 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** @todo check that the full image names matches. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ObDereferenceObject(pChildProcess);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ObDereferenceObject(pStubProcess);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return fRc;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Common code used by the notifies to protect a child process.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns VBox status code.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pNtStub The NT protect structure for the parent.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param hChildPid The child pid.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int supdrvNtProtectProtectNewStubChild(PSUPDRVNTPROTECT pNtParent, HANDLE hChildPid)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Create a child protection struction.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtChild;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = supdrvNtProtectCreate(&pNtChild, hChildPid, kSupDrvNtProtectKind_VmProcessUnconfirmed, false /*fLink*/);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->fFirstProcessCreateHandle = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->fFirstThreadCreateHandle = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->fCsrssFirstProcessCreateHandle = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->fCsrssFirstProcessDuplicateHandle = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->fThemesFirstProcessCreateHandle = true;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->hParentPid = pNtParent->AvlCore.Key;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->hCsrssPid = pNtParent->hCsrssPid;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->pCsrssProcess = pNtParent->pCsrssProcess;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtChild->pCsrssProcess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObReferenceObject(pNtChild->pCsrssProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Take the spinlock, recheck parent conditions and link things.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockAcquire(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtParent->enmProcessKind == kSupDrvNtProtectKind_StubSpawning)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fSuccess = RTAvlPVInsert(&g_NtProtectTree, &pNtChild->AvlCore);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (fSuccess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtParent->u.pChild = pNtChild; /* Parent keeps the initial reference. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtParent->enmProcessKind = kSupDrvNtProtectKind_StubParent;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->u.pParent = pNtParent;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_INTERNAL_ERROR_2;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = VERR_WRONG_ORDER;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSpinlockRelease(g_hNtProtectLock);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtChild);
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Common process termination code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Transitions protected process to the dead states, protecting against handle
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * PID reuse (esp. with unconfirmed VM processes) and handle cleanup issues.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync *
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * @param hDeadPid The PID of the dead process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void supdrvNtProtectUnprotectDeadProcess(HANDLE hDeadPid)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(hDeadPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockAcquire(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * If this is an unconfirmed VM process, we must release the reference
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * the parent structure holds.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtParent = pNtProtect->u.pParent;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertRelease(pNtParent); AssertRelease(pNtParent->u.pChild == pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtParent->u.pChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->u.pParent = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild = pNtProtect;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * If this is a stub exitting before the VM process gets confirmed,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * release the protection of the potential VM process as this is not
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * the prescribed behavior.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync && pNtProtect->u.pChild)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild = pNtProtect->u.pChild;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pNtProtect->u.pChild = NULL;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pNtChild->u.pParent = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtChild->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Transition it to the dead state to prevent it from opening the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * support driver again or be posthumously abused as a vm process parent.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessConfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubSpawning
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->enmProcessKind = kSupDrvNtProtectKind_StubDead;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtChild);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Do session cleanups.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertReturnVoid((HANDLE)(uintptr_t)RTProcSelf() == hDeadPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pDevObjSys)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, (RTPROCESS)(uintptr_t)hDeadPid,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTR0ProcHandleSelf(), NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pSession)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionHashTabRemove(pDevExt, pSession, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Common worker for the process creation callback that verifies a new child
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * being created by the handle creation callback code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pNtStub The parent.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pNtVm The child.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param fCallerChecks The result of any additional tests the caller made.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * This is in order to avoid duplicating the failure
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * path code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void supdrvNtProtectVerifyNewChildProtection(PSUPDRVNTPROTECT pNtStub, PSUPDRVNTPROTECT pNtVm, bool fCallerChecks)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( fCallerChecks
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtStub->enmProcessKind == kSupDrvNtProtectKind_StubParent
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtVm->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtVm->u.pParent == pNtStub
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtStub->u.pChild == pNtVm)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /* Fine, reset the CSRSS hack (fixes ViRobot APT Shield 2.0 issue). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtVm->fFirstProcessCreateHandle = true;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync return;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Misdetected vm stub; hParentPid=%p hChildPid=%p\n", pNtStub->AvlCore.Key, pNtVm->AvlCore.Key));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtStub->enmProcessKind != kSupDrvNtProtectKind_VmProcessConfirmed)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync supdrvNtProtectUnprotectDeadProcess(pNtVm->AvlCore.Key);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Old style callback (since forever).
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync * @param hParentPid The parent PID.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param hNewPid The PID of the new child.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param fCreated TRUE if it's a creation notification,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * FALSE if termination.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @remarks ASSUMES this arrives before the handle creation callback.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic VOID __stdcall
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncsupdrvNtProtectCallback_ProcessCreateNotify(HANDLE hParentPid, HANDLE hNewPid, BOOLEAN fCreated)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Is it a new process that needs protection?
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (fCreated)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(hParentPid);
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync if (pNtStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync PSUPDRVNTPROTECT pNtVm = supdrvNtProtectLookup(hNewPid);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (!pNtVm)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (supdrvNtProtectIsSpawningStubProcess(pNtStub, hParentPid, hNewPid))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectProtectNewStubChild(pNtStub, hNewPid);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync else
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync supdrvNtProtectVerifyNewChildProtection(pNtStub, pNtVm, true);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync supdrvNtProtectRelease(pNtVm);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync supdrvNtProtectRelease(pNtStub);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Process termination, do clean ups.
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectUnprotectDeadProcess(hNewPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/**
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * New style callback (Vista SP1+ / w2k8).
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNewProcess The new process.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param hNewPid The PID of the new process.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @param pInfo Process creation details. NULL if process
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * termination notification.
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * @remarks ASSUMES this arrives before the handle creation callback.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic VOID __stdcall
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncsupdrvNtProtectCallback_ProcessCreateNotifyEx(PEPROCESS pNewProcess, HANDLE hNewPid, PPS_CREATE_NOTIFY_INFO pInfo)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Is it a new process that needs protection?
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (pInfo)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(pInfo->CreatingThreadId.UniqueProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/NewProcessEx: ctx=%04zx/%p pid=%04zx ppid=%04zx ctor=%04zx/%04zx rcNt=%#x %.*ls\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync hNewPid, pInfo->ParentProcessId,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pInfo->CreatingThreadId.UniqueProcess, pInfo->CreatingThreadId.UniqueThread, pInfo->CreationStatus,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pInfo->FileOpenNameAvailable && pInfo->ImageFileName ? (size_t)pInfo->ImageFileName->Length / 2 : 0,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pInfo->FileOpenNameAvailable && pInfo->ImageFileName ? pInfo->ImageFileName->Buffer : NULL));
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtVm = supdrvNtProtectLookup(hNewPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pNtVm)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Parent must be creator. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pInfo->CreatingThreadId.UniqueProcess == pInfo->ParentProcessId)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (supdrvNtProtectIsSpawningStubProcess(pNtStub, pInfo->ParentProcessId, hNewPid))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectProtectNewStubChild(pNtStub, hNewPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Parent must be creator (as above). */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectVerifyNewChildProtection(pNtStub, pNtVm,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pInfo->CreatingThreadId.UniqueProcess == pInfo->ParentProcessId);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtVm);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtStub);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Process termination, do clean ups.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectUnprotectDeadProcess(hNewPid);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync}
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @name Process Handle Callbacks.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @{ */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Process rights that we allow for handles to stub and VM processes. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define SUPDRV_NT_ALLOW_PROCESS_RIGHTS \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ( PROCESS_TERMINATE \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_READ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_QUERY_INFORMATION \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | PROCESS_QUERY_LIMITED_INFORMATION \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | PROCESS_SUSPEND_RESUME \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | DELETE \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | READ_CONTROL \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | SYNCHRONIZE)
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Evil process rights. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define SUPDRV_NT_EVIL_PROCESS_RIGHTS \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ( PROCESS_CREATE_THREAD \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_SESSIONID /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_OPERATION \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | PROCESS_VM_WRITE \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_DUP_HANDLE \
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync | PROCESS_CREATE_PROCESS /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_QUOTA /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_INFORMATION \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_LIMITED_INFORMATION /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncAssertCompile((SUPDRV_NT_ALLOW_PROCESS_RIGHTS & SUPDRV_NT_EVIL_PROCESS_RIGHTS) == 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic OB_PREOP_CALLBACK_STATUS __stdcall
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncsupdrvNtProtectCallback_ProcessHandlePre(PVOID pvUser, POB_PRE_OPERATION_INFORMATION pOpInfo)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pvUser == NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pOpInfo->ObjectType == *PsProcessType);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync * Protected? Kludge required for NtOpenProcess calls comming in before
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * the create process hook triggers on Windows 8.1 (possibly others too).
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE hObjPid = PsGetProcessId((PEPROCESS)pOpInfo->Object);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(hObjPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE hParentPid = PsGetProcessInheritedFromUniqueProcessId((PEPROCESS)pOpInfo->Object);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(hParentPid);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (pNtStub)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (supdrvNtProtectIsSpawningStubProcess(pNtStub, hParentPid, hObjPid))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectProtectNewStubChild(pNtStub, hObjPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect = supdrvNtProtectLookup(hObjPid);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtStub);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->CallContext = pNtProtect; /* Just for reference. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Ok, it's a protected process. Strip rights as required or possible.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync static ACCESS_MASK const s_fCsrssStupidDesires = 0x1fffff;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ACCESS_MASK fAllowedRights = SUPDRV_NT_ALLOW_PROCESS_RIGHTS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Don't restrict the process accessing itself. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ((PEPROCESS)pOpInfo->Object == PsGetCurrentProcess())
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fFirstProcessCreateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] %s\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Allow debuggers full access. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else if (supdrvNtProtectIsWhitelistedDebugger(PsGetCurrentProcess()))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fFirstProcessCreateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] %s [debugger]\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync /* Special case 1 on Vista, 7 & 8:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync The CreateProcess code passes the handle over to CSRSS.EXE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync and the code inBaseSrvCreateProcess will duplicate the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync handle with 0x1fffff as access mask. NtDuplicateObject will
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fail this call before it ever gets down here.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Special case 2 on 8.1:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync The CreateProcess code requires additional rights for
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync something, we'll drop these in the stub code. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->fFirstProcessCreateHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->hParentPid == PsGetProcessId(PsGetCurrentProcess())
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && ExGetPreviousMode() != KernelMode)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( !pOpInfo->KernelHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= s_fCsrssStupidDesires;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights = fAllowedRights
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_OPERATION
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_WRITE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_INFORMATION
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_SET_LIMITED_INFORMATION
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | 0;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fFirstProcessCreateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Special case 3 on 8.1:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync The interaction between the CreateProcess code and CSRSS.EXE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync has changed to the better with Windows 8.1. CSRSS.EXE no
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync longer duplicates the process (thread too) handle, but opens
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync it, thus allowing us to do our job. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 3)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->fCsrssFirstProcessCreateHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fCsrssFirstProcessCreateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Not needed: PROCESS_CREATE_THREAD, PROCESS_SET_SESSIONID,
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync PROCESS_CREATE_PROCESS */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights = fAllowedRights
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_OPERATION
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_WRITE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_DUP_HANDLE /* Needed for CreateProcess/VBoxTestOGL. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Special case 4, Windows 7, Vista, possibly 8, but not 8.1:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync The Themes service requires PROCESS_DUP_HANDLE access to our
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync process or we won't get any menus and dialogs will be half
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync unreadable. This is _very_ unfortunate and more work will
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync go into making this more secure. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 2)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == 0x1478 /* 6.1.7600.16385 (win7_rtm.090713-1255) */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->fThemesFirstProcessCreateHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtProtectIsFrigginThemesService(pNtProtect, PsGetCurrentProcess()) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fThemesFirstProcessCreateHandle = true; /* Only once! */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= PROCESS_DUP_HANDLE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p wants %#x to %p/pid=%04zx [%d], allow %#x => %#x; %s [prev=%#x]\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess & fAllowedRights,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()), ExGetPreviousMode() ));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess &= fAllowedRights;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Don't restrict the process accessing itself. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( (PEPROCESS)pOpInfo->Object == PsGetCurrentProcess()
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == pOpInfo->Object)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Special case 5 on Vista, 7 & 8:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync This is the CSRSS.EXE end of special case #1. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->fCsrssFirstProcessDuplicateHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->hParentPid
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync == PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess()
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fCsrssFirstProcessDuplicateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess == s_fCsrssStupidDesires)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Not needed: PROCESS_CREATE_THREAD, PROCESS_SET_SESSIONID,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PROCESS_CREATE_PROCESS, PROCESS_DUP_HANDLE */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights = fAllowedRights
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_VM_OPERATION
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | PROCESS_VM_WRITE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_DUP_HANDLE /* Needed for launching VBoxTestOGL. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/ProcessHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= fAllowedRights;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return OB_PREOP_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic VOID __stdcall
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncsupdrvNtProtectCallback_ProcessHandlePost(PVOID pvUser, POB_POST_OPERATION_INFORMATION pOpInfo)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pvUser == NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pOpInfo->ObjectType == *PsProcessType);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pOpInfo->CallContext
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && NT_SUCCESS(pOpInfo->ReturnStatus))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ACCESS_MASK const fGrantedAccess = pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ? pOpInfo->Parameters->CreateHandleInformation.GrantedAccess
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync : pOpInfo->Parameters->DuplicateHandleInformation.GrantedAccess;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertReleaseMsg( !(fGrantedAccess & ~( SUPDRV_NT_ALLOW_PROCESS_RIGHTS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | WRITE_OWNER | WRITE_DAC /* these two might be forced upon us */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | PROCESS_UNKNOWN_4000 /* Seen set on win 8.1 */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*| PROCESS_UNKNOWN_8000 */ ) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || pOpInfo->KernelHandle,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ("GrantedAccess=%#x - we allow %#x - we did not allow %#x\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fGrantedAccess, SUPDRV_NT_ALLOW_PROCESS_RIGHTS, fGrantedAccess & ~SUPDRV_NT_ALLOW_PROCESS_RIGHTS));
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync }
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync}
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync# undef SUPDRV_NT_ALLOW_PROCESS_RIGHTS
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync/** @name Thread Handle Callbacks
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync * @{ */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/* From ntifs.h */
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsyncextern "C" NTKERNELAPI PEPROCESS __stdcall IoThreadToProcess(PETHREAD);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** Thread rights that we allow for handles to stub and VM processes. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define SUPDRV_NT_ALLOWED_THREAD_RIGHTS \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ( THREAD_TERMINATE \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | THREAD_GET_CONTEXT \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | THREAD_QUERY_INFORMATION \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | THREAD_QUERY_LIMITED_INFORMATION \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | DELETE \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | READ_CONTROL \
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync | SYNCHRONIZE)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync/** @todo consider THREAD_SET_LIMITED_INFORMATION & THREAD_RESUME */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync/** Evil thread rights.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @remarks THREAD_RESUME is not included as it seems to be forced upon us by
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Windows 8.1, at least for some processes. We dont' actively
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * allow it though, just tollerate it when forced to. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# define SUPDRV_NT_EVIL_THREAD_RIGHTS \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ( THREAD_SUSPEND_RESUME \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_SET_CONTEXT \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_SET_INFORMATION \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_SET_LIMITED_INFORMATION /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_SET_THREAD_TOKEN /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_IMPERSONATE /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | THREAD_DIRECT_IMPERSONATION /*?*/ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*| THREAD_RESUME - see remarks. */ \
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync | 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncAssertCompile((SUPDRV_NT_EVIL_THREAD_RIGHTS & SUPDRV_NT_ALLOWED_THREAD_RIGHTS) == 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncstatic OB_PREOP_CALLBACK_STATUS __stdcall
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsyncsupdrvNtProtectCallback_ThreadHandlePre(PVOID pvUser, POB_PRE_OPERATION_INFORMATION pOpInfo)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pvUser == NULL);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync Assert(pOpInfo->ObjectType == *PsThreadType);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS pProcess = IoThreadToProcess((PETHREAD)pOpInfo->Object);
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(PsGetProcessId(pProcess));
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync pOpInfo->CallContext = pNtProtect; /* Just for reference. */
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync if (pNtProtect)
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync {
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync static ACCESS_MASK const s_fCsrssStupidDesires = 0x1fffff;
c598affb4a1578b0e7be124835a70c4f08c5d2bdvboxsync ACCESS_MASK fAllowedRights = SUPDRV_NT_ALLOWED_THREAD_RIGHTS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Don't restrict the process accessing its own threads. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pProcess == PsGetCurrentProcess())
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] self\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fFirstThreadCreateHandle = false;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync#ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Allow debuggers full access. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else if (supdrvNtProtectIsWhitelistedDebugger(PsGetCurrentProcess()))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] %s [debugger]\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pOpInfo->CallContext = NULL; /* don't assert */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Special case 1 on Vista, 7, 8:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync The CreateProcess code passes the handle over to CSRSS.EXE
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync and the code inBaseSrvCreateProcess will duplicate the
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync handle with 0x1fffff as access mask. NtDuplicateObject will
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fail this call before it ever gets down here. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pNtProtect->fFirstThreadCreateHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
c049162517778158b3507c0389358a7342622b99vboxsync && pNtProtect->hParentPid == PsGetProcessId(PsGetCurrentProcess()) )
c049162517778158b3507c0389358a7342622b99vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( !pOpInfo->KernelHandle
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires)
c049162517778158b3507c0389358a7342622b99vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= s_fCsrssStupidDesires;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->fFirstThreadCreateHandle = false;
c049162517778158b3507c0389358a7342622b99vboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Special case 2 on 8.1, possibly also Vista, 7, 8:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync When creating a process like VBoxTestOGL from the VM process,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync CSRSS.EXE will try talk to the calling thread and, it
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync appears, impersonate it. We unfortunately need to allow
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync this or there will be no 3D support. Typical DbgPrint:
c049162517778158b3507c0389358a7342622b99vboxsync "SXS: BasepCreateActCtx() Calling csrss server failed. Status = 0xc00000a5" */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync SUPDRVNTPROTECTKIND enmProcessKind;
c049162517778158b3507c0389358a7342622b99vboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 0, 0, 0)
c049162517778158b3507c0389358a7342622b99vboxsync && ( (enmProcessKind = pNtProtect->enmProcessKind) == kSupDrvNtProtectKind_VmProcessConfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= THREAD_IMPERSONATE;
c049162517778158b3507c0389358a7342622b99vboxsync fAllowedRights |= THREAD_DIRECT_IMPERSONATION;
c049162517778158b3507c0389358a7342622b99vboxsync //fAllowedRights |= THREAD_SET_LIMITED_INFORMATION; - try without this one
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
c049162517778158b3507c0389358a7342622b99vboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync
c049162517778158b3507c0389358a7342622b99vboxsync Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p wants %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s [prev=%#x]\n",
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess,
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights,
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess & fAllowedRights,
c049162517778158b3507c0389358a7342622b99vboxsync PsGetProcessImageFileName(PsGetCurrentProcess()), ExGetPreviousMode()));
c049162517778158b3507c0389358a7342622b99vboxsync
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->CreateHandleInformation.DesiredAccess &= fAllowedRights;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Don't restrict the process accessing its own threads. */
c049162517778158b3507c0389358a7342622b99vboxsync if ( pProcess == PsGetCurrentProcess()
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && (PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == pProcess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] self\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess),
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess,
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess,
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->CallContext = NULL; /* don't assert */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync /* Special case 3 on Vista, 7, 8:
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync This is the follow up to special case 1. */
c049162517778158b3507c0389358a7342622b99vboxsync SUPDRVNTPROTECTKIND enmProcessKind;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 0, 0, 0)
c049162517778158b3507c0389358a7342622b99vboxsync && ( (enmProcessKind = pNtProtect->enmProcessKind) == kSupDrvNtProtectKind_VmProcessConfirmed
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess()
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pOpInfo->KernelHandle == 0
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= THREAD_IMPERSONATE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fAllowedRights |= THREAD_DIRECT_IMPERSONATION;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync //fAllowedRights |= THREAD_SET_LIMITED_INFORMATION; - try without this one
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->CallContext = NULL; /* don't assert this. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync
c049162517778158b3507c0389358a7342622b99vboxsync Log(("vboxdrv/ThreadHandlePre: %sctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s\n",
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->KernelHandle ? "k" : "", PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(),
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess,
c049162517778158b3507c0389358a7342622b99vboxsync PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess),
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess,
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess,
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights,
c049162517778158b3507c0389358a7342622b99vboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess & fAllowedRights,
c049162517778158b3507c0389358a7342622b99vboxsync PsGetProcessImageFileName(PsGetCurrentProcess()) ));
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= fAllowedRights;
c049162517778158b3507c0389358a7342622b99vboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectRelease(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return OB_PREOP_SUCCESS;
c049162517778158b3507c0389358a7342622b99vboxsync}
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic VOID __stdcall
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncsupdrvNtProtectCallback_ThreadHandlePost(PVOID pvUser, POB_POST_OPERATION_INFORMATION pOpInfo)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pvUser == NULL);
c049162517778158b3507c0389358a7342622b99vboxsync Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE);
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync Assert(pOpInfo->ObjectType == *PsThreadType);
c049162517778158b3507c0389358a7342622b99vboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( pOpInfo->CallContext
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && NT_SUCCESS(pOpInfo->ReturnStatus))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync ACCESS_MASK const fGrantedAccess = pOpInfo->Parameters->CreateHandleInformation.GrantedAccess;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReleaseMsg( !(fGrantedAccess & ~( SUPDRV_NT_ALLOWED_THREAD_RIGHTS
c049162517778158b3507c0389358a7342622b99vboxsync | WRITE_OWNER | WRITE_DAC /* these two might be forced upon us */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync | THREAD_RESUME /* This seems to be force upon us too with 8.1. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || pOpInfo->KernelHandle,
c049162517778158b3507c0389358a7342622b99vboxsync ("GrantedAccess=%#x - we allow %#x - we did not allow %#x\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync fGrantedAccess, SUPDRV_NT_ALLOWED_THREAD_RIGHTS, fGrantedAccess & ~SUPDRV_NT_ALLOWED_THREAD_RIGHTS));
c049162517778158b3507c0389358a7342622b99vboxsync }
c049162517778158b3507c0389358a7342622b99vboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c049162517778158b3507c0389358a7342622b99vboxsync# undef SUPDRV_NT_ALLOWED_THREAD_RIGHTS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/** @} */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
c049162517778158b3507c0389358a7342622b99vboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Creates a new process protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns VBox status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param ppNtProtect Where to return the pointer to the structure
c049162517778158b3507c0389358a7342622b99vboxsync * on success.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param hPid The process ID of the process to protect.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param enmProcessKind The kind of process we're protecting.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param fLink Whether to link the structure into the tree.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
c049162517778158b3507c0389358a7342622b99vboxsyncstatic int supdrvNtProtectCreate(PSUPDRVNTPROTECT *ppNtProtect, HANDLE hPid, SUPDRVNTPROTECTKIND enmProcessKind, bool fLink)
c049162517778158b3507c0389358a7342622b99vboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertReturn(g_hNtProtectLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)RTMemAllocZ(sizeof(*pNtProtect));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_NO_MEMORY;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->AvlCore.Key = hPid;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->u32Magic = SUPDRVNTPROTECT_MAGIC;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->cRefs = 1;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->enmProcessKind = enmProcessKind;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->hParentPid = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->hCsrssPid = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->pCsrssProcess = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (fLink)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
cb39011e69667689c166f1cdf95247b46fff324dvboxsync RTSpinlockAcquire(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync bool fSuccess = RTAvlPVInsert(&g_NtProtectTree, &pNtProtect->AvlCore);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!fSuccess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Duplicate entry, fail. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->u32Magic = SUPDRVNTPROTECT_MAGIC_DEAD;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("supdrvNtProtectCreate: Duplicate (%#x).\n", pNtProtect->AvlCore.Key));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemFree(pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_DUPLICATE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *ppNtProtect = pNtProtect;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Releases a reference to a NT protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNtProtect The NT protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic void supdrvNtProtectRelease(PSUPDRVNTPROTECT pNtProtect)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pNtProtect)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertReturnVoid(pNtProtect->u32Magic == SUPDRVNTPROTECT_MAGIC);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockAcquire(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cRefs = ASMAtomicDecU32(&pNtProtect->cRefs);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (cRefs != 0)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * That was the last reference. Remove it from the tree, invalidate it
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * and free the resources associated with it. Also, release any
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * child/parent references related to this protection structure.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMAtomicWriteU32(&pNtProtect->u32Magic, SUPDRVNTPROTECT_MAGIC_DEAD);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pRemoved = (PSUPDRVNTPROTECT)RTAvlPVRemove(&g_NtProtectTree, pNtProtect->AvlCore.Key);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pRemovedChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pChild = pNtProtect->u.pChild;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pChild)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pNtProtect->u.pChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pChild->u.pParent = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pChild->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cChildRefs = ASMAtomicIncU32(&pChild->cRefs);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!cChildRefs)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pRemovedChild = (PSUPDRVNTPROTECT)RTAvlPVRemove(&g_NtProtectTree, pChild->AvlCore.Key);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pChild = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertRelease(pNtProtect->enmProcessKind != kSupDrvNtProtectKind_VmProcessUnconfirmed);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pRemoved == pNtProtect);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync Assert(pRemovedChild == pChild);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->pCsrssProcess)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ObDereferenceObject(pNtProtect->pCsrssProcess);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->pCsrssProcess = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemFree(pNtProtect);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync if (pChild)
cb39011e69667689c166f1cdf95247b46fff324dvboxsync RTMemFree(pChild);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
cb39011e69667689c166f1cdf95247b46fff324dvboxsync/**
cb39011e69667689c166f1cdf95247b46fff324dvboxsync * Looks up a PID in the NT protect tree.
cb39011e69667689c166f1cdf95247b46fff324dvboxsync *
cb39011e69667689c166f1cdf95247b46fff324dvboxsync * @returns Pointer to a NT protection structure (with a referenced) on success,
cb39011e69667689c166f1cdf95247b46fff324dvboxsync * NULL if not found.
cb39011e69667689c166f1cdf95247b46fff324dvboxsync * @param hPid The process ID.
cb39011e69667689c166f1cdf95247b46fff324dvboxsync */
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncstatic PSUPDRVNTPROTECT supdrvNtProtectLookup(HANDLE hPid)
cb39011e69667689c166f1cdf95247b46fff324dvboxsync{
cb39011e69667689c166f1cdf95247b46fff324dvboxsync RTSpinlockAcquire(g_hNtProtectLock);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync PSUPDRVNTPROTECT pFound = (PSUPDRVNTPROTECT)RTAvlPVGet(&g_NtProtectTree, hPid);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync if (pFound)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ASMAtomicIncU32(&pFound->cRefs);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockRelease(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return pFound;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync}
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Worker for supdrvNtProtectVerifyProcess that verifies the handles to a VM
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * process and its thread.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns VBox status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNtProtect The NT protect structure for getting information
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * about special processes.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic int supdrvNtProtectRestrictHandlesToProcessAndThread(PSUPDRVNTPROTECT pNtProtect)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * What to protect.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PEPROCESS pProtectedProcess = PsGetCurrentProcess();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE hProtectedPid = PsGetProcessId(pProtectedProcess);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PETHREAD pProtectedThread = PsGetCurrentThread();
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertReturn(pNtProtect->AvlCore.Key == hProtectedPid, VERR_INTERNAL_ERROR_5);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Take a snapshot of all the handles in the system.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Note! The 32 bytes on the size of to counteract the allocation header
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync * that rtR0MemAllocEx slaps on everything.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cbBuf = _256K - 32;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint8_t *pbBuf = (uint8_t *)RTMemAlloc(cbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ULONG cbNeeded = cbBuf;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt = NtQuerySystemInformation(SystemExtendedHandleInformation, pbBuf, cbBuf, &cbNeeded);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync while ( rcNt == STATUS_INFO_LENGTH_MISMATCH
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && cbNeeded > cbBuf
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync && cbBuf <= 32U*_1M)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cbBuf = RT_ALIGN_32(cbNeeded + _4K, _64K) - 32;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync RTMemFree(pbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pbBuf = (uint8_t *)RTMemAlloc(cbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!pbBuf)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VERR_NO_MEMORY;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = NtQuerySystemInformation(SystemExtendedHandleInformation, pbBuf, cbBuf, &cbNeeded);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemFree(pbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return RTErrConvertFromNtStatus(rcNt);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Walk the information and look for handles to the two objects we're protecting.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync HANDLE idLastDebugger = (HANDLE)~(uintptr_t)0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cCsrssProcessHandles = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cSystemProcessHandles = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cEvilProcessHandles = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t cBenignProcessHandles = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint32_t cCsrssThreadHandles = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t cEvilThreadHandles = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t cBenignThreadHandles = 0;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SYSTEM_HANDLE_INFORMATION_EX const *pInfo = (SYSTEM_HANDLE_INFORMATION_EX const *)pbBuf;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ULONG_PTR i = pInfo->NumberOfHandles;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertRelease(RT_OFFSETOF(SYSTEM_HANDLE_INFORMATION_EX, Handles[i]) == cbNeeded);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (i-- > 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync const char *pszType;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SYSTEM_HANDLE_ENTRY_INFO_EX const *pHandleInfo = &pInfo->Handles[i];
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pHandleInfo->Object == pProtectedProcess)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Handles within the protected process is fine. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( !(pHandleInfo->GrantedAccess & SUPDRV_NT_EVIL_PROCESS_RIGHTS)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || pHandleInfo->UniqueProcessId == hProtectedPid)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cBenignProcessHandles++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* CSRSS is allowed to have one evil process handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync See the special cases in the hook code. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( cCsrssProcessHandles < 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && pHandleInfo->UniqueProcessId == pNtProtect->hCsrssPid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cCsrssProcessHandles++;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* The system process is allowed having one open process handle in
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Windows 8.1 and later. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 3)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && cSystemProcessHandles < 1
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pHandleInfo->UniqueProcessId == PsGetProcessId(PsInitialSystemProcess))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cSystemProcessHandles++;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cEvilProcessHandles++;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pszType = "process";
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else if (pHandleInfo->Object == pProtectedThread)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Handles within the protected process is fine. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( !(pHandleInfo->GrantedAccess & SUPDRV_NT_EVIL_THREAD_RIGHTS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || pHandleInfo->UniqueProcessId == hProtectedPid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync cBenignThreadHandles++;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
cb39011e69667689c166f1cdf95247b46fff324dvboxsync /* CSRSS is allowed to have one evil handle to the primary thread
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for LPC purposes. See the hook for special case. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( cCsrssThreadHandles < 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && pHandleInfo->UniqueProcessId == pNtProtect->hCsrssPid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cCsrssThreadHandles++;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync continue;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync cEvilThreadHandles++;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pszType = "thread";
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# ifdef VBOX_WITHOUT_DEBUGGER_CHECKS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Ignore whitelisted debuggers. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pHandleInfo->UniqueProcessId == idLastDebugger)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PEPROCESS pDbgProc;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS rcNt = PsLookupProcessByProcessId(pHandleInfo->UniqueProcessId, &pDbgProc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (NT_SUCCESS(rcNt))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool fIsDebugger = supdrvNtProtectIsWhitelistedDebugger(pDbgProc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ObDereferenceObject(pDbgProc);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (fIsDebugger)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync idLastDebugger = pHandleInfo->UniqueProcessId;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync continue;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Found evil handle. Currently ignoring on pre-Vista. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# ifndef VBOX_WITH_VISTA_NO_SP
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( g_uNtVerCombined >= SUP_NT_VER_VISTA
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || g_pfnObRegisterCallbacks)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Found evil handle to budding VM process: pid=%p h=%p acc=%#x attr=%#x type=%s\n",
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pHandleInfo->UniqueProcessId, pHandleInfo->HandleValue,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync pHandleInfo->GrantedAccess, pHandleInfo->HandleAttributes, pszType));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTMemFree(pbBuf);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return rc;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Checks if the current process checks out as a VM process stub.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns VBox status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @param pNtProtect The NT protect structure. This is upgraded to a
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * final protection kind (state) on success.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int supdrvNtProtectVerifyProcess(PSUPDRVNTPROTECT pNtProtect)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(PsGetProcessId(PsGetCurrentProcess()) == pNtProtect->AvlCore.Key, VERR_INTERNAL_ERROR_3);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Do the verification. The handle restriction checks are only preformed
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * on VM processes.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = VINF_SUCCESS;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supdrvNtProtectRestrictHandlesToProcessAndThread(pNtProtect);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (RT_SUCCESS(rc))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync char szErr[256];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RT_ZERO(szErr);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTERRINFO ErrInfo;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTErrInfoInit(&ErrInfo, szErr, sizeof(szErr));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NULL /*pcFixes*/, &ErrInfo);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync RTLogWriteDebugger(szErr, strlen(szErr));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Upgrade and return.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync RTSpinlockAcquire(g_hNtProtectLock);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Stub process verficiation is pretty much straight forward. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified)
cb39011e69667689c166f1cdf95247b46fff324dvboxsync pNtProtect->enmProcessKind = RT_SUCCESS(rc) ? kSupDrvNtProtectKind_StubSpawning : kSupDrvNtProtectKind_StubDead;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* The VM process verification is a little bit more complicated
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync because we need to drop the parent process reference as well. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync AssertRelease(pNtProtect->cRefs >= 2); /* Parent + Caller */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PSUPDRVNTPROTECT pParent = pNtProtect->u.pParent;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertRelease(pParent);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync AssertRelease(pParent->u.pParent == pNtProtect);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertRelease(pParent->enmProcessKind == kSupDrvNtProtectKind_StubParent);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pParent->u.pParent = NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->u.pParent = NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ASMAtomicDecU32(&pNtProtect->cRefs);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (RT_SUCCESS(rc))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessConfirmed;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Since the stub and VM processes are only supposed to have one thread,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync we're not supposed to be subject to any races from within the processes.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync There is a race between VM process verification and the stub process
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync exiting, though. We require the stub process to be alive until the new
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VM process has made it thru the validation. So, when the stub
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync terminates the notification handler will change the state of both stub
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and VM process to dead.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
cb39011e69667689c166f1cdf95247b46fff324dvboxsync Also, I'm not entirely certain where the process
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync termination notification is triggered from, so that can theorically
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync create a race in both cases. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReleaseMsg( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubDead
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessDead,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ("enmProcessKind=%d rc=%Rrc\n", pNtProtect->enmProcessKind, rc));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (RT_SUCCESS(rc))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = VERR_INVALID_STATE; /* There should be no races here. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync RTSpinlockRelease(g_hNtProtectLock);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return rc;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# ifndef VBOX_WITHOUT_DEBUGGER_CHECKS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Checks if the current process is being debugged.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @return @c true if debugged, @c false if not.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool supdrvNtIsDebuggerAttached(void)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return PsIsProcessBeingDebugged(PsGetCurrentProcess()) != FALSE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync}
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# endif /* !VBOX_WITHOUT_DEBUGGER_CHECKS */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Terminates the hardening bits.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void supdrvNtProtectTerm(void)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Stop intercepting process and thread handle creation calls.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pvObCallbacksCookie)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnObUnRegisterCallbacks(g_pvObCallbacksCookie);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pvObCallbacksCookie = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Stop intercepting process creation and termination notifications.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS rcNt;
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync if (g_pfnPsSetCreateProcessNotifyRoutineEx)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync AssertMsg(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(g_NtProtectTree == NULL);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clean up globals.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RTSpinlockDestroy(g_hNtProtectLock);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_NtProtectTree = NIL_RTSPINLOCK;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync supHardenedWinTermImageVerifier();
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync}
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync# ifdef RT_ARCH_X86
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xAF(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB0(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB1(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB2(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB3(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB4(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB5(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB6(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB7(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB8(void);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xB9(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xBA(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xBB(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xBC(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xBD(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0xBE(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync# elif defined(RT_ARCH_AMD64)
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0x1F(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0x20(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0x21(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0x22(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncDECLASM(void) supdrvNtQueryVirtualMemory_0x23(void);
cb39011e69667689c166f1cdf95247b46fff324dvboxsyncextern "C" NTSYSAPI NTSTATUS NTAPI ZwRequestWaitReplyPort(HANDLE, PVOID, PVOID);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync/**
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Initalizes the hardening bits.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync *
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * @returns NT status code.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsyncstatic NTSTATUS supdrvNtProtectInit(void)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync{
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Initialize the globals.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* The NT version. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync ULONG uMajor, uMinor, uBuild;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsGetVersion(&uMajor, &uMinor, &uBuild, NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_uNtVerCombined = SUP_MAKE_NT_VER_COMBINED(uMajor, uMinor, uBuild, 0, 0);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Resolve methods we want but isn't available everywhere. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync UNICODE_STRING RoutineName;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&RoutineName, L"ObGetObjectType");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnObGetObjectType = (PFNOBGETOBJECTTYPE)MmGetSystemRoutineAddress(&RoutineName);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&RoutineName, L"ObRegisterCallbacks");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnObRegisterCallbacks = (PFNOBREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&RoutineName, L"ObUnRegisterCallbacks");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnObUnRegisterCallbacks = (PFNOBUNREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName);
cb39011e69667689c166f1cdf95247b46fff324dvboxsync
cb39011e69667689c166f1cdf95247b46fff324dvboxsync RtlInitUnicodeString(&RoutineName, L"PsSetCreateProcessNotifyRoutineEx");
cb39011e69667689c166f1cdf95247b46fff324dvboxsync g_pfnPsSetCreateProcessNotifyRoutineEx = (PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)MmGetSystemRoutineAddress(&RoutineName);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&RoutineName, L"PsReferenceProcessFilePointer");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnPsReferenceProcessFilePointer = (PFNPSREFERENCEPROCESSFILEPOINTER)MmGetSystemRoutineAddress(&RoutineName);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync RtlInitUnicodeString(&RoutineName, L"PsIsProtectedProcessLight");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnPsIsProtectedProcessLight = (PFNPSISPROTECTEDPROCESSLIGHT)MmGetSystemRoutineAddress(&RoutineName);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RtlInitUnicodeString(&RoutineName, L"ZwAlpcCreatePort");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync g_pfnZwAlpcCreatePort = (PFNZWALPCCREATEPORT)MmGetSystemRoutineAddress(&RoutineName);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RtlInitUnicodeString(&RoutineName, L"ZwQueryVirtualMemory"); /* Yes, using Zw version here. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)MmGetSystemRoutineAddress(&RoutineName);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!g_pfnNtQueryVirtualMemory && g_uNtVerCombined < SUP_NT_VER_VISTA)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync /* XP & W2K3 doesn't have this function exported, so we've cooked up a
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync few alternative in the assembly helper file that uses the code in
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync ZwReadFile with a different eax value. We figure the syscall number
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync by inspecting ZwQueryVolumeInformationFile as it's the next number. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef RT_ARCH_X86
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint8_t const *pbCode = (uint8_t const *)(uintptr_t)ZwQueryVolumeInformationFile;
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync if (*pbCode == 0xb8) /* mov eax, dword */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync switch (*(uint32_t const *)&pbCode[1])
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb0: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xAF; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb1: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB0; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb2: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB1; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb3: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* XP SP3 */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb4: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb5: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB3; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb6: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB4; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb7: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB5; break; /* just in case */
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync case 0xb8: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB6; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xb9: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB7; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xba: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB8; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xbb: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBA; break; /* W2K3 R2 SP2 */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xbc: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBB; break; /* just in case */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync case 0xbd: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBC; break; /* just in case */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync case 0xbe: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBD; break; /* just in case */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync case 0xbf: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBE; break; /* just in case */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# elif defined(RT_ARCH_AMD64)
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync uint8_t const *pbCode = (uint8_t const *)(uintptr_t)ZwRequestWaitReplyPort;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( pbCode[ 0] == 0x48 /* mov rax, rsp */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 1] == 0x8b
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 2] == 0xc4
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 3] == 0xfa /* cli */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && pbCode[ 4] == 0x48 /* sub rsp, 10h */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && pbCode[ 5] == 0x83
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && pbCode[ 6] == 0xec
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 7] == 0x10
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 8] == 0x50 /* push rax */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[ 9] == 0x9c /* pushfq */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[10] == 0x6a /* push 10 */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[11] == 0x10
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[12] == 0x48 /* lea rax, [nt!KiServiceLinkage] */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[13] == 0x8d
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[14] == 0x05
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[19] == 0x50 /* push rax */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[20] == 0xb8 /* mov eax,1fh <- the syscall no. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*&& pbCode[21] == 0x1f*/
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[22] == 0x00
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[23] == 0x00
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[24] == 0x00
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && pbCode[25] == 0xe9 /* jmp KiServiceInternal */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint8_t const *pbKiServiceInternal = &pbCode[30] + *(int32_t const *)&pbCode[26];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync uint8_t const *pbKiServiceLinkage = &pbCode[19] + *(int32_t const *)&pbCode[15];
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (*pbKiServiceLinkage == 0xc3)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnKiServiceInternal = (PFNRT)pbKiServiceInternal;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_pfnKiServiceLinkage = (PFNRT)pbKiServiceLinkage;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync switch (pbCode[21])
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync {
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync case 0x1e: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x1F; break;
36c3589d6411416bba897f2595f1812b9d9ff4b3vboxsync case 0x1f: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x20; break;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync case 0x20: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x21; break;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync case 0x21: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x22; break;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync case 0x22: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x23; break;
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync }
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync }
c66e448632d5ef48cf6b896f02e750440f5c6586vboxsync }
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync# endif
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (!g_pfnNtQueryVirtualMemory)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: Cannot locate ZwQueryVirtualMemory in ntoskrnl, nor were we able to cook up a replacement.\n"));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return STATUS_PROCEDURE_NOT_FOUND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# ifdef VBOX_STRICT
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if ( g_uNtVerCombined >= SUP_NT_VER_W70
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync && ( g_pfnObGetObjectType == NULL
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync || g_pfnZwAlpcCreatePort == NULL) )
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync LogRel(("vboxdrv: g_pfnObGetObjectType=%p g_pfnZwAlpcCreatePort=%p.\n", g_pfnObGetObjectType, g_pfnZwAlpcCreatePort));
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return STATUS_PROCEDURE_NOT_FOUND;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync }
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync# endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync /* The spinlock protecting our structures. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync int rc = RTSpinlockCreate(&g_hNtProtectLock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "NtProtectLock");
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_FAILURE(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync return VBoxDrvNtErr2NtStatus(rc);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync g_NtProtectTree = NULL;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* Image stuff + certificates. */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync NTSTATUS rcNt;
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rc = supHardenedWinInitImageVerifier(NULL);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (RT_SUCCESS(rc))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Intercept process creation and termination.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pfnPsSetCreateProcessNotifyRoutineEx)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, FALSE /*fRemove*/);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync else
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, FALSE /*fRemove*/);
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (NT_SUCCESS(rcNt))
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /*
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * Intercept process and thread handle creation calls.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync * The preferred method is only available on Vista SP1+.
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync */
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync if (g_pfnObRegisterCallbacks && g_pfnObUnRegisterCallbacks)
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync static OB_OPERATION_REGISTRATION s_aObOperations[] =
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsProcessType,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectCallback_ProcessHandlePre,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectCallback_ProcessHandlePost,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync },
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync PsThreadType,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectCallback_ThreadHandlePre,
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync supdrvNtProtectCallback_ThreadHandlePost,
0802b726efeabba46f90cb2b285de4dadaac9507vboxsync },
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync };
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync static OB_CALLBACK_REGISTRATION s_ObCallbackReg =
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync {
ae94ad7e769e467419ab99cab5403bdb39bc544fvboxsync /* .Version = */ OB_FLT_REGISTRATION_VERSION,
/* .OperationRegistrationCount = */ RT_ELEMENTS(s_aObOperations),
/* .Altitude.Length = */ 0,
/* .Altitude.MaximumLength = */ 0,
/* .Altitude.Buffer = */ NULL,
/* .RegistrationContext = */ NULL,
/* .OperationRegistration = */ &s_aObOperations[0]
};
static WCHAR const *s_apwszAltitudes[] = /** @todo get a valid number */
{
L"48596.98940", L"46935.19485", L"49739.39704", L"40334.74976",
L"66667.98940", L"69888.19485", L"69889.39704", L"60364.74976",
L"85780.98940", L"88978.19485", L"89939.39704", L"80320.74976",
L"329879.98940", L"326787.19485", L"328915.39704", L"320314.74976",
};
rcNt = STATUS_FLT_INSTANCE_ALTITUDE_COLLISION;
for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszAltitudes) && rcNt == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; i++)
{
s_ObCallbackReg.Altitude.Buffer = (WCHAR *)s_apwszAltitudes[i];
s_ObCallbackReg.Altitude.Length = (uint16_t)RTUtf16Len(s_apwszAltitudes[i]) * sizeof(WCHAR);
s_ObCallbackReg.Altitude.MaximumLength = s_ObCallbackReg.Altitude.Length + sizeof(WCHAR);
rcNt = g_pfnObRegisterCallbacks(&s_ObCallbackReg, &g_pvObCallbacksCookie);
if (NT_SUCCESS(rcNt))
{
/*
* Happy ending.
*/
return STATUS_SUCCESS;
}
}
LogRel(("vboxdrv: ObRegisterCallbacks failed with rcNt=%#x\n", rcNt));
g_pvObCallbacksCookie = NULL;
}
else
{
/*
* For the time being, we do not implement extra process
* protection on pre-Vista-SP1 systems as they are lacking
* necessary KPIs. XP is end of life, we do not wish to
* spend more time on it, so we don't put up a fuss there.
* Vista users without SP1 can install SP1 (or later), darn it,
* so refuse to load.
*/
/** @todo Hack up an XP solution - will require hooking kernel APIs or doing bad
* stuff to a couple of object types. */
# ifndef VBOX_WITH_VISTA_NO_SP
if (g_uNtVerCombined >= SUP_NT_VER_VISTA)
# else
if (g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0))
# endif
{
DbgPrint("vboxdrv: ObRegisterCallbacks was not found. Please make sure you got the latest updates and service packs installed\n");
rcNt = STATUS_SXS_VERSION_CONFLICT;
}
else
{
Log(("vboxdrv: ObRegisterCallbacks was not found; ignored pre-Vista\n"));
return rcNt = STATUS_SUCCESS;
}
g_pvObCallbacksCookie = NULL;
}
/*
* Drop process create/term notifications.
*/
if (g_pfnPsSetCreateProcessNotifyRoutineEx)
g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
else
PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/);
}
else
LogRel(("vboxdrv: PsSetCreateProcessNotifyRoutine%s failed with rcNt=%#x\n",
g_pfnPsSetCreateProcessNotifyRoutineEx ? "Ex" : "", rcNt));
supHardenedWinTermImageVerifier();
}
else
rcNt = VBoxDrvNtErr2NtStatus(rc);
RTSpinlockDestroy(g_hNtProtectLock);
g_NtProtectTree = NIL_RTSPINLOCK;
return rcNt;
}
#endif /* VBOX_WITH_HARDENING */