SUPR3HardenedMain-win.cpp revision a6c871653045073d6ef74d0589de345ae62b607d
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/* $Id$ */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @file
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox Support Library - Hardened main(), windows bits.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Copyright (C) 2006-2014 Oracle Corporation
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * available from http://www.virtualbox.org. This file is free software;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * General Public License (GPL) as published by the Free Software
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The contents of this file may alternatively be used under the terms
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * of the Common Development and Distribution License Version 1.0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * CDDL are applicable instead of those of the GPL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * You may elect to license modified versions of this file under the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * terms and conditions of either the GPL or the CDDL or both.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Header Files *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/nt/nt-and-windows.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <AccCtrl.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <AclApi.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef PROCESS_SET_LIMITED_INFORMATION
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# define PROCESS_SET_LIMITED_INFORMATION 0x2000
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x200
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x800
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <VBox/sup.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <VBox/err.h>
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync#include <VBox/dis.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/ctype.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/string.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/initterm.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/param.h>
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync#include <iprt/path.h>
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync#include <iprt/thread.h>
edde275acba04aca58db4172a163741e3abadfbcvboxsync#include <iprt/zero.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "SUPLibInternal.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "win/SUPHardenedVerify-win.h"
40839c441cb305d84420565f7ca25403d8177413vboxsync#include "../SUPDrvIOC.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync#ifndef IMAGE_SCN_TYPE_NOLOAD
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync# define IMAGE_SCN_TYPE_NOLOAD 0x00000002
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync#endif
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Defined Constants And Macros *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
edde275acba04aca58db4172a163741e3abadfbcvboxsync/** The first argument of a respawed stub when respawned for the first time.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This just needs to be unique enough to avoid most confusion with real
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * executable names, there are other checks in place to make sure we've respanwed. */
a1d9d394b49969e730c5a8e037ea2d672a48dbf6vboxsync#define SUPR3_RESPAWN_1_ARG0 "60eaff78-4bdd-042d-2e72-669728efd737-suplib-2ndchild"
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync/** The first argument of a respawed stub when respawned for the second time.
edde275acba04aca58db4172a163741e3abadfbcvboxsync * This just needs to be unique enough to avoid most confusion with real
edde275acba04aca58db4172a163741e3abadfbcvboxsync * executable names, there are other checks in place to make sure we've respanwed. */
a1d9d394b49969e730c5a8e037ea2d672a48dbf6vboxsync#define SUPR3_RESPAWN_2_ARG0 "60eaff78-4bdd-042d-2e72-669728efd737-suplib-3rdchild"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Unconditional assertion. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define SUPR3HARDENED_ASSERT(a_Expr) \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync do { \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!(a_Expr)) \
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync supR3HardenedFatal("%s: %s\n", __FUNCTION__, #a_Expr); \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } while (0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Unconditional assertion of NT_SUCCESS. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define SUPR3HARDENED_ASSERT_NT_SUCCESS(a_Expr) \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync do { \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync NTSTATUS rcNtAssert = (a_Expr); \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!NT_SUCCESS(rcNtAssert)) \
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync supR3HardenedFatal("%s: %s -> %#x\n", __FUNCTION__, #a_Expr, rcNtAssert); \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } while (0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Unconditional assertion of a WIN32 API returning non-FALSE. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define SUPR3HARDENED_ASSERT_WIN32_SUCCESS(a_Expr) \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync do { \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync BOOL fRcAssert = (a_Expr); \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (fRcAssert == FALSE) \
30f07af559efcbd967e801903746fc21f81ee533vboxsync supR3HardenedFatal("%s: %s -> %#x\n", __FUNCTION__, #a_Expr, GetLastError()); \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } while (0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Structures and Typedefs *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Security descriptor cleanup structure.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef struct MYSECURITYCLEANUP
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync union
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SID Sid;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint8_t abPadding[SECURITY_MAX_SID_SIZE];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } Everyone, Owner, User, Login;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync union
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ACL AclHdr;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint8_t abPadding[1024];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } Acl;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PSECURITY_DESCRIPTOR pSecDesc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync} MYSECURITYCLEANUP;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Pointer to security cleanup structure. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef MYSECURITYCLEANUP *PMYSECURITYCLEANUP;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Image verifier cache entry.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef struct VERIFIERCACHEENTRY
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** Pointer to the next entry with the same hash value. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync struct VERIFIERCACHEENTRY * volatile pNext;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** Next entry in the WinVerifyTrust todo list. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync struct VERIFIERCACHEENTRY * volatile pNextTodoWvt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The file handle. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync HANDLE hFile;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** If fIndexNumber is set, this is an file system internal file identifier. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync LARGE_INTEGER IndexNumber;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The path hash value. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The verification result. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc;
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync /** Used for shutting up errors after a while. */
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync uint32_t volatile cErrorHits;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync /** The validation flags (for WinVerifyTrust retry). */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync uint32_t fFlags;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** Whether IndexNumber is valid */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync bool fIndexNumberValid;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** Whether verified by WinVerifyTrust. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync bool volatile fWinVerifyTrust;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** cwcPath * sizeof(RTUTF16). */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint16_t cbPath;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The full path of this entry (variable size). */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wszPath[1];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync} VERIFIERCACHEENTRY;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Pointer to an image verifier path entry. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef VERIFIERCACHEENTRY *PVERIFIERCACHEENTRY;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Name of an import DLL that we need to check out.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsynctypedef struct VERIFIERCACHEIMPORT
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** Pointer to the next DLL in the list. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync struct VERIFIERCACHEIMPORT * volatile pNext;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** The length of pwszAltSearchDir if available. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cwcAltSearchDir;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** This points the directory containing the DLL needing it, this will be
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * NULL for a System32 DLL. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PWCHAR pwszAltSearchDir;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /** The name of the import DLL (variable length). */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync char szName[1];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync} VERIFIERCACHEIMPORT;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/** Pointer to a import DLL that needs checking out. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsynctypedef VERIFIERCACHEIMPORT *PVERIFIERCACHEIMPORT;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/*******************************************************************************
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync* Global Variables *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync*******************************************************************************/
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** @name Global variables initialized by suplibHardenedWindowsMain.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @{ */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Combined windows NT version number. See SUP_MAKE_NT_VER_COMBINED. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncuint32_t g_uNtVerCombined = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Count calls to the special main function for linking santity checks. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic uint32_t volatile g_cSuplibHardenedWindowsMainCalls;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** The UTF-16 windows path to the executable. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncRTUTF16 g_wszSupLibHardenedExePath[1024];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** The NT path of the executable. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncSUPSYSROOTDIRBUF g_SupLibHardenedExeNtPath;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** The offset into g_SupLibHardenedExeNtPath of the executable name (WCHAR,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * not byte). This also gives the length of the exectuable directory path,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * including a trailing slash. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncuint32_t g_offSupLibHardenedExeNtName;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** @} */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** @name Hook related variables.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * @{ */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** The jump back address of the patched NtCreateSection. */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsyncextern "C" PFNRT g_pfnNtCreateSectionJmpBack = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Pointer to the bit of assembly code that will perform the original
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * NtCreateSection operation. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic NTSTATUS (NTAPI * g_pfnNtCreateSectionReal)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PLARGE_INTEGER, ULONG, ULONG, HANDLE);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 0
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** The jump back address of the patched LdrLoadDll. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncextern "C" PFNRT g_pfnLdrLoadDllJmpBack = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** Pointer to the bit of assembly code that will perform the original
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * LdrLoadDll operation. */
88d7b87c38cc3800f532139696785e8c96bfd531vboxsyncstatic NTSTATUS (NTAPI * g_pfnLdrLoadDllReal)(PWSTR, PULONG, PUNICODE_STRING, PHANDLE);
88d7b87c38cc3800f532139696785e8c96bfd531vboxsync/** The hash table of verifier cache . */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic PVERIFIERCACHEENTRY volatile g_apVerifierCache[128];
88d7b87c38cc3800f532139696785e8c96bfd531vboxsync/** Queue of cached images which needs WinVerifyTrust to check them. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic PVERIFIERCACHEENTRY volatile g_pVerifierCacheTodoWvt = NULL;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** Queue of cached images which needs their imports checked. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic PVERIFIERCACHEIMPORT volatile g_pVerifierCacheTodoImports = NULL;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** @ */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** Static error info structure used during init. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic RTERRINFOSTATIC g_ErrInfoStatic;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** In the assembly file. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncextern "C" uint8_t g_abSupHardReadWriteExecPage[PAGE_SIZE];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Whether we've patched our own LdrInitializeThunk or not. We do this to
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * disable thread creation. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic bool g_fSupInitThunkSelfPatched;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** The backup of our own LdrInitializeThunk code, for enabling and disabling
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * thread creation in this process. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic uint8_t g_abLdrInitThunkSelfBackup[16];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Mask of adversaries that we've detected (SUPHARDNT_ADVERSARY_XXX). */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic uint32_t g_fSupAdversaries = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** @name SUPHARDNT_ADVERSARY_XXX - Adversaries
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @{ */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Symantec endpoint protection or similar including SysPlant.sys. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT RT_BIT_32(0)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Symantec Norton 360. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_SYMANTEC_N360 RT_BIT_32(1)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Avast! */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_AVAST RT_BIT_32(2)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** TrendMicro OfficeScan and probably others. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_TRENDMICRO RT_BIT_32(3)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** McAfee. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_MCAFEE RT_BIT_32(4)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Kaspersky. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_KASPERSKY RT_BIT_32(5)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Malwarebytes Anti-Malware (MBAM). */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_MBAM RT_BIT_32(6)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** AVG Internet Security. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_AVG RT_BIT_32(7)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Panda Security. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#define SUPHARDNT_ADVERSARY_PANDA RT_BIT_32(8)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** Microsoft Security Essentials. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define SUPHARDNT_ADVERSARY_MSE RT_BIT_32(9)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Comodo. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define SUPHARDNT_ADVERSARY_COMODO RT_BIT_32(10)
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/** Unknown adversary detected while waiting on child. */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync#define SUPHARDNT_ADVERSARY_UNKNOWN RT_BIT_32(31)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** @} */
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync/*******************************************************************************
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync* Internal Functions *
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync bool *pfQuietFailure);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifdef RT_ARCH_AMD64
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# define SYSCALL(a_Num) DECLASM(void) RT_CONCAT(supR3HardenedJmpBack_NtCreateSection_,a_Num)(void)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# include "NtCreateSection-template-amd64-syscall-type-1.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# undef SYSCALL
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifdef RT_ARCH_X86
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# define SYSCALL(a_Num) DECLASM(void) RT_CONCAT(supR3HardenedJmpBack_NtCreateSection_,a_Num)(void)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# include "NtCreateSection-template-x86-syscall-type-1.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# undef SYSCALL
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Simple wide char search routine.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns Pointer to the first location of @a wcNeedle in @a pwszHaystack.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * NULL if not found.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @param pwszHaystack Pointer to the string that should be searched.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @param wcNeedle The character to search for.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncstatic PRTUTF16 suplibHardenedWStrChr(PCRTUTF16 pwszHaystack, RTUTF16 wcNeedle)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (;;)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync RTUTF16 wcCur = *pwszHaystack;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (wcCur == wcNeedle)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync return (PRTUTF16)pwszHaystack;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (wcCur == '\0')
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync return NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pwszHaystack++;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync/**
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Simple wide char string length routine.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync *
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * @returns The number of characters in the given string. (Excludes the
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * terminator.)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pwsz The string.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncstatic size_t suplibHardenedWStrLen(PCRTUTF16 pwsz)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync{
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync PCRTUTF16 pwszCur = pwsz;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync while (*pwszCur != '\0')
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pwszCur++;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync return pwszCur - pwsz;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Allocate zero filled memory on the heap.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * @returns Pointer to the memory. Will never return NULL, triggers a fatal
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * error instead.
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * @param cb The number of bytes to allocate.
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync */
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsyncDECLHIDDEN(void *) suplibHardenedAllocZ(size_t cb)
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync{
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync void *pv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync if (!pv)
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync supR3HardenedFatal("HeapAlloc failed to allocate %zu bytes.\n", cb);
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync return pv;
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync}
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync/**
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Reallocates memory on the heap.
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync *
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @returns Pointer to the resized memory block. Will never return NULL,
100b161379af7255c69e27587cc746e5f76ff050vboxsync * triggers a fatal error instead.
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @param pvOld The old memory block.
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @param cbNew The new block size.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsyncDECLHIDDEN(void *) suplibHardenedReAlloc(void *pvOld, size_t cbNew)
100b161379af7255c69e27587cc746e5f76ff050vboxsync{
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (!pvOld)
100b161379af7255c69e27587cc746e5f76ff050vboxsync return suplibHardenedAllocZ(cbNew);
100b161379af7255c69e27587cc746e5f76ff050vboxsync void *pv = HeapReAlloc(GetProcessHeap(), 0 /*dwFlags*/, pvOld, cbNew);
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (!pv)
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedFatal("HeapReAlloc failed to allocate %zu bytes.\n", cbNew);
100b161379af7255c69e27587cc746e5f76ff050vboxsync return pv;
100b161379af7255c69e27587cc746e5f76ff050vboxsync}
100b161379af7255c69e27587cc746e5f76ff050vboxsync
a6c871653045073d6ef74d0589de345ae62b607dvboxsync
a6c871653045073d6ef74d0589de345ae62b607dvboxsync/**
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsync * Frees memory allocated by suplibHardenedAlloc, suplibHardenedAllocZ or
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsync * suplibHardenedReAlloc.
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync *
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync * @param pv Pointer to the memeory to be freed.
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync */
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsyncDECLHIDDEN(void) suplibHardenedFree(void *pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pv);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync/**
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync * Wrapper around LoadLibraryEx that deals with the UTF-8 to UTF-16 conversion
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync * and supplies the right flags.
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync *
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * @returns Module handle on success, NULL on failure.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pszName The full path to the DLL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param fSystem32Only Whether to only look for imports in the system32
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * directory. If set to false, the application
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * directory is also searched.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncDECLHIDDEN(void *) supR3HardenedWinLoadLibrary(const char *pszName, bool fSystem32Only)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync WCHAR wszPath[RTPATH_MAX];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTUTF16 pwszPath = wszPath;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTStrToUtf16Ex(pszName, RTSTR_MAX, &pwszPath, RT_ELEMENTS(wszPath), NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (*pwszPath)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (*pwszPath == '/')
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *pwszPath = '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pwszPath++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync DWORD fFlags = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!fSystem32Only)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync void *pvRet = (void *)LoadLibraryExW(wszPath, NULL /*hFile*/, fFlags);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Vista, W7, W2K8R might not work without KB2533623, so retry with no flags. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( !pvRet
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && fFlags
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 2)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && GetLastError() == ERROR_INVALID_PARAMETER)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pvRet = (void *)LoadLibraryExW(wszPath, NULL /*hFile*/, 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pvRet;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedFatal("RTStrToUtf16Ex failed on '%s': %Rrc", pszName, rc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return NULL;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync}
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync/**
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync * Gets the internal index number of the file.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync *
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync * @returns True if we got an index number, false if not.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync * @param hFile The file in question.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync * @param pIndexNumber where to return the index number.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync */
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsyncstatic bool supR3HardenedWinVerifyCacheGetIndexNumber(HANDLE hFile, PLARGE_INTEGER pIndexNumber)
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync{
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync NTSTATUS rcNt = NtQueryInformationFile(hFile, &Ios, pIndexNumber, sizeof(*pIndexNumber), FileInternalInformation);
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (NT_SUCCESS(rcNt))
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync rcNt = Ios.Status;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync#ifdef DEBUG_bird
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (!NT_SUCCESS(rcNt))
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync __debugbreak();
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync#endif
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync return NT_SUCCESS(rcNt) && pIndexNumber->QuadPart != 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Calculates the hash value for the given UTF-16 path string.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns Hash value.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pUniStr String to hash.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic uint32_t supR3HardenedWinVerifyCacheHashPath(PCUNICODE_STRING pUniStr)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t uHash = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned cwcLeft = pUniStr->Length / sizeof(WCHAR);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTUTF16 pwc = pUniStr->Buffer;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcLeft-- > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wc = *pwc++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (wc < 0x80)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync wc = wc != '/' ? RT_C_TO_LOWER(wc) : '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uHash = wc + (uHash << 6) + (uHash << 16) - uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Calculates the hash value for a directory + filename combo as if they were
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * one single string.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns Hash value.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pawcDir The directory name.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param cwcDir The length of the directory name. RTSTR_MAX if
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * not available.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pszName The import name (UTF-8).
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic uint32_t supR3HardenedWinVerifyCacheHashDirAndFile(PCRTUTF16 pawcDir, uint32_t cwcDir, const char *pszName)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
30f07af559efcbd967e801903746fc21f81ee533vboxsync uint32_t uHash = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcDir-- > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wc = *pawcDir++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (wc < 0x80)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync wc = wc != '/' ? RT_C_TO_LOWER(wc) : '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uHash = wc + (uHash << 6) + (uHash << 16) - uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned char ch = '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uHash = ch + (uHash << 6) + (uHash << 16) - uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while ((ch = *pszName++) != '\0')
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ch = RT_C_TO_LOWER(ch);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uHash = ch + (uHash << 6) + (uHash << 16) - uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return uHash;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Verify string cache compare function.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns true if the strings match, false if not.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pawcLeft The left hand string.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pawcRight The right hand string.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param cwcToCompare The number of chars to compare.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic bool supR3HardenedWinVerifyCacheIsMatch(PCRTUTF16 pawcLeft, PCRTUTF16 pawcRight, uint32_t cwcToCompare)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Try a quick memory compare first. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (memcmp(pawcLeft, pawcRight, cwcToCompare * sizeof(RTUTF16)) == 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return true;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Slow char by char compare. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcToCompare-- > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wcLeft = *pawcLeft++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wcRight = *pawcRight++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (wcLeft != wcRight)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync wcLeft = wcLeft != '/' ? RT_C_TO_LOWER(wcLeft) : '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync wcLeft = wcRight != '/' ? RT_C_TO_LOWER(wcRight) : '\\';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (wcLeft != wcRight)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return false;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return true;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Inserts the given verifier result into the cache.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param pUniStr The full path of the image.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param hFile The file handle - must either be entered into
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * the cache or closed.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param rc The verifier result.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param fWinVerifyTrust Whether verified by WinVerifyTrust or not.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param fFlags The image verification flags.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsyncstatic void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync bool fWinVerifyTrust, uint32_t fFlags)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Allocate and initalize a new entry.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEENTRY pEntry = (PVERIFIERCACHEENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync sizeof(VERIFIERCACHEENTRY) + pUniStr->Length);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pEntry)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->pNext = NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->pNextTodoWvt = NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->hFile = hFile;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->uHash = supR3HardenedWinVerifyCacheHashPath(pUniStr);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->rc = rc;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->fFlags = fFlags;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->cErrorHits = 0;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->fWinVerifyTrust = fWinVerifyTrust;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->cbPath = pUniStr->Length;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(pEntry->wszPath, pUniStr->Buffer, pUniStr->Length);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pEntry->wszPath[pUniStr->Length / sizeof(WCHAR)] = '\0';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pEntry->fIndexNumberValid = supR3HardenedWinVerifyCacheGetIndexNumber(hFile, &pEntry->IndexNumber);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Try insert it, careful with concurrent code as well as potential duplicates.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t iHashTab = pEntry->uHash % RT_ELEMENTS(g_apVerifierCache);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync VERIFIERCACHEENTRY * volatile *ppEntry = &g_apVerifierCache[iHashTab];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (;;)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (ASMAtomicCmpXchgPtr(ppEntry, pEntry, NULL))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!fWinVerifyTrust)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync do
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pEntry->pNextTodoWvt = g_pVerifierCacheTodoWvt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync while (!ASMAtomicCmpXchgPtr(&g_pVerifierCacheTodoWvt, pEntry, pEntry->pNextTodoWvt));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheInsert: %ls\n", pUniStr->Buffer));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEENTRY pOther = *ppEntry;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!pOther)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync continue;
efdc3bd872b77b5ec7d19d77504264de24b0582bvboxsync if ( pOther->uHash == pEntry->uHash
efdc3bd872b77b5ec7d19d77504264de24b0582bvboxsync && pOther->cbPath == pEntry->cbPath
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && supR3HardenedWinVerifyCacheIsMatch(pOther->wszPath, pEntry->wszPath, pEntry->cbPath / sizeof(RTUTF16)))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync break;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ppEntry = &pOther->pNext;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Duplicate entry (may happen due to races). */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pEntry);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NtClose(hFile);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Looks up an entry in the verifier hash table.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @return Pointer to the entry on if found, NULL if not.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pUniStr The full path of the image.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param hFile The file handle.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic PVERIFIERCACHEENTRY supR3HardenedWinVerifyCacheLookup(PCUNICODE_STRING pUniStr, HANDLE hFile)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync{
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync PRTUTF16 const pwszPath = pUniStr->Buffer;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint16_t const cbPath = pUniStr->Length;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t uHash = supR3HardenedWinVerifyCacheHashPath(pUniStr);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t iHashTab = uHash % RT_ELEMENTS(g_apVerifierCache);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PVERIFIERCACHEENTRY pCur = g_apVerifierCache[iHashTab];
30f07af559efcbd967e801903746fc21f81ee533vboxsync while (pCur)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pCur->uHash == uHash
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pCur->cbPath == cbPath
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && supR3HardenedWinVerifyCacheIsMatch(pCur->wszPath, pwszPath, cbPath / sizeof(RTUTF16)))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync if (!pCur->fIndexNumberValid)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync return pCur;
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync LARGE_INTEGER IndexNumber;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync bool fIndexNumberValid = supR3HardenedWinVerifyCacheGetIndexNumber(hFile, &IndexNumber);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( fIndexNumberValid
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && IndexNumber.QuadPart == pCur->IndexNumber.QuadPart)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return pCur;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync#ifdef DEBUG_bird
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync __debugbreak();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pCur = pCur->pNext;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Looks up an import DLL in the verifier hash table.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @return Pointer to the entry on if found, NULL if not.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param pawcDir The directory name.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param cwcDir The length of the directory name.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param pszName The import name (UTF-8).
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic PVERIFIERCACHEENTRY supR3HardenedWinVerifyCacheLookupImport(PCRTUTF16 pawcDir, uint32_t cwcDir, const char *pszName)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t uHash = supR3HardenedWinVerifyCacheHashDirAndFile(pawcDir, cwcDir, pszName);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t iHashTab = uHash % RT_ELEMENTS(g_apVerifierCache);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t const cbPath = (uint32_t)((cwcDir + 1 + strlen(pszName)) * sizeof(RTUTF16));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEENTRY pCur = g_apVerifierCache[iHashTab];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync while (pCur)
e17f6f8a70a7709a9a6319d9a473596fb600b552vboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( pCur->uHash == uHash
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pCur->cbPath == cbPath)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (supR3HardenedWinVerifyCacheIsMatch(pCur->wszPath, pawcDir, cwcDir))
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
30f07af559efcbd967e801903746fc21f81ee533vboxsync if (pCur->wszPath[cwcDir] == '\\' || pCur->wszPath[cwcDir] == '/')
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTUtf16ICmpAscii(&pCur->wszPath[cwcDir + 1], pszName))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pCur;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pCur = pCur->pNext;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Schedules the import DLLs for verification and entry into the cache.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param hLdrMod The loader module which imports should be
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * scheduled for verification.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pwszName The full NT path of the module.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncDECLHIDDEN(void) supR3HardenedWinVerifyCacheScheduleImports(RTLDRMOD hLdrMod, PCRTUTF16 pwszName)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Any imports?
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cImports;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_IMPORT_COUNT, NULL /*pvBits*/, &cImports, sizeof(cImports), NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cImports)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Figure out the DLL directory from pwszName.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTUTF16 pawcDir = pwszName;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cwcDir = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t i = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 wc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while ((wc = pawcDir[i++]) != '\0')
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ((wc == '\\' || wc == '/' || wc == ':') && cwcDir + 2 != i)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcDir = i - 1;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( g_System32NtPath.UniStr.Length / sizeof(WCHAR) == cwcDir
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && supR3HardenedWinVerifyCacheIsMatch(pawcDir, g_System32NtPath.UniStr.Buffer, cwcDir))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pawcDir = NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Enumerate the imports.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (i = 0; i < cImports; i++)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync union
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync char szName[256];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t iImport;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync } uBuf;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uBuf.iImport = i;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_IMPORT_MODULE, NULL /*pvBits*/, &uBuf, sizeof(uBuf), NULL);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (RT_SUCCESS(rc))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Skip kernel32, ntdll and API set stuff.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync RTStrToLower(uBuf.szName);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( RTStrCmp(uBuf.szName, "kernel32.dll") == 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || RTStrCmp(uBuf.szName, "kernelbase.dll") == 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || RTStrCmp(uBuf.szName, "ntdll.dll") == 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || RTStrNCmp(uBuf.szName, RT_STR_TUPLE("api-ms-win-")) == 0 )
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync continue;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Skip to the next one if it's already in the cache.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (supR3HardenedWinVerifyCacheLookupImport(g_System32NtPath.UniStr.Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_System32NtPath.UniStr.Length / sizeof(WCHAR),
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uBuf.szName) != NULL)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheScheduleImports: '%s' cached for system32\n", uBuf.szName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync continue;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedExeNtPath.UniStr.Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_offSupLibHardenedExeNtName,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uBuf.szName) != NULL)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheScheduleImports: '%s' cached for appdir\n", uBuf.szName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync continue;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (pawcDir && supR3HardenedWinVerifyCacheLookupImport(pawcDir, cwcDir, uBuf.szName) != NULL)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheScheduleImports: '%s' cached for dll dir\n", uBuf.szName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync continue;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* We could skip already scheduled modules, but that'll require serialization and extra work... */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Add it to the todo list.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheScheduleImports: Import todo: #%u '%s'.\n", i, uBuf.szName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cbName = (uint32_t)strlen(uBuf.szName) + 1;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cbNameAligned = RT_ALIGN_32(cbName, sizeof(RTUTF16));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cbNeeded = RT_OFFSETOF(VERIFIERCACHEIMPORT, szName[cbNameAligned])
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync + (pawcDir ? (cwcDir + 1) * sizeof(RTUTF16) : 0);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEIMPORT pImport = (PVERIFIERCACHEIMPORT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNeeded);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (pImport)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Init it. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(pImport->szName, uBuf.szName, cbName);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!pawcDir)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->cwcAltSearchDir = 0;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->pwszAltSearchDir = NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->cwcAltSearchDir = cwcDir;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->pwszAltSearchDir = (PRTUTF16)&pImport->szName[cbNameAligned];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(pImport->pwszAltSearchDir, pawcDir, cwcDir * sizeof(RTUTF16));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->pwszAltSearchDir[cwcDir] = '\0';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Insert it. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync do
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pImport->pNext = g_pVerifierCacheTodoImports;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync while (!ASMAtomicCmpXchgPtr(&g_pVerifierCacheTodoImports, pImport, pImport->pNext));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("RTLDRPROP_IMPORT_MODULE failed with rc=%Rrc i=%#x on '%ls'\n", rc, i, pwszName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("'%ls' has no imports\n", pwszName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("RTLDRPROP_IMPORT_COUNT failed with rc=%Rrc on '%ls'\n", rc, pwszName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Processes the list of import todos.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsyncstatic void supR3HardenedWinVerifyCacheProcessImportTodos(void)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Work until we've got nothing more todo.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (;;)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEIMPORT pTodo = ASMAtomicXchgPtrT(&g_pVerifierCacheTodoImports, NULL, PVERIFIERCACHEIMPORT);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!pTodo)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync break;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync do
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PVERIFIERCACHEIMPORT pCur = pTodo;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pTodo = pTodo->pNext;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Not in the cached already?
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( !supR3HardenedWinVerifyCacheLookupImport(g_System32NtPath.UniStr.Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_System32NtPath.UniStr.Length / sizeof(WCHAR),
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pCur->szName)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && !supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedExeNtPath.UniStr.Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_offSupLibHardenedExeNtName,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pCur->szName)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && ( pCur->cwcAltSearchDir == 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || !supR3HardenedWinVerifyCacheLookupImport(pCur->pwszAltSearchDir, pCur->cwcAltSearchDir, pCur->szName)) )
30f07af559efcbd967e801903746fc21f81ee533vboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Try locate the imported DLL and open it.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: Processing '%s'...\n", pCur->szName));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NTSTATUS rcNt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NTSTATUS rcNtRedir = 0x22222222;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync HANDLE hFile = INVALID_HANDLE_VALUE;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync RTUTF16 wszPath[260 + 260]; /* Assumes we've limited the import name length to 256. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync AssertCompile(sizeof(wszPath) > sizeof(g_System32NtPath));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Check for DLL isolation / redirection / mapping.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync size_t cwcName = 260;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PRTUTF16 pwszName = &wszPath[0];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync int rc = RTStrToUtf16Ex(pCur->szName, RTSTR_MAX, &pwszName, cwcName, &cwcName);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (RT_SUCCESS(rc))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UNICODE_STRING UniStrName;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrName.Buffer = wszPath;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrName.Length = (USHORT)cwcName * sizeof(WCHAR);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrName.MaximumLength = UniStrName.Length + sizeof(WCHAR);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UNICODE_STRING UniStrStatic;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrStatic.Buffer = &wszPath[cwcName + 1];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrStatic.Length = 0;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UniStrStatic.MaximumLength = (USHORT)(sizeof(wszPath) - cwcName * sizeof(WCHAR) - sizeof(WCHAR));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll");
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UNICODE_STRING UniStrDynamic = { 0, 0, NULL };
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PUNICODE_STRING pUniStrResult = NULL;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNtRedir = RtlDosApplyFileIsolationRedirection_Ustr(1 /*fFlags*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &UniStrName,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync (PUNICODE_STRING)&s_DefaultSuffix,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &UniStrStatic,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &UniStrDynamic,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &pUniStrResult,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pNewFlags*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pcbFilename*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pcbNeeded*/);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (NT_SUCCESS(rcNtRedir))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync OBJECT_ATTRIBUTES ObjAttr;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync InitializeObjectAttributes(&ObjAttr, pUniStrResult,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = NtCreateFile(&hFile,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &ObjAttr,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &Ios,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /* Allocation Size*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync FILE_ATTRIBUTE_NORMAL,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync FILE_SHARE_READ,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync FILE_OPEN,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*EaBuffer*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 0 /*EaLength*/);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = Ios.Status;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* For accurate logging. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync size_t cwcCopy = RT_MIN(pUniStrResult->Length / sizeof(RTUTF16), RT_ELEMENTS(wszPath) - 1);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(wszPath, pUniStrResult->Buffer, cwcCopy * sizeof(RTUTF16));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync wszPath[cwcCopy] = '\0';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync hFile = INVALID_HANDLE_VALUE;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync RtlFreeUnicodeString(&UniStrDynamic);
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: RTStrToUtf16Ex #1 failed: %Rrc\n", rc));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync /*
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * If not something that gets remapped, do the half normal searching we need.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (hFile == INVALID_HANDLE_VALUE)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync struct
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PRTUTF16 pawcDir;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync uint32_t cwcDir;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync } Tmp, aDirs[] =
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync { g_System32NtPath.UniStr.Buffer, g_System32NtPath.UniStr.Length / sizeof(WCHAR) },
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync { g_SupLibHardenedExeNtPath.UniStr.Buffer, g_offSupLibHardenedExeNtName - 1 },
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync { pCur->pwszAltSearchDir, pCur->cwcAltSearchDir },
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync };
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /* Search System32 first, unless it's a 'V*' or 'm*' name, the latter for msvcrt. */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if ( pCur->szName[0] == 'v'
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync || pCur->szName[0] == 'V'
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync || pCur->szName[0] == 'm'
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync || pCur->szName[0] == 'M')
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync Tmp = aDirs[0];
100b161379af7255c69e27587cc746e5f76ff050vboxsync aDirs[0] = aDirs[1];
100b161379af7255c69e27587cc746e5f76ff050vboxsync aDirs[1] = Tmp;
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(aDirs); i++)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (aDirs[i].pawcDir && aDirs[i].cwcDir && aDirs[i].cwcDir < RT_ELEMENTS(wszPath) / 3 * 2)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync memcpy(wszPath, aDirs[i].pawcDir, aDirs[i].cwcDir * sizeof(RTUTF16));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync uint32_t cwc = aDirs[i].cwcDir;
100b161379af7255c69e27587cc746e5f76ff050vboxsync wszPath[cwc++] = '\\';
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync cwcName = RT_ELEMENTS(wszPath) - cwc;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync pwszName = &wszPath[cwc];
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rc = RTStrToUtf16Ex(pCur->szName, RTSTR_MAX, &pwszName, cwcName, &cwcName);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (RT_SUCCESS(rc))
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync UNICODE_STRING NtName;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync NtName.Buffer = wszPath;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync NtName.Length = (USHORT)((cwc + cwcName) * sizeof(WCHAR));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync NtName.MaximumLength = NtName.Length + sizeof(WCHAR);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync OBJECT_ATTRIBUTES ObjAttr;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rcNt = NtCreateFile(&hFile,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync &ObjAttr,
100b161379af7255c69e27587cc746e5f76ff050vboxsync &Ios,
100b161379af7255c69e27587cc746e5f76ff050vboxsync NULL /* Allocation Size*/,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FILE_ATTRIBUTE_NORMAL,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FILE_SHARE_READ,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FILE_OPEN,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
100b161379af7255c69e27587cc746e5f76ff050vboxsync NULL /*EaBuffer*/,
100b161379af7255c69e27587cc746e5f76ff050vboxsync 0 /*EaLength*/);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (NT_SUCCESS(rcNt))
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rcNt = Ios.Status;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync break;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync hFile = INVALID_HANDLE_VALUE;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: RTStrToUtf16Ex #2 failed: %Rrc\n", rc));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync /*
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * If we successfully opened it, verify it and cache the result.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (hFile != INVALID_HANDLE_VALUE)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: '%s' -> '%ls' [rcNtRedir=%#x]\n",
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync pCur->szName, wszPath, rcNtRedir));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync ULONG fAccess = 0;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync ULONG fProtect = 0;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync bool fCallRealApi = false;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync "Imports", false /*fAvoidWinVerifyTrust*/, NULL /*pfQuietFailure*/);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync NtClose(hFile);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync else
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: Failed to locate '%s'\n", pCur->szName));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync else
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: '%s' is in the cache.\n", pCur->szName));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pCur);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync } while (pTodo);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync}
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync/**
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * Processes the list of WinVerifyTrust todos.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsyncstatic void supR3HardenedWinVerifyCacheProcessWvtTodos(void)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync{
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync PVERIFIERCACHEENTRY pReschedule = NULL;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync PVERIFIERCACHEENTRY volatile *ppReschedLastNext = NULL;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync /*
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * Work until we've got nothing more todo.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync for (;;)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (!supHardenedWinIsWinVerifyTrustCallable())
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync break;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync PVERIFIERCACHEENTRY pTodo = ASMAtomicXchgPtrT(&g_pVerifierCacheTodoWvt, NULL, PVERIFIERCACHEENTRY);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (!pTodo)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync break;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync do
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync PVERIFIERCACHEENTRY pCur = pTodo;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync pTodo = pTodo->pNextTodoWvt;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync pCur->pNextTodoWvt = NULL;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if ( !pCur->fWinVerifyTrust
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync && RT_SUCCESS(pCur->rc))
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync bool fWinVerifyTrust = false;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync int rc = supHardenedWinVerifyImageTrust(pCur->hFile, pCur->wszPath, pCur->fFlags, pCur->rc,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync &fWinVerifyTrust, NULL /* pErrInfo*/);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (RT_FAILURE(rc) || fWinVerifyTrust)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessWvtTodos: %d (was %d) fWinVerifyTrust=%d for '%ls'\n",
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rc, pCur->rc, fWinVerifyTrust, pCur->wszPath));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pCur->fWinVerifyTrust = true;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pCur->rc = rc;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Retry it at a later time. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessWvtTodos: %d (was %d) fWinVerifyTrust=%d for '%ls' [rescheduled]\n",
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rc, pCur->rc, fWinVerifyTrust, pCur->wszPath));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!pReschedule)
100b161379af7255c69e27587cc746e5f76ff050vboxsync ppReschedLastNext = &pCur->pNextTodoWvt;
100b161379af7255c69e27587cc746e5f76ff050vboxsync pCur->pNextTodoWvt = pReschedule;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* else: already processed. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync } while (pTodo);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Anything to reschedule.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (pReschedule)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync do
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *ppReschedLastNext = g_pVerifierCacheTodoWvt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync while (!ASMAtomicCmpXchgPtr(&g_pVerifierCacheTodoWvt, pReschedule, *ppReschedLastNext));
30f07af559efcbd967e801903746fc21f81ee533vboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Checks whether the path could be containing alternative 8.3 names generated
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * by NTFS, FAT, or other similar file systems.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync *
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @returns Pointer to the first component that might be an 8.3 name, NULL if
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * not 8.3 path.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @param pwszPath The path to check.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsyncstatic PRTUTF16 supR3HardenedWinIsPossible8dot3Path(PCRTUTF16 pwszPath)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync{
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync PCRTUTF16 pwszName = pwszPath;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync for (;;)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync RTUTF16 wc = *pwszPath++;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (wc == '~')
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync /* Could check more here before jumping to conclusions... */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (pwszPath - pwszName <= 8+1+3)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync return (PRTUTF16)pwszName;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync else if (wc == '\\' || wc == '/' || wc == ':')
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync pwszName = pwszPath;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync else if (wc == 0)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync break;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync return NULL;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync}
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync/**
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * Fixes up a path possibly containing one or more alternative 8-dot-3 style
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * components.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync *
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * The path is fixed up in place. Errors are ignored.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync *
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @param hFile The handle to the file which path we're fixing up.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @param pUniStr The path to fix up. MaximumLength is the max buffer
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * length.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsyncstatic void supR3HardenedWinFix8dot3Path(HANDLE hFile, PUNICODE_STRING pUniStr)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync{
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync /*
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * We could use FileNormalizedNameInformation here and slap the volume device
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * path in front of the result, but it's only supported since windows 8.0
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * according to some docs... So we expand all supicious names.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync PRTUTF16 pwszFix = pUniStr->Buffer;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync while (*pwszFix)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync pwszFix = supR3HardenedWinIsPossible8dot3Path(pwszFix);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (pwszFix == NULL)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync break;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync RTUTF16 wc;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync PRTUTF16 pwszFixEnd = pwszFix;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync while ((wc = *pwszFixEnd) != '\0' && wc != '\\' && wc != '//')
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync pwszFixEnd++;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (wc == '\0')
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync break;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync RTUTF16 const wcSaved = *pwszFix;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync *pwszFix = '\0'; /* paranoia. */
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync UNICODE_STRING NtDir;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync NtDir.Buffer = pUniStr->Buffer;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NtDir.Length = NtDir.MaximumLength = (USHORT)((pwszFix - pUniStr->Buffer) * sizeof(WCHAR));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync HANDLE hDir = RTNT_INVALID_HANDLE_VALUE;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync OBJECT_ATTRIBUTES ObjAttr;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync InitializeObjectAttributes(&ObjAttr, &NtDir, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NTSTATUS rcNt = NtCreateFile(&hDir,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_READ_DATA | SYNCHRONIZE,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &ObjAttr,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &Ios,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NULL /* Allocation Size*/,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_ATTRIBUTE_NORMAL,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_OPEN,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NULL /*EaBuffer*/,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync 0 /*EaLength*/);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync *pwszFix = wcSaved;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (NT_SUCCESS(rcNt))
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync union
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FILE_BOTH_DIR_INFORMATION Info;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uint8_t abBuffer[sizeof(FILE_BOTH_DIR_INFORMATION) + 2048 * sizeof(WCHAR)];
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync } uBuf;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync RT_ZERO(uBuf);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync UNICODE_STRING NtFilterStr;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NtFilterStr.Buffer = pwszFix;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NtFilterStr.Length = (USHORT)((uintptr_t)pwszFixEnd - (uintptr_t)pwszFix);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NtFilterStr.MaximumLength = NtFilterStr.Length;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync rcNt = NtQueryDirectoryFile(hDir,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NULL /* Event */,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NULL /* ApcRoutine */,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NULL /* ApcContext */,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &Ios,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &uBuf,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync sizeof(uBuf) - sizeof(WCHAR),
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FileBothDirectoryInformation,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FALSE /*ReturnSingleEntry*/,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &NtFilterStr,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync FALSE /*RestartScan */);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (NT_SUCCESS(rcNt) && uBuf.Info.NextEntryOffset == 0) /* There shall only be one entry matching... */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uint32_t offName = uBuf.Info.FileNameLength / sizeof(WCHAR);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync while (offName > 0 && uBuf.Info.FileName[offName - 1] != '\\' && uBuf.Info.FileName[offName - 1] != '/')
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync offName--;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uint32_t cwcNameNew = (uBuf.Info.FileNameLength / sizeof(WCHAR)) - offName;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uint32_t cwcNameOld = pwszFixEnd - pwszFix;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (cwcNameOld == cwcNameNew)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync memcpy(pwszFix, &uBuf.Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
efdc3bd872b77b5ec7d19d77504264de24b0582bvboxsync else if ( pUniStr->Length + cwcNameNew * sizeof(WCHAR) - cwcNameOld * sizeof(WCHAR) + sizeof(WCHAR)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync <= pUniStr->MaximumLength)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync size_t cwcLeft = pUniStr->Length - (pwszFixEnd - pUniStr->Buffer) * sizeof(WCHAR) + sizeof(WCHAR);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync memmove(&pwszFix[cwcNameNew], pwszFixEnd, cwcLeft * sizeof(WCHAR));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pUniStr->Length -= (USHORT)(cwcNameOld * sizeof(WCHAR));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pUniStr->Length += (USHORT)(cwcNameNew * sizeof(WCHAR));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pwszFixEnd -= cwcNameOld;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pwszFixEnd -= cwcNameNew;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync memcpy(pwszFix, &uBuf.Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /* else: ignore overflow. */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /* else: ignore failure. */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NtClose(hDir);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /* Advance */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pwszFix = pwszFixEnd;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync}
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsyncstatic NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync bool *pfQuietFailure)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync{
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync *pfCallRealApi = false;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (pfQuietFailure)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync *pfQuietFailure = false;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /*
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync * Query the name of the file, making sure to zero terminator the
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync * string. (2nd half of buffer is used for error info, see below.)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync union
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync UNICODE_STRING UniStr;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uint8_t abBuffer[sizeof(UNICODE_STRING) + 2048 * sizeof(WCHAR)];
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync } uBuf;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync RT_ZERO(uBuf);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync ULONG cbNameBuf;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync NTSTATUS rcNt = NtQueryObject(hFile, ObjectNameInformation, &uBuf, sizeof(uBuf) - sizeof(WCHAR) - 128, &cbNameBuf);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (!NT_SUCCESS(rcNt))
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync supR3HardenedError(VINF_SUCCESS, false,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync "supR3HardenedScreenImage/%s: NtQueryObject -> %#x (fImage=%d fProtect=%#x fAccess=%#x)\n",
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pszCaller, fImage, *pfProtect, *pfAccess);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync return rcNt;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (supR3HardenedWinIsPossible8dot3Path(uBuf.UniStr.Buffer))
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync supR3HardenedWinFix8dot3Path(hFile, &uBuf.UniStr);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /*
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync * Check the cache.
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync PVERIFIERCACHEENTRY pCacheHit = supR3HardenedWinVerifyCacheLookup(&uBuf.UniStr, hFile);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (pCacheHit)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync /* If we haven't done the WinVerifyTrust thing, do it if we can. */
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if ( !pCacheHit->fWinVerifyTrust
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync && RT_SUCCESS(pCacheHit->rc)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync && supHardenedWinIsWinVerifyTrustCallable() )
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (!fAvoidWinVerifyTrust)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls [redoing WinVerifyTrust]\n",
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pszCaller, pCacheHit->rc, pCacheHit->wszPath));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync bool fWinVerifyTrust = false;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync int rc = supHardenedWinVerifyImageTrust(pCacheHit->hFile, pCacheHit->wszPath, pCacheHit->fFlags, pCacheHit->rc,
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync &fWinVerifyTrust, NULL /* pErrInfo*/);
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync if (RT_FAILURE(rc) || fWinVerifyTrust)
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync {
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: %d (was %d) fWinVerifyTrust=%d for '%ls'\n",
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pszCaller, rc, pCacheHit->rc, fWinVerifyTrust, pCacheHit->wszPath));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pCacheHit->fWinVerifyTrust = true;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pCacheHit->rc = rc;
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync else
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: WinVerifyTrust not available, rescheduling %ls\n",
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync pszCaller, pCacheHit->wszPath));
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync }
4f2b002896072b0b5a7cb566341c8bac5e69392bvboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls [avoiding WinVerifyTrust]\n",
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync pszCaller, pCacheHit->rc, pCacheHit->wszPath));
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (pCacheHit->cErrorHits < 16)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls%s\n",
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync pszCaller, pCacheHit->rc, pCacheHit->wszPath, pCacheHit->fWinVerifyTrust ? "" : " [lacks WinVerifyTrust]"));
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /* Return the cached value. */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (RT_SUCCESS(pCacheHit->rc))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfCallRealApi = true;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_SUCCESS;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync uint32_t cErrorHits = ASMAtomicIncU32(&pCacheHit->cErrorHits);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if ( cErrorHits < 8
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync || RT_IS_POWER_OF_TWO(cErrorHits))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedError(VINF_SUCCESS, false,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "supR3HardenedScreenImage/%s: cached rc=%Rrc fImage=%d fProtect=%#x fAccess=%#x cErrorHits=%u %ls\n",
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pszCaller, pCacheHit->rc, fImage, *pfProtect, *pfAccess, cErrorHits, uBuf.UniStr.Buffer);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else if (pfQuietFailure)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfQuietFailure = true;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return STATUS_TRUST_FAILURE;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * On XP the loader might hand us handles with just FILE_EXECUTE and
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * SYNCHRONIZE, the means reading will fail later on. Also, we need
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * READ_CONTROL access to check the file ownership later on, and non
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * of the OS versions seems be giving us that. So, in effect we
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * more or less always reopen the file here.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync HANDLE hMyFile = NULL;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync rcNt = NtDuplicateObject(NtCurrentProcess(), hFile, NtCurrentProcess(),
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync &hMyFile,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync 0 /* Handle attributes*/, 0 /* Options */);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (!NT_SUCCESS(rcNt))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (rcNt == STATUS_ACCESS_DENIED)
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync OBJECT_ATTRIBUTES ObjAttr;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync InitializeObjectAttributes(&ObjAttr, &uBuf.UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync rcNt = NtCreateFile(&hMyFile,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync &ObjAttr,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync &Ios,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync NULL /* Allocation Size*/,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync FILE_ATTRIBUTE_NORMAL,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync FILE_SHARE_READ,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync FILE_OPEN,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync NULL /*EaBuffer*/,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync 0 /*EaLength*/);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (NT_SUCCESS(rcNt))
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync rcNt = Ios.Status;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (!NT_SUCCESS(rcNt))
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync {
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync supR3HardenedError(VINF_SUCCESS, false,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync "supR3HardenedScreenImage/%s: Failed to duplicate and open the file: rcNt=%#x hFile=%p %ls\n",
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync pszCaller, rcNt, hFile, uBuf.UniStr.Buffer);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync return rcNt;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync /* Check that we've got the same file. */
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync LARGE_INTEGER idMyFile, idInFile;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync bool fMyValid = supR3HardenedWinVerifyCacheGetIndexNumber(hMyFile, &idMyFile);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync bool fInValid = supR3HardenedWinVerifyCacheGetIndexNumber(hFile, &idInFile);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if ( fMyValid
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync && ( fMyValid != fInValid
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync || idMyFile.QuadPart != idInFile.QuadPart))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedError(VINF_SUCCESS, false,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "supR3HardenedScreenImage/%s: Re-opened has different ID that input: %#llx vx %#llx (%ls)\n",
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pszCaller, rcNt, idMyFile.QuadPart, idInFile.QuadPart, uBuf.UniStr.Buffer);
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync NtClose(hMyFile);
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync return STATUS_TRUST_FAILURE;
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync }
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync }
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync else
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync {
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: NtDuplicateObject -> %#x\n", pszCaller, rcNt));
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync#ifdef DEBUG
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync supR3HardenedError(VINF_SUCCESS, false,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "supR3HardenedScreenImage/%s: NtDuplicateObject(,%#x,) failed: %#x\n", pszCaller, hFile, rcNt);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync#endif
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync hMyFile = hFile;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Special Kludge for Windows XP and W2K3 and their stupid attempts
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * at mapping a hidden XML file called c:\Windows\WindowsShell.Manifest
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * with executable access. The image bit isn't set, fortunately.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if ( !fImage
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync && uBuf.UniStr.Length > g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync && memcmp(uBuf.UniStr.Buffer, g_System32NtPath.UniStr.Buffer,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) == 0)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync PRTUTF16 pwszName = &uBuf.UniStr.Buffer[(g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) / sizeof(WCHAR)];
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (RTUtf16ICmpAscii(pwszName, "WindowsShell.Manifest") == 0)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Drop all executable access to the mapping and let it continue.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync SUP_DPRINTF(("supR3HardenedScreenImage/%s: Applying the drop-exec-kludge for '%ls'\n", pszCaller, uBuf.UniStr.Buffer));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (*pfAccess & SECTION_MAP_EXECUTE)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfAccess = (*pfAccess & ~SECTION_MAP_EXECUTE) | SECTION_MAP_READ;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (*pfProtect & PAGE_EXECUTE)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfProtect = (*pfProtect & ~PAGE_EXECUTE) | PAGE_READONLY;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfProtect = (*pfProtect & ~UINT32_C(0xf0)) | ((*pfProtect & UINT32_C(0xe0)) >> 4);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (hMyFile != hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync NtClose(hMyFile);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfCallRealApi = true;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_SUCCESS;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync#ifndef VBOX_PERMIT_EVEN_MORE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Check the path. We don't allow DLLs to be loaded from just anywhere:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * 1. System32 - normal code or cat signing, owner TrustedInstaller.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * 2. WinSxS - normal code or cat signing, owner TrustedInstaller.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * 3. VirtualBox - kernel code signing and integrity checks.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * 4. AppPatchDir - normal code or cat signing, owner TrustedInstaller.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * 5. Program Files - normal code or cat signing, owner TrustedInstaller.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * 6. Common Files - normal code or cat signing, owner TrustedInstaller.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * 7. x86 variations of 4 & 5 - ditto.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync uint32_t fFlags = 0;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_System32NtPath.UniStr, true /*fCheckSlash*/))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_WinSxSNtPath.UniStr, true /*fCheckSlash*/))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_SupLibHardenedExeNtPath.UniStr.Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# ifdef VBOX_PERMIT_MORE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (supHardViIsAppPatchDir(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR)))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesNtPath.UniStr, true /*fCheckSlash*/))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesNtPath.UniStr, true /*fCheckSlash*/))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# ifdef RT_ARCH_AMD64
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesX86NtPath.UniStr, true /*fCheckSlash*/))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesX86NtPath.UniStr, true /*fCheckSlash*/))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync# endif
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync# endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /* Hack to allow profiling our code with Visual Studio. */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else if ( uBuf.UniStr.Length > sizeof(L"\\SamplingRuntime.dll")
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync && memcmp(uBuf.UniStr.Buffer + (uBuf.UniStr.Length - sizeof(L"\\SamplingRuntime.dll") + sizeof(WCHAR)) / sizeof(WCHAR),
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync L"\\SamplingRuntime.dll", sizeof(L"\\SamplingRuntime.dll") - sizeof(WCHAR)) == 0 )
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (hMyFile != hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync NtClose(hMyFile);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pfCallRealApi = true;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_SUCCESS;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync# endif
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedError(VINF_SUCCESS, false,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "supR3HardenedScreenImage/%s: Not a trusted location: '%ls' (fImage=%d fProtect=%#x fAccess=%#x)\n",
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pszCaller, uBuf.UniStr.Buffer, fImage, *pfAccess, *pfProtect);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (hMyFile != hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync NtClose(hMyFile);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_TRUST_FAILURE;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync#else /* VBOX_PERMIT_EVEN_MORE */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Require trusted installer + some kind of signature on everything, except
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * for the VBox bits where we require kernel code signing and special
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * integrity checks.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t fFlags = 0;
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync g_SupLibHardenedExeNtPath.UniStr.Buffer,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync#endif /* VBOX_PERMIT_EVEN_MORE */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Do the verification. For better error message we borrow what's
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * left of the path buffer for an RTERRINFO buffer.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync RTERRINFO ErrInfo;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync RTErrInfoInit(&ErrInfo, (char *)&uBuf.abBuffer[cbNameBuf], sizeof(uBuf) - cbNameBuf);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync int rc;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync bool fWinVerifyTrust = false;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync rc = supHardenedWinVerifyImageByHandle(hMyFile, uBuf.UniStr.Buffer, fFlags, fAvoidWinVerifyTrust, &fWinVerifyTrust, &ErrInfo);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (RT_FAILURE(rc))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedError(VINF_SUCCESS, false,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync "supR3HardenedScreenImage/%s: rc=%Rrc fImage=%d fProtect=%#x fAccess=%#x %ls: %s\n",
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pszCaller, rc, fImage, *pfAccess, *pfProtect, uBuf.UniStr.Buffer, ErrInfo.pszMsg);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (hMyFile != hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fWinVerifyTrust, fFlags);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_TRUST_FAILURE;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Insert into the cache.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (hMyFile != hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fWinVerifyTrust, fFlags);
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync
9b62e122a37f42c2bbaae1312ad198f44bebea5cvboxsync *pfCallRealApi = true;
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync return STATUS_SUCCESS;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync}
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync/**
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Preloads a file into the verify cache if possible.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * This is used to avoid known cyclic LoadLibrary issues with WinVerifyTrust.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pwszName The name of the DLL to verify.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsyncDECLHIDDEN(void) supR3HardenedWinVerifyCachePreload(PCRTUTF16 pwszName)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync{
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UNICODE_STRING UniStr;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync UniStr.Buffer = (PWCHAR)pwszName;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync UniStr.Length = (USHORT)(RTUtf16Len(pwszName) * sizeof(WCHAR));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync UniStr.MaximumLength = UniStr.Length + sizeof(WCHAR);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync OBJECT_ATTRIBUTES ObjAttr;
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync InitializeObjectAttributes(&ObjAttr, &UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync NTSTATUS rcNt = NtCreateFile(&hFile,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync &ObjAttr,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync &Ios,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync NULL /* Allocation Size*/,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync FILE_ATTRIBUTE_NORMAL,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync FILE_SHARE_READ,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync FILE_OPEN,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync NULL /*EaBuffer*/,
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync 0 /*EaLength*/);
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync if (NT_SUCCESS(rcNt))
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync rcNt = Ios.Status;
cd2274c977e1b722b535e4f601a324e8029b5e43vboxsync if (!NT_SUCCESS(rcNt))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: Error %#x opening '%ls'.\n", rcNt, pwszName));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync ULONG fAccess = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ULONG fProtect = 0;
db87bb1112c1f2827ffa192593174cf845f8f04dvboxsync bool fCallRealApi;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: scanning %ls\n", pwszName));
cf0e96b2c5a08292c6d13e4fdcb2d9518d1983e8vboxsync supR3HardenedScreenImage(hFile, false, &fAccess, &fProtect, &fCallRealApi, "preload", false /*fAvoidWinVerifyTrust*/,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync NULL /*pfQuietFailure*/);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: done %ls\n", pwszName));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NtClose(hFile);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Hook that monitors NtCreateSection calls.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @returns NT status code.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param phSection Where to return the section handle.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @param fAccess The desired access.
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @param pObjAttribs The object attributes (optional).
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pcbSection The section size (optional).
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param fProtect The max section protection.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param fAttribs The section attributes.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param hFile The file to create a section from (optional).
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsyncstatic NTSTATUS NTAPI
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsyncsupR3HardenedMonitor_NtCreateSection(PHANDLE phSection, ACCESS_MASK fAccess, POBJECT_ATTRIBUTES pObjAttribs,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync PLARGE_INTEGER pcbSection, ULONG fProtect, ULONG fAttribs, HANDLE hFile)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync{
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if ( hFile != NULL
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync && hFile != INVALID_HANDLE_VALUE)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync bool const fImage = RT_BOOL(fAttribs & (SEC_IMAGE | SEC_PROTECTED_IMAGE));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync bool const fExecMap = RT_BOOL(fAccess & SECTION_MAP_EXECUTE);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync bool const fExecProt = RT_BOOL(fProtect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_WRITECOPY
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync | PAGE_EXECUTE_READWRITE));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (fImage || fExecMap || fExecProt)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync DWORD dwSavedLastError = GetLastError();
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync bool fCallRealApi;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 1\n"));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync NTSTATUS rcNt = supR3HardenedScreenImage(hFile, fImage, &fAccess, &fProtect, &fCallRealApi,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "NtCreateSection", true /*fAvoidWinVerifyTrust*/, NULL /*pfQuietFailure*/);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 2 rcNt=%#x fCallRealApi=%#x\n", rcNt, fCallRealApi));
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync SetLastError(dwSavedLastError);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (!NT_SUCCESS(rcNt))
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return rcNt;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync Assert(fCallRealApi);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (!fCallRealApi)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_TRUST_FAILURE;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync /*
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Call checked out OK, call the original.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return g_pfnNtCreateSectionReal(phSection, fAccess, pObjAttribs, pcbSection, fProtect, fAttribs, hFile);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync/**
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Helper for supR3HardenedMonitor_LdrLoadDll.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @returns NT status code.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pwszPath The path destination buffer.
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync * @param cwcPath The size of the path buffer.
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync * @param pUniStrResult The result string.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pOrgName The orignal name (for errors).
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pcwc Where to return the actual length.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsyncstatic NTSTATUS supR3HardenedCopyRedirectionResult(WCHAR *pwszPath, size_t cwcPath, PUNICODE_STRING pUniStrResult,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync PUNICODE_STRING pOrgName, UINT *pcwc)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync{
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync UINT cwc;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *pcwc = cwc = pUniStrResult->Length / sizeof(WCHAR);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (pUniStrResult->Buffer == pwszPath)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pwszPath[cwc] = '\0';
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync else
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync if (cwc > cwcPath - 1)
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync {
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync supR3HardenedError(VINF_SUCCESS, false,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync "supR3HardenedMonitor_LdrLoadDll: Name too long: %.*ls -> %.*ls (RtlDosApplyFileIoslationRedirection_Ustr)\n",
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pOrgName->Length / sizeof(WCHAR), pOrgName->Buffer,
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pUniStrResult->Length / sizeof(WCHAR), pUniStrResult->Buffer);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_NAME_TOO_LONG;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync memcpy(&pwszPath[0], pUniStrResult->Buffer, pUniStrResult->Length);
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync pwszPath[cwc] = '\0';
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync }
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync return STATUS_SUCCESS;
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync}
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync/**
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Hooks that intercepts LdrLoadDll calls.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * Two purposes:
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * -# Enforce our own search path restrictions.
30f07af559efcbd967e801903746fc21f81ee533vboxsync * -# Prevalidate DLLs about to be loaded so we don't upset the loader data
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * by doing it from within the NtCreateSection hook (WinVerifyTrust
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * seems to be doing harm there on W7/32).
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync *
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync * @returns
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync * @param pwszSearchPath The search path to use.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * @param pfFlags Flags on input. DLL characteristics or something
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * on return?
30f07af559efcbd967e801903746fc21f81ee533vboxsync * @param pName The name of the module.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param phMod Where the handle of the loaded DLL is to be
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync * returned to the caller.
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsync */
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsyncstatic NTSTATUS NTAPI
48e06e6a052c50ecf176f63f5537f80b544bf34avboxsyncsupR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_STRING pName, PHANDLE phMod)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync DWORD dwSavedLastError = GetLastError();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync NTSTATUS rcNt;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Process WinVerifyTrust todo before and after.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinVerifyCacheProcessWvtTodos();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Reject things we don't want to deal with.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (!pName || pName->Length == 0)
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync supR3HardenedError(VINF_SUCCESS, false, "supR3HardenedMonitor_LdrLoadDll: name is NULL or have a zero length.\n");
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x (pName=%p)\n", STATUS_INVALID_PARAMETER, pName));
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SetLastError(dwSavedLastError);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync return STATUS_INVALID_PARAMETER;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync }
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync /*SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: pName=%.*ls *pfFlags=%#x pwszSearchPath=%p:%ls\n",
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer, pfFlags ? *pfFlags : UINT32_MAX, pwszSearchPath,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync !((uintptr_t)pwszSearchPath & 1) && (uintptr_t)pwszSearchPath >= 0x2000U ? pwszSearchPath : L"<flags>"));*/
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync /*
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync * Reject long paths that's close to the 260 limit without looking.
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync */
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (pName->Length > 256 * sizeof(WCHAR))
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync supR3HardenedError(VINF_SUCCESS, false, "supR3HardenedMonitor_LdrLoadDll: too long name: %#x bytes\n", pName->Length);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_NAME_TOO_LONG));
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SetLastError(dwSavedLastError);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync return STATUS_NAME_TOO_LONG;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync }
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync /*
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync * Absolute path?
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync */
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync bool fSkipValidation = false;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync WCHAR wszPath[260];
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll");
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync UNICODE_STRING UniStrStatic = { 0, (USHORT)sizeof(wszPath) - sizeof(WCHAR), wszPath };
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync UNICODE_STRING UniStrDynamic = { 0, 0, NULL };
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync PUNICODE_STRING pUniStrResult = NULL;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync UNICODE_STRING ResolvedName;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if ( ( pName->Length >= 4 * sizeof(WCHAR)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && RT_C_IS_ALPHA(pName->Buffer[0])
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pName->Buffer[1] == ':'
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && RTPATH_IS_SLASH(pName->Buffer[2]) )
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || ( pName->Length >= 1 * sizeof(WCHAR)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && RTPATH_IS_SLASH(pName->Buffer[1]) )
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync )
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = RtlDosApplyFileIsolationRedirection_Ustr(1 /*fFlags*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pName,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync (PUNICODE_STRING)&s_DefaultSuffix,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &UniStrStatic,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &UniStrDynamic,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &pUniStrResult,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pNewFlags*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pcbFilename*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync NULL /*pcbNeeded*/);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync UINT cwc;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = supR3HardenedCopyRedirectionResult(wszPath, RT_ELEMENTS(wszPath), pUniStrResult, pName, &cwc);
30f07af559efcbd967e801903746fc21f81ee533vboxsync RtlFreeUnicodeString(&UniStrDynamic);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (!NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", rcNt));
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SetLastError(dwSavedLastError);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync return rcNt;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ResolvedName.Buffer = wszPath;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ResolvedName.Length = (USHORT)(cwc * sizeof(WCHAR));
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ResolvedName.MaximumLength = ResolvedName.Length + sizeof(WCHAR);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: '%.*ls' -> '%.*ls' [redir]\n",
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer,
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync ResolvedName.Length / sizeof(WCHAR), ResolvedName.Buffer, rcNt));
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync pName = &ResolvedName;
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync }
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(wszPath, pName->Buffer, pName->Length);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync wszPath[pName->Length / sizeof(WCHAR)] = '\0';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync * Not an absolute path. Check if it's one of those special API set DLLs
30f07af559efcbd967e801903746fc21f81ee533vboxsync * or something we're known to use but should be taken from WinSxS.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else if (supHardViUtf16PathStartsWithEx(pName->Buffer, pName->Length / sizeof(WCHAR),
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync L"api-ms-win-", 11, false /*fCheckSlash*/))
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync memcpy(wszPath, pName->Buffer, pName->Length);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync wszPath[pName->Length / sizeof(WCHAR)] = '\0';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync fSkipValidation = true;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Not an absolute path or special API set. There are two alternatives
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * now, either there is no path at all or there is a relative path. We
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * will resolve it to an absolute path in either case, failing the call
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync * if we can't.
30f07af559efcbd967e801903746fc21f81ee533vboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync PCWCHAR pawcName = pName->Buffer;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cwcName = pName->Length / sizeof(WCHAR);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t offLastSlash = UINT32_MAX;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t offLastDot = UINT32_MAX;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (uint32_t i = 0; i < cwcName; i++)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync switch (pawcName[i])
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync case '\\':
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync case '/':
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync offLastSlash = i;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offLastDot = UINT32_MAX;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync break;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync case '.':
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offLastDot = i;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync break;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync bool const fNeedDllSuffix = offLastDot == UINT32_MAX && offLastSlash == UINT32_MAX;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (offLastDot != UINT32_MAX && offLastDot == cwcName - 1)
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync cwcName--;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync /*
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync * Reject relative paths for now as they might be breakout attempts.
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync */
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (offLastSlash != UINT32_MAX)
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync supR3HardenedError(VINF_SUCCESS, false,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync "supR3HardenedMonitor_LdrLoadDll: relative name not permitted: %.*ls\n",
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync cwcName, pawcName);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_OBJECT_NAME_INVALID));
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync SetLastError(dwSavedLastError);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync return STATUS_OBJECT_NAME_INVALID;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync }
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync /*
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync * Perform dll redirection to WinSxS such. We using an undocumented
30f07af559efcbd967e801903746fc21f81ee533vboxsync * API here, which as always is a bit risky... ASSUMES that the API
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync * returns a full DOS path.
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync */
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync UINT cwc;
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync rcNt = RtlDosApplyFileIsolationRedirection_Ustr(1 /*fFlags*/,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync pName,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync (PUNICODE_STRING)&s_DefaultSuffix,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync &UniStrStatic,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync &UniStrDynamic,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync &pUniStrResult,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync NULL /*pNewFlags*/,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync NULL /*pcbFilename*/,
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync NULL /*pcbNeeded*/);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (NT_SUCCESS(rcNt))
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync rcNt = supR3HardenedCopyRedirectionResult(wszPath, RT_ELEMENTS(wszPath), pUniStrResult, pName, &cwc);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync RtlFreeUnicodeString(&UniStrDynamic);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (!NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", rcNt));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SetLastError(dwSavedLastError);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync return rcNt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Search for the DLL. Only System32 is allowed as the target of
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * a search on the API level, all VBox calls will have full paths.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync cwc = GetSystemDirectoryW(wszPath, RT_ELEMENTS(wszPath) - 32);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!cwc)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedError(VINF_SUCCESS, false,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync "supR3HardenedMonitor_LdrLoadDll: GetSystemDirectoryW failed: %u\n", GetLastError());
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_UNEXPECTED_IO_ERROR));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SetLastError(dwSavedLastError);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return STATUS_UNEXPECTED_IO_ERROR;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (cwc + 1 + cwcName + fNeedDllSuffix * 4 >= RT_ELEMENTS(wszPath))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedError(VINF_SUCCESS, false,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync "supR3HardenedMonitor_LdrLoadDll: Name too long (system32): %.*ls\n", cwcName, pawcName);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_NAME_TOO_LONG));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SetLastError(dwSavedLastError);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return STATUS_NAME_TOO_LONG;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync wszPath[cwc++] = '\\';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(&wszPath[cwc], pawcName, cwcName * sizeof(WCHAR));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync cwc += cwcName;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!fNeedDllSuffix)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync wszPath[cwc] = '\0';
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(&wszPath[cwc], L".dll", 5 * sizeof(WCHAR));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync cwc += 4;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ResolvedName.Buffer = wszPath;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ResolvedName.Length = (USHORT)(cwc * sizeof(WCHAR));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ResolvedName.MaximumLength = ResolvedName.Length + sizeof(WCHAR);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: '%.*ls' -> '%.*ls' [rcNt=%#x]\n",
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ResolvedName.Length / sizeof(WCHAR), ResolvedName.Buffer, rcNt));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pName = &ResolvedName;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync
30f07af559efcbd967e801903746fc21f81ee533vboxsync if (!fSkipValidation)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Try open the file. If this fails, never mind, just pass it on to
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * the real API as we've replaced any searchable name with a full name
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * and the real API can come up with a fitting status code for it.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync HANDLE hFile = CreateFileW(wszPath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecurityAttributes*/,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL /*hTemplateFile*/);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync if (hFile != INVALID_HANDLE_VALUE)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync ULONG fAccess = 0;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync ULONG fProtect = 0;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync bool fCallRealApi = false;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync bool fQuietFailure = false;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync "LdrLoadDll", false /*fAvoidWinVerifyTrust*/, &fQuietFailure);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync NtClose(hFile);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (!NT_SUCCESS(rcNt))
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!fQuietFailure)
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync {
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync supR3HardenedError(VINF_SUCCESS, false, "supR3HardenedMonitor_LdrLoadDll: rejecting '%ls': rcNt=%#x\n",
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync wszPath, rcNt);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x '%ls'\n", rcNt, wszPath));
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync }
30f07af559efcbd967e801903746fc21f81ee533vboxsync SetLastError(dwSavedLastError);
28a2653de6f80a4b1f000cfc52e1a04492d4c151vboxsync return rcNt;
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedWinVerifyCacheProcessImportTodos();
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync else
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync {
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync DWORD dwErr = GetLastError();
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: error opening '%ls': %u\n", wszPath, dwErr));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync /*
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * Screened successfully enough. Call the real thing.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: pName=%.*ls *pfFlags=%#x pwszSearchPath=%p:%ls [calling]\n",
30f07af559efcbd967e801903746fc21f81ee533vboxsync (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer, pfFlags ? *pfFlags : UINT32_MAX, pwszSearchPath,
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync !((uintptr_t)pwszSearchPath & 1) && (uintptr_t)pwszSearchPath >= 0x2000U ? pwszSearchPath : L"<flags>"));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SetLastError(dwSavedLastError);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync rcNt = g_pfnLdrLoadDllReal(pwszSearchPath, pfFlags, pName, phMod);
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync /*
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync * Log the result and process pending WinVerifyTrust work if we can.
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync */
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync dwSavedLastError = GetLastError();
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync if (NT_SUCCESS(rcNt) && phMod)
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x hMod=%p '%ls'\n", rcNt, *phMod, wszPath));
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync else
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x '%ls'\n", rcNt, wszPath));
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedWinVerifyCacheProcessWvtTodos();
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SetLastError(dwSavedLastError);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return rcNt;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync}
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
817577d2c4d6dee709de7a92d3bb7d0aeedae9aevboxsync#ifdef RT_ARCH_AMD64
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync/**
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Tries to allocate memory between @a uStart and @a uEnd.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @returns Pointer to the memory on success. NULL on failure.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param uStart The start address.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param uEnd The end address. This is lower than @a uStart
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * if @a iDirection is negative, and higher if
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * positive.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param iDirection The search direction.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * @param cbAlloc The number of bytes to allocate.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsyncstatic void *supR3HardenedWinAllocHookMemory(uintptr_t uStart, uintptr_t uEnd, intptr_t iDirection, size_t cbAlloc)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync{
9f997e760f610c92e3a365be21ead6972bc46130vboxsync size_t const cbAllocGranularity = _64K;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync size_t const uAllocGranularityMask = ~(cbAllocGranularity - 1);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync HANDLE const hProc = NtCurrentProcess();
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /*
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Make uEnd the last valid return address.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (iDirection > 0)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SUPR3HARDENED_ASSERT(uEnd > cbAlloc);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uEnd -= cbAlloc;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uEnd &= uAllocGranularityMask;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync else
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uEnd = RT_ALIGN_Z(uEnd, cbAllocGranularity);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /*
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Search for free memory.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uintptr_t uCur = uStart & uAllocGranularityMask;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync for (;;)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /*
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Examine the memory at this address, if it's free, try make the allocation here.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SIZE_T cbIgn;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync MEMORY_BASIC_INFORMATION MemInfo;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtQueryVirtualMemory(hProc,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync (void *)uCur,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync MemoryBasicInformation,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync &MemInfo,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync sizeof(MemInfo),
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync &cbIgn));
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if ( MemInfo.State == MEM_FREE
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync && MemInfo.RegionSize >= cbAlloc)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync for (;;)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync SUPR3HARDENED_ASSERT((uintptr_t)MemInfo.BaseAddress <= uCur);
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync PVOID pvMem = (PVOID)uCur;
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync SIZE_T cbMem = cbAlloc;
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync NTSTATUS rcNt = NtAllocateVirtualMemory(hProc, &pvMem, 0 /*ZeroBits*/, &cbAlloc,
eb259de2a9eac4b4dda56e89f5004671f926bd9bvboxsync MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
30f07af559efcbd967e801903746fc21f81ee533vboxsync if (NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( iDirection > 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ? (uintptr_t)pvMem >= uStart
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && (uintptr_t)pvMem <= uEnd
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync : (uintptr_t)pvMem >= uEnd
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && (uintptr_t)pvMem <= uStart)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync return pvMem;
30f07af559efcbd967e801903746fc21f81ee533vboxsync NtFreeVirtualMemory(hProc, &pvMem, &cbMem, MEM_RELEASE);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Advance within the free area and try again? */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uintptr_t uNext = iDirection > 0 ? uCur + cbAllocGranularity : uCur - cbAllocGranularity;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uNext &= uAllocGranularityMask;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( iDirection > 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ? uNext <= uCur
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || uNext > uEnd
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || uNext - (uintptr_t)MemInfo.BaseAddress > MemInfo.RegionSize
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync || MemInfo.RegionSize - (uNext - (uintptr_t)MemInfo.BaseAddress) < cbAlloc
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync : uNext >= uCur
680c2aff33be2ee9340c8763a3cb5c218c352bcfvboxsync || uNext < uEnd
30f07af559efcbd967e801903746fc21f81ee533vboxsync || uNext < (uintptr_t)MemInfo.BaseAddress)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync break;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uCur = uNext;
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync }
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync }
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync
30f07af559efcbd967e801903746fc21f81ee533vboxsync /*
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync * Advance to the next memory region.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (iDirection > 0)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uCur = (uintptr_t)MemInfo.BaseAddress + MemInfo.RegionSize;
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync uCur = RT_ALIGN_Z(uCur, cbAllocGranularity);
93e05ea894cefd56ca308d72372b4dd8045bd1eevboxsync if (uCur >= uEnd)
90624af27b0e648b68167bd3b332d0e3b1d18ab1vboxsync break;
30f07af559efcbd967e801903746fc21f81ee533vboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uCur = (uintptr_t)(MemInfo.AllocationBase ? MemInfo.AllocationBase : MemInfo.BaseAddress);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (uCur > uEnd)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uCur -= cbAlloc;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync uCur &= uAllocGranularityMask;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (uCur < uEnd)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync break;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync return NULL;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync}
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#endif
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncstatic void supR3HardenedWinHookFailed(const char *pszWhich, uint8_t const *pbPrologue)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync{
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_NO_MEMORY,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync "Failed to install %s monitor: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n "
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#ifdef RT_ARCH_X86
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync "(It is also possible you are running 32-bit VirtualBox under 64-bit windows.)\n"
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#endif
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pszWhich,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pbPrologue[0], pbPrologue[1], pbPrologue[2], pbPrologue[3],
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pbPrologue[4], pbPrologue[5], pbPrologue[6], pbPrologue[7],
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pbPrologue[8], pbPrologue[9], pbPrologue[10], pbPrologue[11],
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pbPrologue[12], pbPrologue[13], pbPrologue[14], pbPrologue[15]);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync}
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync/**
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * IPRT thread that waits for the parent process to terminate and reacts by
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * exiting the current process.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @returns VINF_SUCCESS
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @param hSelf The current thread. Ignored.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @param pvUser The handle of the parent process.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncstatic DECLCALLBACK(int) supR3HardenedWinParentWatcherThread(RTTHREAD hSelf, void *pvUser)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync{
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync HANDLE hProcWait = (HANDLE)pvUser;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NOREF(hSelf);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Wait for the parent to terminate.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NTSTATUS rcNt;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync for (;;)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync rcNt = NtWaitForSingleObject(hProcWait, TRUE /*Alertable*/, NULL /*pTimeout*/);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if ( rcNt == STATUS_WAIT_0
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync || rcNt == STATUS_ABANDONED_WAIT_0)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync break;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if ( rcNt != STATUS_TIMEOUT
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && rcNt != STATUS_USER_APC
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && rcNt != STATUS_ALERTED)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedFatal("NtWaitForSingleObject returned %#x\n", rcNt);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Proxy the termination code of the child, if it exited already.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync PROCESS_BASIC_INFORMATION BasicInfo;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NTSTATUS rcNt2 = NtQueryInformationProcess(hProcWait, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if ( !NT_SUCCESS(rcNt2)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync || BasicInfo.ExitStatus == STATUS_PENDING)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync BasicInfo.ExitStatus = RTEXITCODE_FAILURE;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NtClose(hProcWait);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUP_DPRINTF(("supR3HardenedWinParentWatcherThread: Quitting: ExitCode=%#x rcNt=%#x\n", BasicInfo.ExitStatus, rcNt));
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync suplibHardenedExit((RTEXITCODE)BasicInfo.ExitStatus);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync return VINF_SUCCESS; /* won't be reached. */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync}
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync/**
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Creates the parent watcher thread that will make sure this process exits when
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * the parent does.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * This is a necessary evil to make VBoxNetDhcp and VBoxNetNat termination from
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Main work without too much new magic. It also makes Ctrl-C or similar work
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * in on the hardened processes in the windows console.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @param hVBoxRT The VBoxRT.dll handle. We use RTThreadCreate to
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * spawn the thread to avoid duplicating thread
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * creation and thread naming code from IPRT.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncDECLHIDDEN(void) supR3HardenedWinCreateParentWatcherThread(HMODULE hVBoxRT)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync{
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Resolve runtime methods that we need.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync PFNRTTHREADCREATE pfnRTThreadCreate = (PFNRTTHREADCREATE)GetProcAddress(hVBoxRT, "RTThreadCreate");
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUPR3HARDENED_ASSERT(pfnRTThreadCreate != NULL);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Find the parent process ID.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync PROCESS_BASIC_INFORMATION BasicInfo;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NTSTATUS rcNt = NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (!NT_SUCCESS(rcNt))
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedFatal("supR3HardenedWinCreateParentWatcherThread: NtQueryInformationProcess failed: %#x\n", rcNt);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Open the parent process for waiting and exitcode query.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync OBJECT_ATTRIBUTES ObjAttr;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync InitializeObjectAttributes(&ObjAttr, NULL, 0, NULL /*hRootDir*/, NULL /*pSecDesc*/);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync CLIENT_ID ClientId;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ClientId.UniqueProcess = (HANDLE)BasicInfo.InheritedFromUniqueProcessId;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ClientId.UniqueThread = NULL;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync HANDLE hParent;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync rcNt = NtOpenProcess(&hParent, SYNCHRONIZE | PROCESS_QUERY_INFORMATION, &ObjAttr, &ClientId);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (!NT_SUCCESS(rcNt))
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedFatalMsg("supR3HardenedWinCreateParentWatcherThread", kSupInitOp_Misc, VERR_GENERAL_FAILURE,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync "NtOpenProcess(%p.0) failed: %#x\n", ClientId.UniqueProcess, rcNt);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Create the thread that should do the waiting.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync int rc = pfnRTThreadCreate(NULL, supR3HardenedWinParentWatcherThread, hParent, _64K /* stack */,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync RTTHREADTYPE_DEFAULT, 0 /*fFlags*/, "ParentWatcher");
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (RT_FAILURE(rc))
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedFatal("supR3HardenedWinCreateParentWatcherThread: RTThreadCreate failed: %Rrc\n", rc);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync}
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync/**
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Install hooks for intercepting calls dealing with mapping shared libraries
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * into the process.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * This allows us to prevent undesirable shared libraries from being loaded.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @remarks We assume we're alone in this process, so no seralizing trickery is
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * necessary when installing the patch.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * @remarks We would normally just copy the prologue sequence somewhere and add
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * a jump back at the end of it. But because we wish to avoid
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * allocating executable memory, we need to have preprepared assembly
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * "copies". This makes the non-system call patching a little tedious
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * and inflexible.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsyncDECLHIDDEN(void) supR3HardenedWinInstallHooks(void)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync{
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync NTSTATUS rcNt;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#ifndef VBOX_WITHOUT_DEBUGGER_CHECKS
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Install a anti debugging hack before we continue. This prevents most
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * notifications from ending up in the debugger. (Also applied to the
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * child process when respawning.)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = NtSetInformationThread(NtCurrentThread(), ThreadHideFromDebugger, NULL, 0);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_GENERAL_FAILURE,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync "NtSetInformationThread/ThreadHideFromDebugger failed: %#x\n", rcNt);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync#endif
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Disable hard error popups so we can quietly refuse images to be loaded.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ULONG fHardErr = 0;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync rcNt = NtQueryInformationProcess(NtCurrentProcess(), ProcessDefaultHardErrorMode, &fHardErr, sizeof(fHardErr), NULL);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if (!NT_SUCCESS(rcNt))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_GENERAL_FAILURE,
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync "NtQueryInformationProcess/ProcessDefaultHardErrorMode failed: %#x\n", rcNt);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if (fHardErr & PROCESS_HARDERR_CRITICAL_ERROR)
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync {
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync fHardErr &= ~PROCESS_HARDERR_CRITICAL_ERROR;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync rcNt = NtSetInformationProcess(NtCurrentProcess(), ProcessDefaultHardErrorMode, &fHardErr, sizeof(fHardErr));
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if (!NT_SUCCESS(rcNt))
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_GENERAL_FAILURE,
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync "NtSetInformationProcess/ProcessDefaultHardErrorMode failed: %#x\n", rcNt);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync }
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /*
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * Locate the routines first so we can allocate memory that's near enough.
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync PFNRT pfnNtCreateSection = supR3HardenedWinGetRealDllSymbol("ntdll.dll", "NtCreateSection");
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync SUPR3HARDENED_ASSERT(pfnNtCreateSection != NULL);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync //SUPR3HARDENED_ASSERT(pfnNtCreateSection == (FARPROC)NtCreateSection);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync PFNRT pfnLdrLoadDll = supR3HardenedWinGetRealDllSymbol("ntdll.dll", "LdrLoadDll");
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync SUPR3HARDENED_ASSERT(pfnLdrLoadDll != NULL);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync //SUPR3HARDENED_ASSERT(pfnLdrLoadDll == (FARPROC)LdrLoadDll);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync#ifdef RT_ARCH_AMD64
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /*
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * For 64-bit hosts we need some memory within a +/-2GB range of the
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * actual function to be able to patch it.
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync uintptr_t uStart = RT_MAX((uintptr_t)pfnNtCreateSection, (uintptr_t)pfnLdrLoadDll);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync size_t cbMem = _4K;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync void *pvMem = supR3HardenedWinAllocHookMemory(uStart, uStart - _2G + PAGE_SIZE, -1, cbMem);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if (!pvMem)
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync {
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync uintptr_t uStart = RT_MIN((uintptr_t)pfnNtCreateSection, (uintptr_t)pfnLdrLoadDll);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync pvMem = supR3HardenedWinAllocHookMemory(uStart, uStart + _2G - PAGE_SIZE, 1, cbMem);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if (!pvMem)
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_NO_MEMORY,
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync "Failed to allocate memory within the +/-2GB range from NTDLL.\n");
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync }
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync uintptr_t *puJmpTab = (uintptr_t *)pvMem;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync#endif
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /*
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * Hook #1 - NtCreateSection.
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * Purpose: Validate everything that can be mapped into the process before
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * it's mapped and we still have a file handle to work with.
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync uint8_t * const pbNtCreateSection = (uint8_t *)(uintptr_t)pfnNtCreateSection;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync#ifdef RT_ARCH_AMD64
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /*
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync * Patch 64-bit hosts.
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync PFNRT pfnCallReal = NULL;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync uint8_t offJmpBack = UINT8_MAX;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync /* Pattern #1: XP64/W2K3-64 thru Windows 8.1
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 0:000> u ntdll!NtCreateSection
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync ntdll!NtCreateSection:
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 00000000`779f1750 4c8bd1 mov r10,rcx
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 00000000`779f1753 b847000000 mov eax,47h
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 00000000`779f1758 0f05 syscall
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 00000000`779f175a c3 ret
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync 00000000`779f175b 0f1f440000 nop dword ptr [rax+rax]
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync The variant is the value loaded into eax: W2K3=??, Vista=47h?, W7=47h, W80=48h, W81=49h */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if ( pbNtCreateSection[ 0] == 0x4c /* mov r10, rcx */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 1] == 0x8b
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 2] == 0xd1
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 3] == 0xb8 /* mov eax, 000000xxh */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 5] == 0x00
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 6] == 0x00
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 7] == 0x00
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 8] == 0x0f /* syscall */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[ 9] == 0x05
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync && pbNtCreateSection[10] == 0xc3 /* ret */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync/* b8 22 35 ed 0 48 63 c0 ff e0 c3 f 1f 44 0 0 - necros2 - agnitum firewall? */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync )
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync {
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync offJmpBack = 8; /* the 3rd instruction (syscall). */
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync switch (pbNtCreateSection[4])
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync {
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync# define SYSCALL(a_Num) case a_Num: pfnCallReal = RT_CONCAT(supR3HardenedJmpBack_NtCreateSection_,a_Num); break;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync# include "NtCreateSection-template-amd64-syscall-type-1.h"
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync# undef SYSCALL
0d73750f953d8569054777eab62f40ad88a66d88vboxsync }
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync }
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync if (!pfnCallReal)
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync supR3HardenedWinHookFailed("NtCreateSection", pbNtCreateSection);
0d73750f953d8569054777eab62f40ad88a66d88vboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync g_pfnNtCreateSectionJmpBack = (PFNRT)(uintptr_t)(pbNtCreateSection + offJmpBack);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync *(PFNRT *)&g_pfnNtCreateSectionReal = pfnCallReal;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync *puJmpTab = (uintptr_t)supR3HardenedMonitor_NtCreateSection;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync DWORD dwOldProt;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync PAGE_EXECUTE_READWRITE, &dwOldProt));
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync pbNtCreateSection[0] = 0xff;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync pbNtCreateSection[1] = 0x25;
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync *(uint32_t *)&pbNtCreateSection[2] = (uint32_t)((uintptr_t)puJmpTab - (uintptr_t)&pbNtCreateSection[2+4]);
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync
2fce40121ae472df2fd959fbe19775ed43304a0bvboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync PAGE_EXECUTE_READ, &dwOldProt));
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync puJmpTab++;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync#else
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync /*
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync * Patch 32-bit hosts.
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync */
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync PFNRT pfnCallReal = NULL;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync uint8_t offJmpBack = UINT8_MAX;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync /* Pattern #1: XP thru Windows 7
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync kd> u ntdll!NtCreateSection
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync ntdll!NtCreateSection:
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync 7c90d160 b832000000 mov eax,32h
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync 7c90d165 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
30f07af559efcbd967e801903746fc21f81ee533vboxsync 7c90d16a ff12 call dword ptr [edx]
30f07af559efcbd967e801903746fc21f81ee533vboxsync 7c90d16c c21c00 ret 1Ch
30f07af559efcbd967e801903746fc21f81ee533vboxsync 7c90d16f 90 nop
30f07af559efcbd967e801903746fc21f81ee533vboxsync The variable bit is the value loaded into eax: XP=32h, W2K3=34h, Vista=4bh, W7=54h
30f07af559efcbd967e801903746fc21f81ee533vboxsync
30f07af559efcbd967e801903746fc21f81ee533vboxsync Pattern #2: Windows 8.1
30f07af559efcbd967e801903746fc21f81ee533vboxsync 0:000:x86> u ntdll_6a0f0000!NtCreateSection
30f07af559efcbd967e801903746fc21f81ee533vboxsync ntdll_6a0f0000!NtCreateSection:
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eabc b854010000 mov eax,154h
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eac1 e803000000 call ntdll_6a0f0000!NtCreateSection+0xd (6a15eac9)
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eac6 c21c00 ret 1Ch
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eac9 8bd4 mov edx,esp
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eacb 0f34 sysenter
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6a15eacd c3 ret
30f07af559efcbd967e801903746fc21f81ee533vboxsync The variable bit is the value loaded into eax: W81=154h
30f07af559efcbd967e801903746fc21f81ee533vboxsync Note! One nice thing here is that we can share code pattern #1. */
30f07af559efcbd967e801903746fc21f81ee533vboxsync
30f07af559efcbd967e801903746fc21f81ee533vboxsync if ( pbNtCreateSection[ 0] == 0xb8 /* mov eax, 000000xxh*/
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 2] <= 0x02
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 3] == 0x00
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 4] == 0x00
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && ( ( pbNtCreateSection[ 5] == 0xba /* mov edx, offset SharedUserData!SystemCallStub */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 6] == 0x00
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 7] == 0x03
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 8] == 0xfe
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[ 9] == 0x7f
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[10] == 0xff /* call [edx] */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[11] == 0x12
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[12] == 0xc2 /* ret 1ch */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[13] == 0x1c
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[14] == 0x00)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync || ( pbNtCreateSection[ 5] == 0xe8 /* call [$+3] */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && RT_ABS(*(int32_t *)&pbNtCreateSection[6]) < 0x10
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[10] == 0xc2 /* ret 1ch */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[11] == 0x1c
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbNtCreateSection[12] == 0x00 )
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync )
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync )
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync offJmpBack = 5; /* the 2nd instruction. */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync switch (*(uint32_t const *)&pbNtCreateSection[1])
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync# define SYSCALL(a_Num) case a_Num: pfnCallReal = RT_CONCAT(supR3HardenedJmpBack_NtCreateSection_,a_Num); break;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync# include "NtCreateSection-template-x86-syscall-type-1.h"
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync# undef SYSCALL
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync }
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (!pfnCallReal)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync supR3HardenedWinHookFailed("NtCreateSection", pbNtCreateSection);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync g_pfnNtCreateSectionJmpBack = (PFNRT)(uintptr_t)(pbNtCreateSection + offJmpBack);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *(PFNRT *)&g_pfnNtCreateSectionReal = pfnCallReal;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync DWORD dwOldProt;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync PAGE_EXECUTE_READWRITE, &dwOldProt));
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync pbNtCreateSection[0] = 0xe9;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *(uint32_t *)&pbNtCreateSection[1] = (uintptr_t)supR3HardenedMonitor_NtCreateSection
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync - (uintptr_t)&pbNtCreateSection[1+4];
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync PAGE_EXECUTE_READ, &dwOldProt));
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#endif
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Hook #2 - LdrLoadDll
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Purpose: (a) Enforce LdrLoadDll search path constraints, and (b) pre-validate
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * DLLs so we can avoid calling WinVerifyTrust from the first hook,
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * and thus avoiding messing up the loader data on some installations.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * This differs from the above function in that is no a system call and
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * we're at the mercy of the compiler.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync uint8_t * const pbLdrLoadDll = (uint8_t *)(uintptr_t)pfnLdrLoadDll;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync uint32_t offExecPage = 0;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync memset(g_abSupHardReadWriteExecPage, 0xcc, PAGE_SIZE);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync#ifdef RT_ARCH_AMD64
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /*
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync * Patch 64-bit hosts.
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync# if 0
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /* Pattern #1:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync Windows 8.1:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 0:000> u ntdll!LdrLoadDll
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync ntdll!LdrLoadDll:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd44 488bc4 mov rax,rsp
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd47 48895808 mov qword ptr [rax+8],rbx
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd4b 48896810 mov qword ptr [rax+10h],rbp
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd4f 48897018 mov qword ptr [rax+18h],rsi
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd53 48897820 mov qword ptr [rax+20h],rdi
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd57 4156 push r14
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00007ffa`814ccd59 4883ec70 sub rsp,70h
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00007ffa`814ccd5d f6059cd2100009 test byte ptr [ntdll!LdrpDebugFlags (00007ffa`815da000)],9
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pbLdrLoadDll[0] == 0x48 /* mov rax,rsp */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[1] == 0x8b
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[2] == 0xc4
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[3] == 0x48 /* mov qword ptr [rax+8],rbx */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[4] == 0x89
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[5] == 0x58
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[6] == 0x08)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offJmpBack = 7; /* the 3rd instruction. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type1;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Pattern #2:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync Windows 8.0:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 0:000> u ntdll_w8_64!LdrLoadDll
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync ntdll_w8_64!LdrLoadDll:
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7c0 48895c2408 mov qword ptr [rsp+8],rbx
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7c5 4889742410 mov qword ptr [rsp+10h],rsi
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7ca 48897c2418 mov qword ptr [rsp+18h],rdi
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7cf 55 push rbp
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7d0 4156 push r14
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7d2 4157 push r15
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7d4 488bec mov rbp,rsp
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7d7 4883ec60 sub rsp,60h
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7db 8b05df321000 mov eax,dword ptr [ntdll_w8_64!LdrpDebugFlags (00007ffa`530fdac0)]
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync 00007ffa`52ffa7e1 4d8bf1 mov r14,r9
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync */
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync else if ( pbLdrLoadDll[0] == 0x48 /* mov qword ptr [rsp+8],rbx */
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync && pbLdrLoadDll[1] == 0x89
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync && pbLdrLoadDll[2] == 0x5c
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync && pbLdrLoadDll[3] == 0x24
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync && pbLdrLoadDll[4] == 0x08
751a35d04fb11f94562583ad77bc0a1382957f49vboxsync && pbLdrLoadDll[5] == 0x48 /* mov qword ptr [rsp+10h],rsi */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[6] == 0x89
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[7] == 0x74
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[8] == 0x24
a6c871653045073d6ef74d0589de345ae62b607dvboxsync && pbLdrLoadDll[9] == 0x10)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offJmpBack = 10; /* the 3rd instruction. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type2;
a6c871653045073d6ef74d0589de345ae62b607dvboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync Pattern #3:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Windows 7:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ntdll_w7_64!LdrLoadDll:
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58be4a20 48895c2410 mov qword ptr [rsp+10h],rbx
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58be4a25 48896c2418 mov qword ptr [rsp+18h],rbp
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58be4a2a 56 push rsi
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58be4a2b 57 push rdi
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 00000000`58be4a2c 4154 push r12
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 00000000`58be4a2e 4883ec50 sub rsp,50h
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 00000000`58be4a32 f605976e100009 test byte ptr [ntdll_w7_64!ShowSnaps (00000000`58ceb8d0)],9
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 00000000`58be4a39 498bf1 mov rsi,r9
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else if ( pbLdrLoadDll[0] == 0x48 /* mov qword ptr [rsp+10h],rbx */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbLdrLoadDll[1] == 0x89
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbLdrLoadDll[2] == 0x5c
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync && pbLdrLoadDll[3] == 0x24
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync && pbLdrLoadDll[4] == 0x10)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offJmpBack = 5; /* the 2nd instruction. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type3;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Pattern #4:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Windows Vista:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 0:000> u ntdll_vista_64!LdrLoadDll
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ntdll_vista_64!LdrLoadDll:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58c11f60 fff3 push rbx
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58c11f62 56 push rsi
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58c11f63 57 push rdi
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58c11f64 4154 push r12
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`58c11f66 4155 push r13
30f07af559efcbd967e801903746fc21f81ee533vboxsync 00000000`58c11f68 4156 push r14
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00000000`58c11f6a 4157 push r15
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58c11f6c 4881ecb0020000 sub rsp,2B0h
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58c11f73 488b05367b0e00 mov rax,qword ptr [ntdll_vista_64!_security_cookie (00000000`58cf9ab0)]
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58c11f7a 4833c4 xor rax,rsp
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`58c11f7d 48898424a0020000 mov qword ptr [rsp+2A0h],rax
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if ( pbLdrLoadDll[0] == 0xff /* push rbx */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[1] == 0xf3
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[2] == 0x56 /* push rsi */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[3] == 0x57 /* push rdi */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[4] == 0x41 /* push r12 */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[5] == 0x54)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync offJmpBack = 6; /* the 5th instruction. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type4;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Pattern #5:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Windows XP64:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 0:000> u ntdll!LdrLoadDll
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ntdll!LdrLoadDll:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa580 4c8bdc mov r11,rsp
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa583 4881ece8020000 sub rsp,2E8h
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa58a 49895bf8 mov qword ptr [r11-8],rbx
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa58e 498973f0 mov qword ptr [r11-10h],rsi
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa592 49897be8 mov qword ptr [r11-18h],rdi
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa596 4d8963e0 mov qword ptr [r11-20h],r12
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa59a 4d896bd8 mov qword ptr [r11-28h],r13
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa59e 4d8973d0 mov qword ptr [r11-30h],r14
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`78efa5a2 4d897bc8 mov qword ptr [r11-38h],r15
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 00000000`78efa5a6 488b051bd10a00 mov rax,qword ptr [ntdll!_security_cookie (00000000`78fa76c8)]
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00000000`78efa5ad 48898424a0020000 mov qword ptr [rsp+2A0h],rax
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`78efa5b5 4d8bf9 mov r15,r9
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00000000`78efa5b8 4c8bf2 mov r14,rdx
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 00000000`78efa5bb 4c8be9 mov r13,rcx
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 00000000`78efa5be 4c89442458 mov qword ptr [rsp+58h],r8
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync 00000000`78efa5c3 66c74424680000 mov word ptr [rsp+68h],0
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync else if ( pbLdrLoadDll[0] == 0x4c /* mov r11,rsp */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[1] == 0x8b
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[2] == 0xdc
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[3] == 0x48 /* sub rsp,2e8h */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[4] == 0x81
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[5] == 0xec
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[6] == 0xe8
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[7] == 0x02
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync && pbLdrLoadDll[8] == 0x00
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync && pbLdrLoadDll[9] == 0x00)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offJmpBack = 10; /* the 3rd instruction. */
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type5;
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync }
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync else
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync supR3HardenedWinHookFailed("LdrLoadDll", pbLdrLoadDll);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync# else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Just use the disassembler to skip 6 bytes or more. */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync DISSTATE Dis;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync uint32_t cbInstr;
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync offJmpBack = 0;
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync while (offJmpBack < 6)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync {
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync cbInstr = 1;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync int rc = DISInstr(pbLdrLoadDll + offJmpBack, DISCPUMODE_64BIT, &Dis, &cbInstr);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync if ( RT_FAILURE(rc)
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || (Dis.pCurInstr->fOpType & (DISOPTYPE_CONTROLFLOW))
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync || (Dis.ModRM.Bits.Mod == 0 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */) )
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync supR3HardenedWinHookFailed("LdrLoadDll", pbLdrLoadDll);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offJmpBack += cbInstr;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync }
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync# endif
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Assemble the code for resuming the call.*/
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *(PFNRT *)&g_pfnLdrLoadDllReal = (PFNRT)(uintptr_t)&g_abSupHardReadWriteExecPage[offExecPage];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync memcpy(&g_abSupHardReadWriteExecPage[offExecPage], pbLdrLoadDll, offJmpBack);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offExecPage += offJmpBack;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_abSupHardReadWriteExecPage[offExecPage++] = 0xff; /* jmp qword [$+8 wrt RIP] */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync g_abSupHardReadWriteExecPage[offExecPage++] = 0x25;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *(uint32_t *)&g_abSupHardReadWriteExecPage[offExecPage] = RT_ALIGN_32(offExecPage + 4, 8) - (offExecPage + 4);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offExecPage = RT_ALIGN_32(offExecPage + 4, 8);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *(uint64_t *)&g_abSupHardReadWriteExecPage[offExecPage] = (uintptr_t)&pbLdrLoadDll[offJmpBack];
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync offExecPage = RT_ALIGN_32(offJmpBack + 8, 16);
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync /* Patch the function. */
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync *puJmpTab = (uintptr_t)supR3HardenedMonitor_LdrLoadDll;
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbLdrLoadDll, 16, PAGE_EXECUTE_READWRITE, &dwOldProt));
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync Assert(offJmpBack >= 6);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pbLdrLoadDll[0] = 0xff;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync pbLdrLoadDll[1] = 0x25;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync *(uint32_t *)&pbLdrLoadDll[2] = (uint32_t)((uintptr_t)puJmpTab - (uintptr_t)&pbLdrLoadDll[2+4]);
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbLdrLoadDll, 16, PAGE_EXECUTE_READ, &dwOldProt));
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync puJmpTab++;
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync#else
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /*
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync * Patch 32-bit hosts.
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync */
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync# if 0
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync /* Pattern #1:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync Windows 7:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 0:000> u ntdll!LdrLoadDll
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ntdll!LdrLoadDll:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff585 8bff mov edi,edi
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff587 55 push ebp
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff588 8bec mov ebp,esp
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff58a 51 push ecx
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff58b 51 push ecx
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 77aff58c a1f8bdaf77 mov eax,dword ptr [ntdll!LdrpLogLevelStateTable+0x24 (77afbdf8)]
f81115e612ee8fa2bc082db9d4c8879e33babc5avboxsync
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync Windows 8 rtm:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 0:000:x86> u ntdll_67150000!LdrLoadDll
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ntdll_67150000!LdrLoadDll:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 67189f3f 8bff mov edi,edi
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 67189f41 55 push ebp
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 67189f42 8bec mov ebp,esp
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 67189f44 8b0d10eb2467 mov ecx,dword ptr [ntdll_67150000!LdrpDebugFlags (6724eb10)]
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync Windows 8.1:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 0:000:x86> u ntdll_w81_32!LdrLoadDll
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync ntdll_w81_32!LdrLoadDll:
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 6718aade 8bff mov edi,edi
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 6718aae0 55 push ebp
a60be2c64ea23bb7ce4c9998bcd541c4db879fbavboxsync 6718aae1 8bec mov ebp,esp
30f07af559efcbd967e801903746fc21f81ee533vboxsync 6718aae3 83ec14 sub esp,14h
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 6718aae6 f6050040246709 test byte ptr [ntdll_w81_32!LdrpDebugFlags (67244000)],9
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync Pattern #2:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync Windows XP:
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync 0:000:x86> u ntdll_xp!LdrLoadDll
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ntdll_xp!LdrLoadDll:
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 77f569d2 6858020000 push 258h
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 77f569d7 68d866f777 push offset ntdll_xp!`string'+0x12c (77f766d8)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 77f569dc e83bb20200 call ntdll_xp!_SEH_prolog (77f81c1c)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 77f569e1 33db xor ebx,ebx
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 77f569e3 66895de0 mov word ptr [ebp-20h],bx
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 77f569e7 33c0 xor eax,eax
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 77f569e9 8d7de2 lea edi,[ebp-1Eh]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 77f569ec ab stos dword ptr es:[edi]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Windows Server 2003:
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 0:000:x86> u ntdll_w2k3_32!LdrLoadDll
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ntdll_w2k3_32!LdrLoadDll:
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 7c833f63 6840020000 push 240h
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 7c833f68 68b040837c push offset ntdll_w2k3_32!`string'+0x12c (7c8340b0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 7c833f6d e8a942ffff call ntdll_w2k3_32!_SEH_prolog (7c82821b)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 7c833f72 a13077887c mov eax,dword ptr [ntdll_w2k3_32!__security_cookie (7c887730)]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 7c833f77 8945e4 mov dword ptr [ebp-1Ch],eax
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 7c833f7a 8b4508 mov eax,dword ptr [ebp+8]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 7c833f7d 8985b0fdffff mov dword ptr [ebp-250h],eax
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 7c833f83 8b450c mov eax,dword ptr [ebp+0Ch]
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Windows Vista SP0 & SP1:
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 0:000:x86> u ntdll_vista_sp0_32!LdrLoadDll
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ntdll_vista_sp0_32!LdrLoadDll:
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb00 6844020000 push 244h
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb05 6838e9b269 push offset ntdll_vista_sp0_32! ?? ::FNODOBFM::`string'+0x39e (69b2e938)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb0a e835420300 call ntdll_vista_sp0_32!_SEH_prolog4_GS (69b42d44)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb0f 8b4508 mov eax,dword ptr [ebp+8]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb12 8985acfdffff mov dword ptr [ebp-254h],eax
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb18 8b450c mov eax,dword ptr [ebp+0Ch]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb1b 8985c0fdffff mov dword ptr [ebp-240h],eax
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 69b0eb21 8b4510 mov eax,dword ptr [ebp+10h]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if ( pbLdrLoadDll[0] == 0x8b /* mov edi, edi - for hot patching */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync && pbLdrLoadDll[1] == 0xff
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pbLdrLoadDll[2] == 0x55 /* push ebp */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync && pbLdrLoadDll[3] == 0x8b /* mov ebp,esp */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync && pbLdrLoadDll[4] == 0xec)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offJmpBack = 5; /* the 3rd instruction. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type1;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (pbLdrLoadDll[0] == 0x68 /* push dword XXXXXXXX */)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offJmpBack = 5;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pfnCallReal = supR3HardenedJmpBack_LdrLoadDll_Type2;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync g_supR3HardenedJmpBack_LdrLoadDll_Type2_PushDword = *(uint32_t const *)&pbLdrLoadDll[1];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinHookFailed("LdrLoadDll", pbLdrLoadDll);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync g_pfnLdrLoadDllJmpBack = (PFNRT)(uintptr_t)(pbLdrLoadDll + offJmpBack);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *(PFNRT *)&g_pfnLdrLoadDllReal = pfnCallReal;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Just use the disassembler to skip 6 bytes or more. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync DISSTATE Dis;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uint32_t cbInstr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offJmpBack = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync while (offJmpBack < 5)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync cbInstr = 1;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = DISInstr(pbLdrLoadDll + offJmpBack, DISCPUMODE_32BIT, &Dis, &cbInstr);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if ( RT_FAILURE(rc)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync || (Dis.pCurInstr->fOpType & (DISOPTYPE_CONTROLFLOW)) )
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedWinHookFailed("LdrLoadDll", pbLdrLoadDll);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offJmpBack += cbInstr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Assemble the code for resuming the call.*/
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *(PFNRT *)&g_pfnLdrLoadDllReal = (PFNRT)(uintptr_t)&g_abSupHardReadWriteExecPage[offExecPage];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync memcpy(&g_abSupHardReadWriteExecPage[offExecPage], pbLdrLoadDll, offJmpBack);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offExecPage += offJmpBack;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync g_abSupHardReadWriteExecPage[offExecPage++] = 0xe9;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *(uint32_t *)&g_abSupHardReadWriteExecPage[offExecPage] = (uintptr_t)&pbLdrLoadDll[offJmpBack]
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync - (uintptr_t)&g_abSupHardReadWriteExecPage[offExecPage + 4];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync offExecPage = RT_ALIGN_32(offJmpBack + 4, 16);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync# endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Patch LdrLoadDLl. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbLdrLoadDll, 16,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PAGE_EXECUTE_READWRITE, &dwOldProt));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(offJmpBack >= 5);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pbLdrLoadDll[0] = 0xe9;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *(uint32_t *)&pbLdrLoadDll[1] = (uintptr_t)supR3HardenedMonitor_LdrLoadDll - (uintptr_t)&pbLdrLoadDll[1+4];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbLdrLoadDll, 16, PAGE_EXECUTE_READ, &dwOldProt));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Seal the rwx page.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), g_abSupHardReadWriteExecPage, PAGE_SIZE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PAGE_EXECUTE_READ, &dwOldProt));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Verifies the process integrity.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncDECLHIDDEN(void) supR3HardenedWinVerifyProcess(void)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RTErrInfoInitStatic(&g_ErrInfoStatic);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(),
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPHARDNTVPKIND_VERIFY_ONLY, NULL /*pcFixes*/, &g_ErrInfoStatic.Core);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedFatalMsg("supR3HardenedWinVerifyProcess", kSupInitOp_Integrity, rc,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "Failed to verify process integrity: %s", g_ErrInfoStatic.szMsg);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Gets the SID of the user associated with the process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns @c true if we've got a login SID, @c false if not.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pSidUser Where to return the user SID.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param cbSidUser The size of the user SID buffer.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pSidLogin Where to return the login SID.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param cbSidLogin The size of the login SID buffer.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic bool supR3HardenedGetUserAndLogSids(PSID pSidUser, ULONG cbSidUser, PSID pSidLogin, ULONG cbSidLogin)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hToken;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync union
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync TOKEN_USER UserInfo;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync TOKEN_GROUPS Groups;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uint8_t abPadding[4096];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync } uBuf;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG cbRet = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtQueryInformationToken(hToken, TokenUser, &uBuf, sizeof(uBuf), &cbRet));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlCopySid(cbSidUser, pSidUser, uBuf.UserInfo.User.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync bool fLoginSid = false;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtQueryInformationToken(hToken, TokenLogonSid, &uBuf, sizeof(uBuf), &cbRet);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync for (DWORD i = 0; i < uBuf.Groups.GroupCount; i++)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if ((uBuf.Groups.Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlCopySid(cbSidLogin, pSidLogin, uBuf.Groups.Groups[i].Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fLoginSid = true;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync break;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtClose(hToken));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return fLoginSid;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Build security attributes for the process or the primary thread (@a fProcess)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Process DACLs can be bypassed using the SeDebugPrivilege (generally available
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * to admins, i.e. normal windows users), or by taking ownership and/or
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * modifying the DACL. However, it restricts
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pSecAttrs Where to return the security attributes.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pCleanup Cleanup record.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param fProcess Set if it's for the process, clear if it's for
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * the primary thread.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic void supR3HardenedInitSecAttrs(PSECURITY_ATTRIBUTES pSecAttrs, PMYSECURITYCLEANUP pCleanup, bool fProcess)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Safe return values.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync suplibHardenedMemSet(pCleanup, 0, sizeof(*pCleanup));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pSecAttrs->nLength = sizeof(*pSecAttrs);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pSecAttrs->bInheritHandle = FALSE;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pSecAttrs->lpSecurityDescriptor = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/** @todo This isn't at all complete, just sketches... */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Create an ACL detailing the access of the above groups.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlCreateAcl(&pCleanup->Acl.AclHdr, sizeof(pCleanup->Acl), ACL_REVISION));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fDeny = DELETE | WRITE_DAC | WRITE_OWNER;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fAllow = SYNCHRONIZE | READ_CONTROL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fAllowLogin = SYNCHRONIZE | READ_CONTROL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (fProcess)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny |= PROCESS_CREATE_THREAD | PROCESS_SET_SESSIONID | PROCESS_VM_OPERATION | PROCESS_VM_WRITE
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync | PROCESS_CREATE_PROCESS | PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow |= PROCESS_TERMINATE | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllowLogin |= PROCESS_TERMINATE | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)) /* Introduced in Vista. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow |= PROCESS_QUERY_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllowLogin |= PROCESS_QUERY_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 3)) /* Introduced in Windows 8.1. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow |= PROCESS_SET_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny |= THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT | THREAD_SET_INFORMATION | THREAD_SET_THREAD_TOKEN
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync | THREAD_IMPERSONATE | THREAD_DIRECT_IMPERSONATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow |= THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllowLogin |= THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)) /* Introduced in Vista. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow |= THREAD_QUERY_LIMITED_INFORMATION | THREAD_SET_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllowLogin |= THREAD_QUERY_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny |= ~fAllow & (SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Deny everyone access to bad bits. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 1
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlInitializeSid(&pCleanup->Everyone.Sid, &SIDAuthWorld, 1));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *RtlSubAuthoritySid(&pCleanup->Everyone.Sid, 0) = SECURITY_WORLD_RID;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessDeniedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny, &pCleanup->Everyone.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 0
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Grant some access to the owner - doesn't work. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SID_IDENTIFIER_AUTHORITY SIDAuthCreator = SECURITY_CREATOR_SID_AUTHORITY;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlInitializeSid(&pCleanup->Owner.Sid, &SIDAuthCreator, 1));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *RtlSubAuthoritySid(&pCleanup->Owner.Sid, 0) = SECURITY_CREATOR_OWNER_RID;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessDeniedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny, &pCleanup->Owner.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessAllowedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow, &pCleanup->Owner.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 1
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync bool fHasLoginSid = supR3HardenedGetUserAndLogSids(&pCleanup->User.Sid, sizeof(pCleanup->User),
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &pCleanup->Login.Sid, sizeof(pCleanup->Login));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync# if 1
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Grant minimal access to the user. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessDeniedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fDeny, &pCleanup->User.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessAllowedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllow, &pCleanup->User.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync# endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync# if 1
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Grant very limited access to the login sid. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (fHasLoginSid)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlAddAccessAllowedAce(&pCleanup->Acl.AclHdr, ACL_REVISION,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fAllowLogin, &pCleanup->Login.Sid));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync# endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Create a security descriptor with the above ACL.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PSECURITY_DESCRIPTOR pSecDesc = (PSECURITY_DESCRIPTOR)suplibHardenedAllocZ(SECURITY_DESCRIPTOR_MIN_LENGTH);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pCleanup->pSecDesc = pSecDesc;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlCreateSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlSetDaclSecurityDescriptor(pSecDesc, TRUE /*fDaclPresent*/, &pCleanup->Acl.AclHdr,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FALSE /*fDaclDefaulted*/));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pSecAttrs->lpSecurityDescriptor = pSecDesc;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Predicate function which tests whether @a ch is a argument separator
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * character.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns True/false.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param ch The character to examine.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncDECLINLINE(bool) suplibCommandLineIsArgSeparator(int ch)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return ch == ' '
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync || ch == '\t'
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync || ch == '\n'
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync || ch == '\r';
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Construct the new command line.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Since argc/argv are both derived from GetCommandLineW (see
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * suplibHardenedWindowsMain), we skip the argument by argument UTF-8 -> UTF-16
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * conversion and quoting by going to the original source.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * The executable name, though, is replaced in case it's not a fullly
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * qualified path.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * The re-spawn indicator is added immediately after the executable name
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * so that we don't get tripped up missing close quote chars in the last
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * argument.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns Pointer to a command line string (heap).
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pUniStr Unicode string structure to initialize to the
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * command line. Optional.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param iWhich Which respawn we're to check for, 1 being the first
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * one, and 2 the second and final.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic PRTUTF16 supR3HardenedWinConstructCmdLine(PUNICODE_STRING pString, int iWhich)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT(iWhich == 1 || iWhich == 2);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Get the command line and skip the executable name.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PUNICODE_STRING pCmdLineStr = &NtCurrentPeb()->ProcessParameters->CommandLine;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PCRTUTF16 pawcArgs = pCmdLineStr->Buffer;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uint32_t cwcArgs = pCmdLineStr->Length / sizeof(WCHAR);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Skip leading space (shouldn't be any, but whatever). */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync while (cwcArgs > 0 && suplibCommandLineIsArgSeparator(*pawcArgs) )
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync cwcArgs--, pawcArgs++;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT(cwcArgs > 0 && *pawcArgs != '\0');
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Walk to the end of it. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int fQuoted = false;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync do
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (*pawcArgs == '"')
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fQuoted = !fQuoted;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync cwcArgs--; pawcArgs++;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (*pawcArgs != '\\' || (pawcArgs[1] != '\\' && pawcArgs[1] != '"'))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcArgs--, pawcArgs++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned cSlashes = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync do
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cSlashes++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcArgs--;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pawcArgs++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcArgs > 0 && *pawcArgs == '\\');
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cwcArgs > 0 && *pawcArgs == '"' && (cSlashes & 1))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcArgs--, pawcArgs++; /* odd number of slashes == escaped quote */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } while (cwcArgs > 0 && (fQuoted || !suplibCommandLineIsArgSeparator(*pawcArgs)));
30f07af559efcbd967e801903746fc21f81ee533vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Skip trailing spaces. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcArgs > 0 && suplibCommandLineIsArgSeparator(*pawcArgs))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcArgs--, pawcArgs++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Allocate a new buffer.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertCompile(sizeof(SUPR3_RESPAWN_1_ARG0) == sizeof(SUPR3_RESPAWN_2_ARG0));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync size_t cwcCmdLine = (sizeof(SUPR3_RESPAWN_1_ARG0) - 1) / sizeof(SUPR3_RESPAWN_1_ARG0[0]) /* Respawn exe name. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync + !!cwcArgs + cwcArgs; /* if arguments present, add space + arguments. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cwcCmdLine * sizeof(WCHAR) >= 0xfff0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedFatalMsg("supR3HardenedWinConstructCmdLine", kSupInitOp_Misc, VERR_OUT_OF_RANGE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "Command line is too long (%u chars)!", cwcCmdLine);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTUTF16 pwszCmdLine = (PRTUTF16)HeapAlloc(GetProcessHeap(), 0 /* dwFlags*/, (cwcCmdLine + 1) * sizeof(RTUTF16));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUPR3HARDENED_ASSERT(pwszCmdLine != NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Construct the new command line.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTUTF16 pwszDst = pwszCmdLine;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync for (const char *pszSrc = iWhich == 1 ? SUPR3_RESPAWN_1_ARG0 : SUPR3_RESPAWN_2_ARG0; *pszSrc; pszSrc++)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *pwszDst++ = *pszSrc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cwcArgs)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync *pwszDst++ = ' ';
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync suplibHardenedMemCopy(pwszDst, pawcArgs, cwcArgs * sizeof(RTUTF16));
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync pwszDst += cwcArgs;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync }
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *pwszDst = '\0';
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUPR3HARDENED_ASSERT(pwszDst - pwszCmdLine == cwcCmdLine);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pString)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pString->Buffer = pwszCmdLine;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pString->Length = (USHORT)(cwcCmdLine * sizeof(WCHAR));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pString->MaximumLength = pString->Length + sizeof(WCHAR);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync return pwszCmdLine;
edde275acba04aca58db4172a163741e3abadfbcvboxsync}
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Check if the zero terminated NT unicode string is the path to the given
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * system32 DLL.
edde275acba04aca58db4172a163741e3abadfbcvboxsync *
edde275acba04aca58db4172a163741e3abadfbcvboxsync * @returns true if it is, false if not.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pUniStr The zero terminated NT unicode string path.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pszName The name of the system32 DLL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsyncstatic bool supR3HardNtIsNamedSystem32Dll(PUNICODE_STRING pUniStr, const char *pszName)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync{
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if (pUniStr->Length > g_System32NtPath.UniStr.Length)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (memcmp(pUniStr->Buffer, g_System32NtPath.UniStr.Buffer, g_System32NtPath.UniStr.Length) == 0)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync {
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if (pUniStr->Buffer[g_System32NtPath.UniStr.Length / sizeof(WCHAR)] == '\\')
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTUtf16ICmpAscii(&pUniStr->Buffer[g_System32NtPath.UniStr.Length / sizeof(WCHAR) + 1], pszName) == 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return true;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return false;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync/**
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * Common code used for child and parent to make new threads exit immediately.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This patches the LdrInitializeThunk code to call NtTerminateThread with
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * STATUS_SUCCESS instead of doing the NTDLL initialization.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * @returns VBox status code.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param hProcess The process to do this to.
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * @param pvLdrInitThunk The address of the LdrInitializeThunk code to
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * override.
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * @param pvNtTerminateThread The address of the NtTerminateThread function in
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * the NTDLL instance we're patching. (Must be +/-
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * 2GB from the thunk code.)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * @param pabBackup Where to back up the original instruction bytes
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * at pvLdrInitThunk.
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * @param cbBackup The size of the backup area. Must be 16 bytes.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pErrInfo Where to return extended error information.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Optional.
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync */
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsyncstatic int supR3HardNtDisableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, void *pvNtTerminateThread,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint8_t *pabBackup, size_t cbBackup, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF(("supR3HardNtDisableThreadCreation: pvLdrInitThunk=%p pvNtTerminateThread=%p\n", pvLdrInitThunk, pvNtTerminateThread));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUPR3HARDENED_ASSERT(cbBackup == 16);
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUPR3HARDENED_ASSERT(RT_ABS((intptr_t)pvLdrInitThunk - (intptr_t)pvNtTerminateThread) < 16*_1M);
edde275acba04aca58db4172a163741e3abadfbcvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Back up the thunk code.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync SIZE_T cbIgnored;
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNt = NtReadVirtualMemory(hProcess, pvLdrInitThunk, pabBackup, cbBackup, &cbIgnored);
30f07af559efcbd967e801903746fc21f81ee533vboxsync if (!NT_SUCCESS(rcNt))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "supR3HardNtDisableThreadCreation: NtReadVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Cook up replacement code that calls NtTerminateThread.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint8_t abReplacement[16];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(abReplacement, pabBackup, sizeof(abReplacement));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifdef RT_ARCH_AMD64
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[0] = 0x31; /* xor ecx, ecx */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[1] = 0xc9;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync abReplacement[2] = 0x31; /* xor edx, edx */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[3] = 0xd2;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[4] = 0xe8; /* call near NtTerminateThread */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *(int32_t *)&abReplacement[5] = (int32_t)((uintptr_t)pvNtTerminateThread - ((uintptr_t)pvLdrInitThunk + 9));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[9] = 0xcc; /* int3 */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#elif defined(RT_ARCH_X86)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abReplacement[0] = 0x6a; /* push 0 */
edde275acba04aca58db4172a163741e3abadfbcvboxsync abReplacement[1] = 0x00;
edde275acba04aca58db4172a163741e3abadfbcvboxsync abReplacement[2] = 0x6a; /* push 0 */
edde275acba04aca58db4172a163741e3abadfbcvboxsync abReplacement[3] = 0x00;
edde275acba04aca58db4172a163741e3abadfbcvboxsync abReplacement[4] = 0xe8; /* call near NtTerminateThread */
edde275acba04aca58db4172a163741e3abadfbcvboxsync *(int32_t *)&abReplacement[5] = (int32_t)((uintptr_t)pvNtTerminateThread - ((uintptr_t)pvLdrInitThunk + 9));
edde275acba04aca58db4172a163741e3abadfbcvboxsync abReplacement[9] = 0xcc; /* int3 */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync# error "Unsupported arch."
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
dca3cdd56f38abf4257b94ff13268323ea52e0a7vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Install the replacment code.
dca3cdd56f38abf4257b94ff13268323ea52e0a7vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PVOID pvProt = pvLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SIZE_T cbProt = cbBackup;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fOldProt = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
dca3cdd56f38abf4257b94ff13268323ea52e0a7vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
dca3cdd56f38abf4257b94ff13268323ea52e0a7vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, abReplacement, sizeof(abReplacement), &cbIgnored);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "supR3HardNtDisableThreadCreationEx: NtWriteVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
dca3cdd56f38abf4257b94ff13268323ea52e0a7vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pvProt = pvLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync cbProt = cbBackup;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk/2 failed: %#x", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync return VINF_SUCCESS;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Undo the effects of supR3HardNtDisableThreadCreationEx.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns VBox status code.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param hProcess The process to do this to.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pvLdrInitThunk The address of the LdrInitializeThunk code to
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * override.
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * @param pabBackup Where to back up the original instruction bytes
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * at pvLdrInitThunk.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param cbBackup The size of the backup area. Must be 16 bytes.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pErrInfo Where to return extended error information.
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * Optional.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic int supR3HardNtEnableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, uint8_t const *pabBackup, size_t cbBackup,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PRTERRINFO pErrInfo)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtEnableThreadCreation:\n"));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT(cbBackup == 16);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PVOID pvProt = pvLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SIZE_T cbProt = cbBackup;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fOldProt = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync SIZE_T cbIgnored;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, pabBackup, cbBackup, &cbIgnored);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync "supR3HardNtEnableThreadCreation: NtWriteVirtualMemory/LdrInitializeThunk[restore] failed: %#x",
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync rcNt);
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync pvProt = pvLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync cbProt = cbBackup;
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "supR3HardNtEnableThreadCreation: NtProtectVirtualMemory/LdrInitializeThunk[restore] failed: %#x",
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return VINF_SUCCESS;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync/**
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Disable thread creation for the current process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
edde275acba04aca58db4172a163741e3abadfbcvboxsync * @remarks Doesn't really disables it, just makes the threads exit immediately
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * without executing any real code.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic void supR3HardenedWinDisableThreadCreation(void)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Cannot use the imported NtTerminateThread as it's pointing to our own
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync syscall assembly code. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync static PFNRT s_pfnNtTerminateThread = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (s_pfnNtTerminateThread == NULL)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync s_pfnNtTerminateThread = supR3HardenedWinGetRealDllSymbol("ntdll.dll", "NtTerminateThread");
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUPR3HARDENED_ASSERT(s_pfnNtTerminateThread);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supR3HardNtDisableThreadCreationEx(NtCurrentProcess(),
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync (void *)(uintptr_t)&LdrInitializeThunk,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync (void *)(uintptr_t)s_pfnNtTerminateThread,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync g_abLdrInitThunkSelfBackup, sizeof(g_abLdrInitThunkSelfBackup),
edde275acba04aca58db4172a163741e3abadfbcvboxsync NULL /* pErrInfo*/);
edde275acba04aca58db4172a163741e3abadfbcvboxsync g_fSupInitThunkSelfPatched = RT_SUCCESS(rc);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Undoes the effects of supR3HardenedWinDisableThreadCreation.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncDECLHIDDEN(void) supR3HardenedWinEnableThreadCreation(void)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
edde275acba04aca58db4172a163741e3abadfbcvboxsync if (g_fSupInitThunkSelfPatched)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supR3HardNtEnableThreadCreationEx(NtCurrentProcess(),
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync (void *)(uintptr_t)&LdrInitializeThunk,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync g_abLdrInitThunkSelfBackup, sizeof(g_abLdrInitThunkSelfBackup),
edde275acba04aca58db4172a163741e3abadfbcvboxsync RTErrInfoInitStatic(&g_ErrInfoStatic));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedError(rc, true /*fFatal*/, "%s", g_ErrInfoStatic.szMsg);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync g_fSupInitThunkSelfPatched = false;
04f85536aa01b3e25cece11d2a094e2a362bcbfavboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/*
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync * Child-Process Purification - release it from dubious influences.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * AV software and other things injecting themselves into the embryonic
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync * and budding process to intercept API calls and what not. Unfortunately
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * this is also the behavior of viruses, malware and other unfriendly
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * software, so we won't stand for it. AV software can scan our image
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * as they are loaded via kernel hooks, that's sufficient. No need for
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * matching half of NTDLL or messing with the import table of the
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * process executable.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsynctypedef struct SUPR3HARDNTPUCH
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** Process handle. */
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync HANDLE hProcess;
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync /** Primary thread handle. */
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync HANDLE hThread;
edde275acba04aca58db4172a163741e3abadfbcvboxsync /** Error buffer. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PRTERRINFO pErrInfo;
edde275acba04aca58db4172a163741e3abadfbcvboxsync /** The address of NTDLL in the child. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uintptr_t uNtDllAddr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** The address of NTDLL in this process. */
edde275acba04aca58db4172a163741e3abadfbcvboxsync uintptr_t uNtDllParentAddr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** The basic process info. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PROCESS_BASIC_INFORMATION BasicInfo;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** The probable size of the PEB. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync size_t cbPeb;
edde275acba04aca58db4172a163741e3abadfbcvboxsync /** The pristine process environment block. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PEB Peb;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync} SUPR3HARDNTPUCH;
edde275acba04aca58db4172a163741e3abadfbcvboxsynctypedef SUPR3HARDNTPUCH *PSUPR3HARDNTPUCH;
1042ff61f0b8de217c7e694021be0b9a5b9b8468vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic int supR3HardNtPuChScrewUpPebForInitialImageEvents(PSUPR3HARDNTPUCH pThis)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
1042ff61f0b8de217c7e694021be0b9a5b9b8468vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Not sure if any of the cracker software uses the PEB at this point, but
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * just in case they do make some of the PEB fields a little less useful.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PEB Peb = pThis->Peb;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Make ImageBaseAddress useless. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.ImageBaseAddress = (PVOID)((uintptr_t)Peb.ImageBaseAddress ^ UINT32_C(0x5f139000));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#ifdef RT_ARCH_AMD64
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.ImageBaseAddress = (PVOID)((uintptr_t)Peb.ImageBaseAddress | UINT64_C(0x0313000000000000));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Write the PEB.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SIZE_T cbActualMem = pThis->cbPeb;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtWriteVirtualMemory(pThis->hProcess, pThis->BasicInfo.PebBaseAddress, &Peb, pThis->cbPeb, &cbActualMem);
1042ff61f0b8de217c7e694021be0b9a5b9b8468vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE, "NtWriteVirtualMemory/Peb failed: %#x", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return VINF_SUCCESS;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Unmaps a DLL from the child process that was previously mapped by
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * supR3HardNtPuChMapDllIntoChild.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns Pointer to the DLL mapping on success, NULL on failure.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pThis The child purification instance data.
1042ff61f0b8de217c7e694021be0b9a5b9b8468vboxsync * @param pvBase The base address of the mapping. Nothing done
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * if NULL.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pszShort The short name (for logging).
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic void supR3HardNtPuChUnmapDllFromChild(PSUPR3HARDNTPUCH pThis, PVOID pvBase, const char *pszShort)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (pvBase)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*SUP_DPRINTF(("supR3HardNtPuChUnmapDllFromChild: Calling NtUnmapViewOfSection on %p / %s\n", pvBase, pszShort));*/
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtUnmapViewOfSection(pThis->hProcess, pvBase);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(!rcNt))
1042ff61f0b8de217c7e694021be0b9a5b9b8468vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: NtUnmapViewOfSection failed on %s: %#x (%p)\n",
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pszShort, rcNt, pvBase));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Maps a DLL into the child process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns Pointer to the DLL mapping on success, NULL on failure.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pThis The child purification instance data.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pNtName The path to the DLL.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pszShort The short name (for logging).
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic PVOID supR3HardNtPuChMapDllIntoChild(PSUPR3HARDNTPUCH pThis, PUNICODE_STRING pNtName, const char *pszShort)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync OBJECT_ATTRIBUTES ObjAttr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync InitializeObjectAttributes(&ObjAttr, pNtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtCreateFile(&hFile,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync GENERIC_READ | GENERIC_EXECUTE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &ObjAttr,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &Ios,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* Allocation Size*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FILE_ATTRIBUTE_NORMAL,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FILE_SHARE_READ,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FILE_OPEN,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FILE_NON_DIRECTORY_FILE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /*EaBuffer*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync 0 /*EaLength*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = Ios.Status;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PVOID pvRet = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hSection = RTNT_INVALID_HANDLE_VALUE;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtCreateSection(&hSection,
edde275acba04aca58db4172a163741e3abadfbcvboxsync SECTION_MAP_EXECUTE | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_QUERY,
04f85536aa01b3e25cece11d2a094e2a362bcbfavboxsync NULL /* pObjAttr*/, NULL /*pMaxSize*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PAGE_EXECUTE, SEC_IMAGE, hFile);
04f85536aa01b3e25cece11d2a094e2a362bcbfavboxsync if (NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SIZE_T cbView = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: mapping view of %s\n", pszShort)); /* For SEP. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtMapViewOfSection(hSection, pThis->hProcess, &pvRet, 0 /*ZeroBits*/, 0 /*CommitSize*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /*pOffSect*/, &cbView, ViewShare, 0 /*AllocationType*/, PAGE_READWRITE);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (NT_SUCCESS(rcNt))
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: %s mapped at %p LB %#x\n", pszShort, pvRet, cbView));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: NtMapViewOfSection failed on %s: %#x\n", pszShort, rcNt));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pvRet = NULL;
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtClose(hSection);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: NtCreateSection failed on %s: %#x\n", pszShort, rcNt));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtClose(hFile);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync else
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: Error opening %s: %#x\n", pszShort, rcNt));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return pvRet;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Trigger the initial image events without actually initializing the process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * This is a trick to force sysplant.sys to call its hand by tripping the image
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * loaded event for the main executable and ntdll images. This will happen when
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * the first thread in a process starts executing in PspUserThreadStartup. We
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * create a second thread that quits immediately by means of temporarily
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync * replacing ntdll!LdrInitializeThunk by a NtTerminateThread call.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * (LdrInitializeThunk is called by way of an APC queued the thread is created,
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync * thus NtSetContextThread is of no use.)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns VBox status code.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pThis The child cleanup
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pErrInfo For extended error information.
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync */
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsyncstatic int supR3HardNtPuChTriggerInitialImageEvents(PSUPR3HARDNTPUCH pThis)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Use the on-disk image for the ntdll entrypoints here.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PSUPHNTLDRCACHEENTRY pLdrEntry;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supHardNtLdrCacheOpen("ntdll.dll", &pLdrEntry);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pThis->pErrInfo, rc, "supHardNtLdrCacheOpen failed on NTDLL: %Rrc", rc);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RTLDRADDR uLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = RTLdrGetSymbolEx(pLdrEntry->hLdrMod, pLdrEntry->pbBits, pThis->uNtDllAddr, UINT32_MAX,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "LdrInitializeThunk", &uLdrInitThunk);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pThis->pErrInfo, rc, "Error locating LdrInitializeThunk in NTDLL: %Rrc", rc);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PVOID pvLdrInitThunk = (PVOID)(uintptr_t)uLdrInitThunk;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RTLDRADDR uNtTerminateThread;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = RTLdrGetSymbolEx(pLdrEntry->hLdrMod, pLdrEntry->pbBits, pThis->uNtDllAddr, UINT32_MAX,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "NtTerminateThread", &uNtTerminateThread);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pThis->pErrInfo, rc, "Error locating NtTerminateThread in NTDLL: %Rrc", rc);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: uLdrInitThunk=%p uNtTerminateThread=%p\n",
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync (uintptr_t)uLdrInitThunk, (uintptr_t)uNtTerminateThread));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Patch the child's LdrInitializeThunk to exit the thread immediately.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint8_t abBackup[16];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supR3HardNtDisableThreadCreationEx(pThis->hProcess, pvLdrInitThunk, (void *)(uintptr_t)uNtTerminateThread,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync abBackup, sizeof(abBackup), pThis->pErrInfo);
edde275acba04aca58db4172a163741e3abadfbcvboxsync if (RT_FAILURE(rc))
edde275acba04aca58db4172a163741e3abadfbcvboxsync return rc;
edde275acba04aca58db4172a163741e3abadfbcvboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * To further muddle the waters, we map the executable image and ntdll.dll
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * a 2nd time into the process before we actually start executing the thread
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * and trigger the genuine image load events.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Update #1 (after 4.3.15 build 7):
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Turns out Symantec Endpoint Protection deadlocks when we map the
edde275acba04aca58db4172a163741e3abadfbcvboxsync * executable into the process like this. The system only works
edde275acba04aca58db4172a163741e3abadfbcvboxsync * halfways after that Powerbutton, impossible to shutdown without
edde275acba04aca58db4172a163741e3abadfbcvboxsync * using the power or reset button. The order of the two mappings
edde275acba04aca58db4172a163741e3abadfbcvboxsync * below doesn't matter. Haven't had time to look at stack yet.
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Observed on W7/64, SEP v12.1.4112.4156.
edde275acba04aca58db4172a163741e3abadfbcvboxsync *
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Update #2 (after 4.3.16):
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Some avast! users complain about a deadlock mapping ntdll.dll
edde275acba04aca58db4172a163741e3abadfbcvboxsync * as well. Unfortunately not reproducible, so there may possibly be
edde275acba04aca58db4172a163741e3abadfbcvboxsync * some other cause. Sad as it's really a serious bug in whichever
edde275acba04aca58db4172a163741e3abadfbcvboxsync * software it is that is causing it, and we'd like to report it to
edde275acba04aca58db4172a163741e3abadfbcvboxsync * the responsible party.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync#if 0
edde275acba04aca58db4172a163741e3abadfbcvboxsync PVOID pvExe2 = supR3HardNtPuChMapDllIntoChild(pThis, &g_SupLibHardenedExeNtPath.UniStr, "executable[2nd]");
edde275acba04aca58db4172a163741e3abadfbcvboxsync#else
edde275acba04aca58db4172a163741e3abadfbcvboxsync PVOID pvExe2 = NULL;
edde275acba04aca58db4172a163741e3abadfbcvboxsync#endif
edde275acba04aca58db4172a163741e3abadfbcvboxsync#if 0
edde275acba04aca58db4172a163741e3abadfbcvboxsync UNICODE_STRING NtName1 = RTNT_CONSTANT_UNISTR(L"\\SystemRoot\\System32\\ntdll.dll");
edde275acba04aca58db4172a163741e3abadfbcvboxsync PVOID pvNtDll2 = supR3HardNtPuChMapDllIntoChild(pThis, &NtName1, "ntdll.dll[2nd]");
edde275acba04aca58db4172a163741e3abadfbcvboxsync#else
edde275acba04aca58db4172a163741e3abadfbcvboxsync PVOID pvNtDll2 = NULL;
edde275acba04aca58db4172a163741e3abadfbcvboxsync#endif
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Create the thread, waiting 10 seconds for it to complete.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync CLIENT_ID Thread2Id;
edde275acba04aca58db4172a163741e3abadfbcvboxsync HANDLE hThread2;
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNt = RtlCreateUserThread(pThis->hProcess,
edde275acba04aca58db4172a163741e3abadfbcvboxsync NULL /* SecurityAttribs */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync FALSE /* CreateSuspended */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync 0 /* ZeroBits */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync 0 /* MaximumStackSize */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync 0 /* CommittedStackSize */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync (PFNRT)2 /* StartAddress */,
edde275acba04aca58db4172a163741e3abadfbcvboxsync NULL /*Parameter*/ ,
edde275acba04aca58db4172a163741e3abadfbcvboxsync &hThread2,
edde275acba04aca58db4172a163741e3abadfbcvboxsync &Thread2Id);
edde275acba04aca58db4172a163741e3abadfbcvboxsync if (NT_SUCCESS(rcNt))
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync LARGE_INTEGER Timeout;
edde275acba04aca58db4172a163741e3abadfbcvboxsync Timeout.QuadPart = -10 * 10000000; /* 10 seconds */
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtWaitForSingleObject(hThread2, FALSE /* Alertable */, &Timeout);
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtTerminateThread(hThread2, DBG_TERMINATE_THREAD);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtClose(hThread2);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Map kernel32.dll and kernelbase.dll (if applicable) into the process.
edde275acba04aca58db4172a163741e3abadfbcvboxsync * This triggers should image load events that may set of AV activities
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * that we'd rather see early than later.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync UNICODE_STRING NtName2 = RTNT_CONSTANT_UNISTR(L"\\SystemRoot\\System32\\kernel32.dll");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PVOID pvKernel32 = supR3HardNtPuChMapDllIntoChild(pThis, &NtName2, "kernel32.dll");
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync UNICODE_STRING NtName3 = RTNT_CONSTANT_UNISTR(L"\\SystemRoot\\System32\\KernelBase.dll");
9f997e760f610c92e3a365be21ead6972bc46130vboxsync PVOID pvKernelBase = g_uNtVerCombined >= SUP_NT_VER_VISTA
9f997e760f610c92e3a365be21ead6972bc46130vboxsync ? supR3HardNtPuChMapDllIntoChild(pThis, &NtName3, "KernelBase.dll")
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync : NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Fudge factor for letting kernel threads get a chance to mess up our
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * process asynchronously.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync DWORD dwStart = GetTickCount();
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uint32_t cMsKludge = (g_fSupAdversaries & SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT) ? 256 : g_fSupAdversaries ? 64 : 16;
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync do
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync {
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync NtYieldExecution();
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync LARGE_INTEGER Time;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Time.QuadPart = -8000000 / 100; /* 8ms in 100ns units, relative time. */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync NtDelayExecution(FALSE, &Time);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync } while (GetTickCount() - dwStart < cMsKludge);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardNtPuChTriggerInitialImageEvents: Startup delay kludge #1: %u ms\n", GetTickCount() - dwStart));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync * Unmap the image we mapped into the guest above.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync supR3HardNtPuChUnmapDllFromChild(pThis, pvKernel32, "kernel32.dll");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardNtPuChUnmapDllFromChild(pThis, pvKernelBase, "KernelBase.dll");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardNtPuChUnmapDllFromChild(pThis, pvNtDll2, "ntdll.dll[2nd]");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardNtPuChUnmapDllFromChild(pThis, pvExe2, "executable[2nd]");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Restore the original thunk code and protection.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * We do this after waiting as anyone trying to kick of threads in the
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync * process will get nothing done as long as our patch is in place.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync rc = supR3HardNtEnableThreadCreationEx(pThis->hProcess, pvLdrInitThunk, abBackup, sizeof(abBackup), pThis->pErrInfo);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return rc;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return VINF_SUCCESS;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 0
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic int supR3HardenedWinScratchChildMemory(HANDLE hProcess, void *pv, size_t cb, const char *pszWhat, PRTERRINFO pErrInfo)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinScratchChildMemory: %p %#x\n", pv, cb));
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync PVOID pvCopy = pv;
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync SIZE_T cbCopy = cb;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtProtectVirtualMemory(hProcess, &pvCopy, &cbCopy, PAGE_NOACCESS, NULL);
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync if (!NT_SUCCESS(rcNt))
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "NtProtectVirtualMemory/%s (%p LB %#zx) failed: %#x",
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pszWhat, pv, cb, rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return VINF_SUCCESS;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic int supR3HardNtPuChSanitizePeb(PSUPR3HARDNTPUCH pThis)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Make a copy of the pre-execution PEB.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PEB Peb = pThis->Peb;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync#if 0
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * There should not be any activation context, so if there is, we scratch the memory associated with it.
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync int rc = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (RT_SUCCESS(rc) && Peb.pShimData && !((uintptr_t)Peb.pShimData & PAGE_OFFSET_MASK))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync rc = supR3HardenedWinScratchChildMemory(hProcess, Peb.pShimData, PAGE_SIZE, "pShimData", pErrInfo);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_SUCCESS(rc) && Peb.ActivationContextData && !((uintptr_t)Peb.ActivationContextData & PAGE_OFFSET_MASK))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supR3HardenedWinScratchChildMemory(hProcess, Peb.ActivationContextData, PAGE_SIZE, "ActivationContextData", pErrInfo);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (RT_SUCCESS(rc) && Peb.ProcessAssemblyStorageMap && !((uintptr_t)Peb.ProcessAssemblyStorageMap & PAGE_OFFSET_MASK))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supR3HardenedWinScratchChildMemory(hProcess, Peb.ProcessAssemblyStorageMap, PAGE_SIZE, "ProcessAssemblyStorageMap", pErrInfo);
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync if (RT_SUCCESS(rc) && Peb.SystemDefaultActivationContextData && !((uintptr_t)Peb.SystemDefaultActivationContextData & PAGE_OFFSET_MASK))
bc6740610771ba30b63f58af903b4824c33f5b51vboxsync rc = supR3HardenedWinScratchChildMemory(hProcess, Peb.ProcessAssemblyStorageMap, PAGE_SIZE, "SystemDefaultActivationContextData", pErrInfo);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (RT_SUCCESS(rc) && Peb.SystemAssemblyStorageMap && !((uintptr_t)Peb.SystemAssemblyStorageMap & PAGE_OFFSET_MASK))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync rc = supR3HardenedWinScratchChildMemory(hProcess, Peb.SystemAssemblyStorageMap, PAGE_SIZE, "SystemAssemblyStorageMap", pErrInfo);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (RT_FAILURE(rc))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync return rc;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Clear compatibility and activation related fields.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.AppCompatFlags.QuadPart = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync Peb.AppCompatFlagsUser.QuadPart = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.pShimData = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.AppCompatInfo = NULL;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync#if 0
9f997e760f610c92e3a365be21ead6972bc46130vboxsync Peb.ActivationContextData = NULL;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync Peb.ProcessAssemblyStorageMap = NULL;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync Peb.SystemDefaultActivationContextData = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync Peb.SystemAssemblyStorageMap = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*Peb.Diff0.W6.IsProtectedProcess = 1;*/
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Write back the PEB.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SIZE_T cbActualMem = pThis->cbPeb;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync NTSTATUS rcNt = NtWriteVirtualMemory(pThis->hProcess, pThis->BasicInfo.PebBaseAddress, &Peb, pThis->cbPeb, &cbActualMem);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE, "NtWriteVirtualMemory/Peb failed: %#x", rcNt);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return VINF_SUCCESS;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync}
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsyncstatic void supR3HardNtPuChFindNtdll(PSUPR3HARDNTPUCH pThis)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync{
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /*
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Find NTDLL in this process first and take that as a starting point.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pThis->uNtDllParentAddr = (uintptr_t)GetModuleHandleW(L"ntdll.dll");
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT(pThis->uNtDllParentAddr != 0 && !(pThis->uNtDllParentAddr & PAGE_OFFSET_MASK));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pThis->uNtDllAddr = pThis->uNtDllParentAddr;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Scan the virtual memory of the child.
9f997e760f610c92e3a365be21ead6972bc46130vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync uintptr_t cbAdvance = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uintptr_t uPtrWhere = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync for (uint32_t i = 0; i < 1024; i++)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /* Query information. */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SIZE_T cbActual = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync MEMORY_BASIC_INFORMATION MemInfo = { 0, 0, 0, 0, 0, 0, 0 };
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtQueryVirtualMemory(pThis->hProcess,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync (void const *)uPtrWhere,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync MemoryBasicInformation,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync &MemInfo,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync sizeof(MemInfo),
9f997e760f610c92e3a365be21ead6972bc46130vboxsync &cbActual);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (!NT_SUCCESS(rcNt))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync break;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if ( MemInfo.Type == SEC_IMAGE
9f997e760f610c92e3a365be21ead6972bc46130vboxsync || MemInfo.Type == SEC_PROTECTED_IMAGE
9f997e760f610c92e3a365be21ead6972bc46130vboxsync || MemInfo.Type == (SEC_IMAGE | SEC_PROTECTED_IMAGE))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (MemInfo.BaseAddress == MemInfo.AllocationBase)
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /* Get the image name. */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync union
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync UNICODE_STRING UniStr;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uint8_t abPadding[4096];
9f997e760f610c92e3a365be21ead6972bc46130vboxsync } uBuf;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync NTSTATUS rcNt = NtQueryVirtualMemory(pThis->hProcess,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync MemInfo.BaseAddress,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync MemorySectionName,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync &uBuf,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync sizeof(uBuf) - sizeof(WCHAR),
9f997e760f610c92e3a365be21ead6972bc46130vboxsync &cbActual);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (NT_SUCCESS(rcNt))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uBuf.UniStr.Buffer[uBuf.UniStr.Length / sizeof(WCHAR)] = '\0';
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (supR3HardNtIsNamedSystem32Dll(&uBuf.UniStr, "ntdll.dll"))
9f997e760f610c92e3a365be21ead6972bc46130vboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pThis->uNtDllAddr = (uintptr_t)MemInfo.AllocationBase;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync SUP_DPRINTF(("supR3HardNtPuChFindNtdll: uNtDllParentAddr=%p uNtDllChildAddr=%p\n",
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pThis->uNtDllParentAddr, pThis->uNtDllAddr));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync return;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * Advance.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync cbAdvance = MemInfo.RegionSize;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (uPtrWhere + cbAdvance <= uPtrWhere)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync break;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uPtrWhere += MemInfo.RegionSize;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#ifdef DEBUG
9f997e760f610c92e3a365be21ead6972bc46130vboxsync supR3HardenedFatal("%s: ntdll.dll not found in child.", __FUNCTION__);
9f997e760f610c92e3a365be21ead6972bc46130vboxsync#endif
9f997e760f610c92e3a365be21ead6972bc46130vboxsync}
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsyncstatic int supR3HardenedWinPurifyChild(HANDLE hProcess, HANDLE hThread, PRTERRINFO pErrInfo)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Initialize the purifier instance data.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDNTPUCH This;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.hProcess = hProcess;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.hThread = hThread;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.pErrInfo = pErrInfo;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG cbActual = 0;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtQueryInformationProcess(hProcess, ProcessBasicInformation,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &This.BasicInfo, sizeof(This.BasicInfo), &cbActual);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "NtQueryInformationProcess/ProcessBasicInformation failed: %#x", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (g_uNtVerCombined < SUP_NT_VER_W2K3)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W51;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else if (g_uNtVerCombined < SUP_NT_VER_VISTA)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W52;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else if (g_uNtVerCombined < SUP_NT_VER_W70)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W6;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else if (g_uNtVerCombined < SUP_NT_VER_W80)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W7;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else if (g_uNtVerCombined < SUP_NT_VER_W81)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W80;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync This.cbPeb = PEB_SIZE_W81;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinPurifyChild: PebBaseAddress=%p cbPeb=%#x\n", This.BasicInfo.PebBaseAddress, This.cbPeb));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SIZE_T cbActualMem;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RT_ZERO(This.Peb);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtReadVirtualMemory(hProcess, This.BasicInfo.PebBaseAddress, &This.Peb, sizeof(This.Peb), &cbActualMem);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "NtReadVirtualMemory/Peb failed: %#x", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardNtPuChFindNtdll(&This);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Do the work, the last bit we tag along with the process verfication code.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supR3HardNtPuChScrewUpPebForInitialImageEvents(&This);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_SUCCESS(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supR3HardNtPuChTriggerInitialImageEvents(&This);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_SUCCESS(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supR3HardNtPuChSanitizePeb(&This);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_SUCCESS(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rc = supHardenedWinVerifyProcess(hProcess, hThread, SUPHARDNTVPKIND_CHILD_PURIFICATION, NULL /*pcFixes*/, pErrInfo);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return rc;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Does the actually respawning.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @returns Never, will call exit or raise fatal error.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param iWhich Which respawn we're to check for, 1 being the
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * first one, and 2 the second and final.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @todo Split up this function.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsyncstatic int supR3HardenedWinDoReSpawn(int iWhich)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync{
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PPEB pPeb = NtCurrentPeb();
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PRTL_USER_PROCESS_PARAMETERS pParentProcParams = pPeb->ProcessParameters;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT(g_cSuplibHardenedWindowsMainCalls == 1);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Set up security descriptors.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SECURITY_ATTRIBUTES ProcessSecAttrs;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync MYSECURITYCLEANUP ProcessSecAttrsCleanup;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedInitSecAttrs(&ProcessSecAttrs, &ProcessSecAttrsCleanup, true /*fProcess*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SECURITY_ATTRIBUTES ThreadSecAttrs;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync MYSECURITYCLEANUP ThreadSecAttrsCleanup;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedInitSecAttrs(&ThreadSecAttrs, &ThreadSecAttrsCleanup, false /*fProcess*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#if 1
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Configure the startup info and creation flags.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync DWORD dwCreationFlags = CREATE_SUSPENDED;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync STARTUPINFOEXW SiEx;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync suplibHardenedMemSet(&SiEx, 0, sizeof(SiEx));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (1)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.cb = sizeof(SiEx.StartupInfo);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.cb = sizeof(SiEx);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** @todo experiment with protected process stuff later on. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.dwFlags |= pParentProcParams->WindowFlags & STARTF_USESHOWWINDOW;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.wShowWindow = (WORD)pParentProcParams->ShowWindowFlags;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.hStdInput = pParentProcParams->StandardInput;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.hStdOutput = pParentProcParams->StandardOutput;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SiEx.StartupInfo.hStdError = pParentProcParams->StandardError;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Construct the command line and launch the process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PRTUTF16 pwszCmdLine = supR3HardenedWinConstructCmdLine(NULL, iWhich);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedWinEnableThreadCreation();
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PROCESS_INFORMATION ProcessInfoW32;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!CreateProcessW(g_wszSupLibHardenedExePath,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pwszCmdLine,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &ProcessSecAttrs,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &ThreadSecAttrs,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync TRUE /*fInheritHandles*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync dwCreationFlags,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /*pwszzEnvironment*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /*pwszCurDir*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &SiEx.StartupInfo,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &ProcessInfoW32))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, VERR_INVALID_NAME,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "Error relaunching VirtualBox VM process: %u\n"
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "Command line: '%ls'",
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync GetLastError(), pwszCmdLine);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedWinDisableThreadCreation();
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinDoReSpawn(%d): New child %x.%x [kernel32].\n",
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync iWhich, ProcessInfoW32.dwProcessId, ProcessInfoW32.dwThreadId));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hProcess = ProcessInfoW32.hProcess;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hThread = ProcessInfoW32.hThread;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#else
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Construct the process parameters.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync UNICODE_STRING W32ImageName;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync W32ImageName.Buffer = g_wszSupLibHardenedExePath; /* Yes the windows name for the process parameters. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync W32ImageName.Length = (USHORT)RTUtf16Len(g_wszSupLibHardenedExePath) * sizeof(WCHAR);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync W32ImageName.MaximumLength = W32ImageName.Length + sizeof(WCHAR);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync UNICODE_STRING CmdLine;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedWinConstructCmdLine(&CmdLine, iWhich);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PRTL_USER_PROCESS_PARAMETERS pProcParams = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(RtlCreateProcessParameters(&pProcParams,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &W32ImageName,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* DllPath - inherit from this process */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* CurrentDirectory - inherit from this process */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &CmdLine,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* Environment - inherit from this process */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* WindowsTitle - none */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* DesktopTitle - none. */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* ShellInfo - none. */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* RuntimeInfo - none (byte array for MSVCRT file info) */)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync );
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /** @todo this doesn't work. :-( */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams->ConsoleHandle = pParentProcParams->ConsoleHandle;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams->ConsoleFlags = pParentProcParams->ConsoleFlags;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams->StandardInput = pParentProcParams->StandardInput;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams->StandardOutput = pParentProcParams->StandardOutput;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams->StandardError = pParentProcParams->StandardError;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RTL_USER_PROCESS_INFORMATION ProcessInfoNt = { sizeof(ProcessInfoNt) };
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = RtlCreateUserProcess(&g_SupLibHardenedExeNtPath.UniStr,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync OBJ_INHERIT | OBJ_CASE_INSENSITIVE /*Attributes*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync pProcParams,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL, //&ProcessSecAttrs,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL, //&ThreadSecAttrs,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtCurrentProcess() /* ParentProcess */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FALSE /*fInheritHandles*/,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* DebugPort */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NULL /* ExceptionPort */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &ProcessInfoNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, VERR_INVALID_NAME,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "Error relaunching VirtualBox VM process: %#x\n"
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync "Command line: '%ls'",
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt, CmdLine.Buffer);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinDoReSpawn(%d): New child %x.%x [ntdll].\n",
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync iWhich, ProcessInfo.ClientId.UniqueProcess, ProcessInfo.ClientId.UniqueThread));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync RtlDestroyProcessParameters(pProcParams);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hProcess = ProcessInfoNt.ProcessHandle;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hThread = ProcessInfoNt.ThreadHandle;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#ifndef VBOX_WITHOUT_DEBUGGER_CHECKS
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Apply anti debugger notification trick to the thread. (Also done in
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * supR3HardenedWinInstallHooks.)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtSetInformationThread(NtCurrentThread(), ThreadHideFromDebugger, NULL, 0);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtTerminateProcess(hProcess, DBG_TERMINATE_PROCESS);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedError(rcNt, true /*fFatal*/, "NtSetInformationThread/ThreadHideFromDebugger failed: %#x\n", rcNt);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#endif
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Clean up the process.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = supR3HardenedWinPurifyChild(hProcess, hThread, RTErrInfoInitStatic(&g_ErrInfoStatic));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync NtTerminateProcess(hProcess, DBG_TERMINATE_PROCESS);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync supR3HardenedError(rc, true /*fFatal*/, "%s", g_ErrInfoStatic.szMsg);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync }
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Start the process execution.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync ULONG cSuspendCount = 0;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtResumeThread(hThread, &cSuspendCount));
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Close the unrestricted access handles. Since we need to wait on the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * child process, we'll reopen the process with limited access before doing
9f997e760f610c92e3a365be21ead6972bc46130vboxsync * away with the process handle returned by CreateProcess.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtClose(hThread));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync PROCESS_BASIC_INFORMATION BasicInfo;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hProcWait;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync ULONG fRights = SYNCHRONIZE;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)) /* Introduced in Vista. */
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync fRights |= PROCESS_QUERY_LIMITED_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync else
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync fRights |= PROCESS_QUERY_INFORMATION;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtDuplicateObject(NtCurrentProcess(), hProcess,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync NtCurrentProcess(), &hProcWait,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync fRights, 0 /*HandleAttributes*/, 0);
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (rcNt == STATUS_ACCESS_DENIED)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtDuplicateObject(NtCurrentProcess(), hProcess,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync NtCurrentProcess(), &hProcWait,
edde275acba04aca58db4172a163741e3abadfbcvboxsync SYNCHRONIZE, 0 /*HandleAttributes*/, 0);
edde275acba04aca58db4172a163741e3abadfbcvboxsync if (!NT_SUCCESS(rcNt))
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync /* Failure is unacceptable, kill the process. */
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtTerminateProcess(hProcess, RTEXITCODE_FAILURE);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync supR3HardenedError(rcNt, false /*fFatal*/, "NtDuplicateObject failed on child process handle: %#x\n", rcNt);
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNtExit = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
edde275acba04aca58db4172a163741e3abadfbcvboxsync bool fExitOk = NT_SUCCESS(rcNtExit) && BasicInfo.ExitStatus != STATUS_PENDING;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!fExitOk)
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNtWait;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync DWORD dwStartTick = GetTickCount();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync do
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtTerminateProcess(hProcess, DBG_TERMINATE_PROCESS);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync LARGE_INTEGER Timeout;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Timeout.QuadPart = -20000000; /* 2 second */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNtWait = NtWaitForSingleObject(hProcess, TRUE /*Alertable*/, &Timeout);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNtExit = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fExitOk = NT_SUCCESS(rcNtExit) && BasicInfo.ExitStatus != STATUS_PENDING;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync } while ( !fExitOk
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && ( rcNtWait == STATUS_TIMEOUT
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync || rcNtWait == STATUS_USER_APC
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync || rcNtWait == STATUS_ALERTED)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && GetTickCount() - dwStartTick < 60 * 1000);
a505d18eaecf5f7faff58cc7c05397f8adaf6d71vboxsync if (fExitOk)
0aab9cd857ec35928a0e61c68d3f27a5b4d88a95vboxsync supR3HardenedError(rcNt, false /*fFatal*/,
0aab9cd857ec35928a0e61c68d3f27a5b4d88a95vboxsync "NtDuplicateObject failed and we failed to kill child: rcNt=%u rcNtWait=%u hProcess=%p\n",
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNt, rcNtWait, hProcess);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync }
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, VERR_INVALID_NAME,
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync "NtDuplicateObject failed on child process handle: %#x\n", rcNt);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(NtClose(hProcess));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync hProcess = NULL;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync * Ditch the loader cache so we don't sit on too much memory while waiting.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinFlushLoaderCache();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync HeapCompact(GetProcessHeap(), 0 /*dwFlags*/);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Enable thread creation at this point so Ctrl-C and Ctrl-Break can be processed.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinEnableThreadCreation();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * If this is the middle process, wait for both parent and child to quit.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync HANDLE hParent = NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (iWhich > 1)
30f07af559efcbd967e801903746fc21f81ee533vboxsync {
8302394f164acb4adb187954f6ac8ef7a9efa629vboxsync rcNt = NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (NT_SUCCESS(rcNt))
b2560fc359a998cb1002e5de6eba0ef716d48803vboxsync {
b2560fc359a998cb1002e5de6eba0ef716d48803vboxsync OBJECT_ATTRIBUTES ObjAttr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync InitializeObjectAttributes(&ObjAttr, NULL, 0, NULL /*hRootDir*/, NULL /*pSecDesc*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync CLIENT_ID ClientId;
edde275acba04aca58db4172a163741e3abadfbcvboxsync ClientId.UniqueProcess = (HANDLE)BasicInfo.InheritedFromUniqueProcessId;
edde275acba04aca58db4172a163741e3abadfbcvboxsync ClientId.UniqueThread = NULL;
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync rcNt = NtOpenProcess(&hParent, SYNCHRONIZE | PROCESS_QUERY_INFORMATION, &ObjAttr, &ClientId);
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync#ifdef DEBUG
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(rcNt);
edde275acba04aca58db4172a163741e3abadfbcvboxsync#endif
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync if (hParent != NULL)
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync for (;;)
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync HANDLE ahHandles[2] = { hProcWait, hParent };
edde275acba04aca58db4172a163741e3abadfbcvboxsync rcNt = NtWaitForMultipleObjects(2, &ahHandles[0], WaitAnyObject, TRUE /*Alertable*/, NULL /*pTimeout*/);
edde275acba04aca58db4172a163741e3abadfbcvboxsync if ( rcNt == STATUS_WAIT_0
edde275acba04aca58db4172a163741e3abadfbcvboxsync || rcNt == STATUS_WAIT_0 + 1
edde275acba04aca58db4172a163741e3abadfbcvboxsync || rcNt == STATUS_ABANDONED_WAIT_0
edde275acba04aca58db4172a163741e3abadfbcvboxsync || rcNt == STATUS_ABANDONED_WAIT_0 + 1)
edde275acba04aca58db4172a163741e3abadfbcvboxsync break;
edde275acba04aca58db4172a163741e3abadfbcvboxsync if ( rcNt != STATUS_TIMEOUT
edde275acba04aca58db4172a163741e3abadfbcvboxsync && rcNt != STATUS_USER_APC
edde275acba04aca58db4172a163741e3abadfbcvboxsync && rcNt != STATUS_ALERTED)
edde275acba04aca58db4172a163741e3abadfbcvboxsync supR3HardenedFatal("NtWaitForMultipleObjects returned %#x\n", rcNt);
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtClose(hParent);
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync else
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Wait for the process to terminate.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync for (;;)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync {
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync rcNt = NtWaitForSingleObject(hProcWait, TRUE /*Alertable*/, NULL /*pTimeout*/);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if ( rcNt == STATUS_WAIT_0
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync || rcNt == STATUS_ABANDONED_WAIT_0)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync break;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if ( rcNt != STATUS_TIMEOUT
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync && rcNt != STATUS_USER_APC
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync && rcNt != STATUS_ALERTED)
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync supR3HardenedFatal("NtWaitForSingleObject returned %#x\n", rcNt);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync }
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Proxy the termination code of the child, if it exited already.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNt2 = NtQueryInformationProcess(hProcWait, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
b2560fc359a998cb1002e5de6eba0ef716d48803vboxsync if ( !NT_SUCCESS(rcNt2)
b2560fc359a998cb1002e5de6eba0ef716d48803vboxsync || BasicInfo.ExitStatus == STATUS_PENDING)
edde275acba04aca58db4172a163741e3abadfbcvboxsync BasicInfo.ExitStatus = RTEXITCODE_FAILURE;
edde275acba04aca58db4172a163741e3abadfbcvboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtClose(hProcWait);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinDoReSpawn(%d): Quitting: ExitCode=%#x rcNt=%#x\n", iWhich, BasicInfo.ExitStatus, rcNt));
edde275acba04aca58db4172a163741e3abadfbcvboxsync suplibHardenedExit((RTEXITCODE)BasicInfo.ExitStatus);
edde275acba04aca58db4172a163741e3abadfbcvboxsync}
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync/**
09af8164395ce22610792b5097e2b6ba3a63ac78vboxsync * Logs the content of the given object directory.
09af8164395ce22610792b5097e2b6ba3a63ac78vboxsync *
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync * @returns true if it exists, false if not.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * @param pszDir The path of the directory to log (ASCII).
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync */
09af8164395ce22610792b5097e2b6ba3a63ac78vboxsyncstatic void supR3HardenedWinLogObjDir(const char *pszDir)
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync{
b2560fc359a998cb1002e5de6eba0ef716d48803vboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Open the driver object directory.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync RTUTF16 wszDir[128];
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync int rc = RTUtf16CopyAscii(wszDir, RT_ELEMENTS(wszDir), pszDir);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (RT_FAILURE(rc))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinLogObjDir: RTUtf16CopyAscii -> %Rrc on '%s'\n", rc, pszDir));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync return;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync UNICODE_STRING NtDirName;
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtDirName.Buffer = (WCHAR *)wszDir;
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtDirName.Length = (USHORT)(RTUtf16Len(wszDir) * sizeof(WCHAR));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtDirName.MaximumLength = NtDirName.Length + sizeof(WCHAR);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync OBJECT_ATTRIBUTES ObjAttr;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync InitializeObjectAttributes(&ObjAttr, &NtDirName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync HANDLE hDir;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NTSTATUS rcNt = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY | FILE_LIST_DIRECTORY, &ObjAttr);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync SUP_DPRINTF(("supR3HardenedWinLogObjDir: %ls => %#x\n", wszDir, rcNt));
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync if (!NT_SUCCESS(rcNt))
edde275acba04aca58db4172a163741e3abadfbcvboxsync return;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Enumerate it, looking for the driver.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ULONG uObjDirCtx = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync for (;;)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t abBuffer[_64K + _1K];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ULONG cbActual;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync rcNt = NtQueryDirectoryObject(hDir,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync abBuffer,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync sizeof(abBuffer) - 4, /* minus four for string terminator space. */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FALSE /*ReturnSingleEntry */,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync FALSE /*RestartScan*/,
9f997e760f610c92e3a365be21ead6972bc46130vboxsync &uObjDirCtx,
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync &cbActual);
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (!NT_SUCCESS(rcNt) || cbActual < sizeof(OBJECT_DIRECTORY_INFORMATION))
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync {
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync SUP_DPRINTF(("supR3HardenedWinLogObjDir: NtQueryDirectoryObject => rcNt=%#x cbActual=%#x\n", rcNt, cbActual));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync break;
bfc39c8324b2a90c8cb3fedf883495d1ed92e724vboxsync }
bfc39c8324b2a90c8cb3fedf883495d1ed92e724vboxsync
bfc39c8324b2a90c8cb3fedf883495d1ed92e724vboxsync POBJECT_DIRECTORY_INFORMATION pObjDir = (POBJECT_DIRECTORY_INFORMATION)abBuffer;
bfc39c8324b2a90c8cb3fedf883495d1ed92e724vboxsync while (pObjDir->Name.Length != 0)
79a6b20f984859d9cc49305172355d6c3901f1c5vboxsync {
bfc39c8324b2a90c8cb3fedf883495d1ed92e724vboxsync WCHAR wcSaved = pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)];
71e448b6623e801f76cb68355a28500169de5695vboxsync SUP_DPRINTF((" %.*ls %.*ls\n",
71e448b6623e801f76cb68355a28500169de5695vboxsync pObjDir->TypeName.Length / sizeof(WCHAR), pObjDir->TypeName.Buffer,
71e448b6623e801f76cb68355a28500169de5695vboxsync pObjDir->Name.Length / sizeof(WCHAR), pObjDir->Name.Buffer));
71e448b6623e801f76cb68355a28500169de5695vboxsync
71e448b6623e801f76cb68355a28500169de5695vboxsync /* Next directory entry. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pObjDir++;
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Clean up and return.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync */
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync NtClose(hDir);
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync}
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync/**
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync * Checks if the driver exists.
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync *
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * This checks whether the driver is present in the /Driver object directory.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Drivers being initialized or terminated will have an object there
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * before/after their devices nodes are created/deleted.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @returns true if it exists, false if not.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @param pszDriver The driver name.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsyncstatic bool supR3HardenedWinDriverExists(const char *pszDriver)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync{
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Open the driver object directory.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync UNICODE_STRING NtDirName = RTNT_CONSTANT_UNISTR(L"\\Driver");
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync OBJECT_ATTRIBUTES ObjAttr;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync InitializeObjectAttributes(&ObjAttr, &NtDirName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync HANDLE hDir;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync NTSTATUS rcNt = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY | FILE_LIST_DIRECTORY, &ObjAttr);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync#ifdef VBOX_STRICT
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(rcNt);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync#endif
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (!NT_SUCCESS(rcNt))
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync return true;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Enumerate it, looking for the driver.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync bool fFound = true;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync ULONG uObjDirCtx = 0;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync do
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync {
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync uint32_t abBuffer[_64K + _1K];
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync ULONG cbActual;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync rcNt = NtQueryDirectoryObject(hDir,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync abBuffer,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync sizeof(abBuffer) - 4, /* minus four for string terminator space. */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync FALSE /*ReturnSingleEntry */,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync FALSE /*RestartScan*/,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync &uObjDirCtx,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync &cbActual);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (!NT_SUCCESS(rcNt) || cbActual < sizeof(OBJECT_DIRECTORY_INFORMATION))
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync break;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync POBJECT_DIRECTORY_INFORMATION pObjDir = (POBJECT_DIRECTORY_INFORMATION)abBuffer;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync while (pObjDir->Name.Length != 0)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync {
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync WCHAR wcSaved = pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)];
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)] = '\0';
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if ( pObjDir->Name.Length > 1
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync && RTUtf16ICmpAscii(pObjDir->Name.Buffer, pszDriver) == 0)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync {
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync fFound = true;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync break;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync }
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)] = wcSaved;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /* Next directory entry. */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync pObjDir++;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync }
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync } while (!fFound);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Clean up and return.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync NtClose(hDir);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync return fFound;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync}
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync/**
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Open the stub device before the 2nd respawn.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsyncstatic void supR3HardenedWinOpenStubDevice(void)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync{
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Retry if we think driver might still be initializing (STATUS_NO_SUCH_DEVICE + \Drivers\VBoxDrv).
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync static const WCHAR s_wszName[] = L"\\Device\\VBoxDrvStub";
edde275acba04aca58db4172a163741e3abadfbcvboxsync DWORD const uStartTick = GetTickCount();
edde275acba04aca58db4172a163741e3abadfbcvboxsync NTSTATUS rcNt;
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint32_t iTry;
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync for (iTry = 0;; iTry++)
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
edde275acba04aca58db4172a163741e3abadfbcvboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync UNICODE_STRING NtName;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NtName.Buffer = (PWSTR)s_wszName;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NtName.Length = sizeof(s_wszName) - sizeof(WCHAR);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NtName.MaximumLength = sizeof(s_wszName);
eca3ddadc12f677ac68395c5eab914d41fc8963avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync OBJECT_ATTRIBUTES ObjAttr;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync rcNt = NtCreateFile(&hFile,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync GENERIC_READ | GENERIC_WRITE,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync &ObjAttr,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync &Ios,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NULL /* Allocation Size*/,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync FILE_ATTRIBUTE_NORMAL,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync FILE_OPEN,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync FILE_NON_DIRECTORY_FILE,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NULL /*EaBuffer*/,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync 0 /*EaLength*/);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (NT_SUCCESS(rcNt))
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync rcNt = Ios.Status;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /* The STATUS_NO_SUCH_DEVICE might be returned if the device is not
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync completely initialized. Delay a little bit and try again. */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (rcNt != STATUS_NO_SUCH_DEVICE)
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (iTry > 0 && GetTickCount() - uStartTick > 5000) /* 5 sec, at least two tries */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (!supR3HardenedWinDriverExists("VBoxDrv"))
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /** @todo Consider starting the VBoxdrv.sys service. Requires 2nd process
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * though, rather complicated actually as CreateProcess causes all
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * kind of things to happen to this process which would make it hard to
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * pass the process verification tests... :-/ */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync }
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync LARGE_INTEGER Time;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (iTry < 8)
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync Time.QuadPart = -1000000 / 100; /* 1ms in 100ns units, relative time. */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync else
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync Time.QuadPart = -32000000 / 100; /* 32ms in 100ns units, relative time. */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync NtDelayExecution(TRUE, &Time);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync }
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (!NT_SUCCESS(rcNt))
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /*
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * Report trouble (fatal). For some errors codes we try gather some
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * extra information that goes into VBoxStartup.log so that we stand a
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * better chance resolving the issue.
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync int rc = VERR_OPEN_FAILED;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync rc = SUP_NT_STATUS_TO_VBOX(rcNt);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /*
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * \Windows\ApiPort open trouble. So far only
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * STATUS_OBJECT_TYPE_MISMATCH has been observed.
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (rc == VERR_SUPDRV_APIPORT_OPEN_ERROR)
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF(("Error opening VBoxDrvStub: VERR_SUPDRV_APIPORT_OPEN_ERROR\n"));
edde275acba04aca58db4172a163741e3abadfbcvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t uSessionId = NtCurrentPeb()->SessionId;
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUP_DPRINTF((" SessionID=%#x\n", uSessionId));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync char szDir[64];
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync if (uSessionId == 0)
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync RTStrCopy(szDir, sizeof(szDir), "\\Windows");
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync RTStrPrintf(szDir, sizeof(szDir), "\\Sessions\\%u\\Windows", uSessionId);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinLogObjDir(szDir);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync supR3HardenedWinLogObjDir("\\Windows");
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync supR3HardenedWinLogObjDir("\\Sessions");
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, rc,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "NtCreateFile(%ls) failed: VERR_SUPDRV_APIPORT_OPEN_ERROR\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "Error getting %s\\ApiPort in the driver from vboxdrv.\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "Could be due to security software is redirecting access to it, so please include full "
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "details of such software in a bug report. VBoxStartup.log may contain details important "
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "to resolving the issue."
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync , s_wszName, szDir);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync }
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /*
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * Generic VBox failure message.
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, rc,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "NtCreateFile(%ls) failed: %Rrc (rcNt=%#x)\n", s_wszName, rc, rcNt);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync }
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync else
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync const char *pszDefine;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync switch (rcNt)
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync case STATUS_NO_SUCH_DEVICE: pszDefine = " STATUS_NO_SUCH_DEVICE"; break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync case STATUS_OBJECT_NAME_NOT_FOUND: pszDefine = " STATUS_OBJECT_NAME_NOT_FOUND"; break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync case STATUS_ACCESS_DENIED: pszDefine = " STATUS_ACCESS_DENIED"; break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync case STATUS_TRUST_FAILURE: pszDefine = " STATUS_TRUST_FAILURE"; break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync default: pszDefine = ""; break;
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync }
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync /*
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * Problems opening the device is generally due to driver load/
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * unload issues. Check whether the driver is loaded and make
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * suggestions accordingly.
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync */
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if ( rcNt == STATUS_NO_SUCH_DEVICE
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync || rcNt == STATUS_OBJECT_NAME_NOT_FOUND)
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync {
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync SUP_DPRINTF(("Error opening VBoxDrvStub: %s\n", pszDefine));
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync if (supR3HardenedWinDriverExists("VBoxDrv"))
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, VERR_OPEN_FAILED,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "NtCreateFile(%ls) failed: %#x%s (%u retries)\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "Driver is probably stuck stopping/starting. Try 'sc.exe query vboxdrv' to get more "
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "information about its state. Rebooting may actually help.\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync , s_wszName, rcNt, pszDefine, iTry);
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync else
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, VERR_OPEN_FAILED,
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "NtCreateFile(%ls) failed: %#x%s (%u retries)\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "Driver is does not appear to be loaded. Try 'sc.exe start vboxdrv', reinstall "
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync "VirtualBox or reboot.\n"
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync , s_wszName, rcNt, pszDefine, iTry);
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync }
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync /* Generic NT failure message. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, VERR_OPEN_FAILED,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync "NtCreateFile(%ls) failed: %#x%s (%u retries)\n", s_wszName, rcNt, pszDefine, iTry);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync }
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync }
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync}
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
40839c441cb305d84420565f7ca25403d8177413vboxsync
40839c441cb305d84420565f7ca25403d8177413vboxsync/**
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Called by the main code if supR3HardenedWinIsReSpawnNeeded returns @c true.
40839c441cb305d84420565f7ca25403d8177413vboxsync *
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @returns Program exit code.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsyncDECLHIDDEN(int) supR3HardenedWinReSpawn(int iWhich)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync{
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Before the 2nd respawn we set up a child protection deal with the
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * support driver via /Devices/VBoxDrvStub.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (iWhich == 2)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync supR3HardenedWinOpenStubDevice();
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Respawn the process with kernel protection for the new process.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync return supR3HardenedWinDoReSpawn(iWhich);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync}
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync/**
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Checks if re-spawning is required, replacing the respawn argument if not.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync *
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @returns true if required, false if not. In the latter case, the first
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * argument in the vector is replaced.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @param iWhich Which respawn we're to check for, 1 being the
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * first one, and 2 the second and final.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @param cArgs The number of arguments.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @param papszArgs Pointer to the argument vector.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsyncDECLHIDDEN(bool) supR3HardenedWinIsReSpawnNeeded(int iWhich, int cArgs, char **papszArgs)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync{
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync SUPR3HARDENED_ASSERT(g_cSuplibHardenedWindowsMainCalls == 1);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync SUPR3HARDENED_ASSERT(iWhich == 1 || iWhich == 2);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (cArgs < 1)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync return true;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (suplibHardenedStrCmp(papszArgs[0], SUPR3_RESPAWN_1_ARG0) == 0)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (iWhich > 1)
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync return true;
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync }
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync else if (suplibHardenedStrCmp(papszArgs[0], SUPR3_RESPAWN_2_ARG0) == 0)
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync {
485f31dd3495c289f625c9c5b900cf0b95838ed6vboxsync if (iWhich < 2)
485f31dd3495c289f625c9c5b900cf0b95838ed6vboxsync return false;
485f31dd3495c289f625c9c5b900cf0b95838ed6vboxsync }
485f31dd3495c289f625c9c5b900cf0b95838ed6vboxsync else
485f31dd3495c289f625c9c5b900cf0b95838ed6vboxsync return true;
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /* Replace the argument. */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync papszArgs[0] = g_szSupLibHardenedExePath;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync return false;
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync}
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync/**
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Initializes the windows verficiation bits.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * @param fFlags The main flags.
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync */
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsyncDECLHIDDEN(void) supR3HardenedWinInit(uint32_t fFlags)
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync{
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync RTErrInfoInitStatic(&g_ErrInfoStatic);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync int rc = supHardenedWinInitImageVerifier(&g_ErrInfoStatic.Core);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (RT_FAILURE(rc))
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync supR3HardenedFatalMsg("supR3HardenedWinInit", kSupInitOp_Misc, rc,
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync "supHardenedWinInitImageVerifier failed: %s", g_ErrInfoStatic.szMsg);
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync if (!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV))
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync {
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync /*
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * Do a self purification to cure avast's weird NtOpenFile write-thru
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * change in GetBinaryTypeW change in kernel32. Unfortunately, avast
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * uses a system thread to perform the process modifications, which
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * means it's hard to make sure it had the chance to make them...
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync *
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * We have to resort to kludge doing yield and sleep fudging for a
681f9c8332e6b5a57c59e898d1edcc150423223dvboxsync * number of milliseconds and schedulings before we can hope that avast
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * and similar products have done what they need to do. If we do any
4221c34ed2180fbc3a82504145c4a66c589e9e6avboxsync * fixes, we wait for a while again and redo it until we're clean.
b4ac1123bab63c58a3323bc1eb96dc7fde868aafvboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This is unfortunately kind of fragile.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint32_t cMsFudge = g_fSupAdversaries ? 512 : 128;
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint32_t cFixes;
edde275acba04aca58db4172a163741e3abadfbcvboxsync for (uint32_t iLoop = 0; iLoop < 16; iLoop++)
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync uint32_t cSleeps = 0;
edde275acba04aca58db4172a163741e3abadfbcvboxsync DWORD dwStart = GetTickCount();
edde275acba04aca58db4172a163741e3abadfbcvboxsync do
edde275acba04aca58db4172a163741e3abadfbcvboxsync {
edde275acba04aca58db4172a163741e3abadfbcvboxsync NtYieldExecution();
edde275acba04aca58db4172a163741e3abadfbcvboxsync LARGE_INTEGER Time;
edde275acba04aca58db4172a163741e3abadfbcvboxsync Time.QuadPart = -8000000 / 100; /* 8ms in 100ns units, relative time. */
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync NtDelayExecution(FALSE, &Time);
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync cSleeps++;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync } while ( GetTickCount() - dwStart <= cMsFudge
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync || cSleeps < 8);
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUP_DPRINTF(("supR3HardenedWinInit: Startup delay kludge #2/%u: %u ms, %u sleeps\n",
edde275acba04aca58db4172a163741e3abadfbcvboxsync iLoop, GetTickCount() - dwStart, cSleeps));
edde275acba04aca58db4172a163741e3abadfbcvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cFixes = 0;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_SELF_PURIFICATION,
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync &cFixes, NULL /*pErrInfo*/);
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync if (RT_FAILURE(rc) || cFixes == 0)
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync break;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync if (!g_fSupAdversaries)
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync g_fSupAdversaries |= SUPHARDNT_ADVERSARY_UNKNOWN;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync cMsFudge = 512;
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync SUP_DPRINTF(("supR3HardenedWinInit: cFixes=%u g_fSupAdversaries=%#x\n", cFixes, g_fSupAdversaries));
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync }
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync /*
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync * Install the hooks.
5b6c1ebab7273734a475e2e3b850b16ccbdf788cvboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedWinInstallHooks();
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync#ifndef VBOX_WITH_VISTA_NO_SP
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync /*
f20463d06f9bf3f81e2c049c697dcd20a0b0c435vboxsync * Complain about Vista w/o service pack if we're launching a VM.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( !(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && g_uNtVerCombined >= SUP_NT_VER_VISTA
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && g_uNtVerCombined < SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync supR3HardenedFatalMsg("supR3HardenedWinInit", kSupInitOp_Misc, VERR_NOT_SUPPORTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "Window Vista without any service pack installed is not supported. Please install the latest service pack.");
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Converts the Windows command line string (UTF-16) to an array of UTF-8
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * arguments suitable for passing to main().
edde275acba04aca58db4172a163741e3abadfbcvboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns Pointer to the argument array.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pawcCmdLine The UTF-16 windows command line to parse.
edde275acba04aca58db4172a163741e3abadfbcvboxsync * @param cwcCmdLine The length of the command line.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pcArgs Where to return the number of arguments.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic char **suplibCommandLineToArgvWStub(PCRTUTF16 pawcCmdLine, size_t cwcCmdLine, int *pcArgs)
edde275acba04aca58db4172a163741e3abadfbcvboxsync{
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Convert the command line string to UTF-8.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync char *pszCmdLine = NULL;
edde275acba04aca58db4172a163741e3abadfbcvboxsync SUPR3HARDENED_ASSERT(RT_SUCCESS(RTUtf16ToUtf8Ex(pawcCmdLine, cwcCmdLine, &pszCmdLine, 0, NULL)));
edde275acba04aca58db4172a163741e3abadfbcvboxsync
edde275acba04aca58db4172a163741e3abadfbcvboxsync /*
edde275acba04aca58db4172a163741e3abadfbcvboxsync * Parse the command line, carving argument strings out of it.
edde275acba04aca58db4172a163741e3abadfbcvboxsync */
edde275acba04aca58db4172a163741e3abadfbcvboxsync int cArgs = 0;
edde275acba04aca58db4172a163741e3abadfbcvboxsync int cArgsAllocated = 4;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync char **papszArgs = (char **)suplibHardenedAllocZ(sizeof(char *) * cArgsAllocated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync char *pszSrc = pszCmdLine;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync for (;;)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* skip leading blanks. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync char ch = *pszSrc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (suplibCommandLineIsArgSeparator(ch))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ch = *++pszSrc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!ch)
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync break;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /* Add argument to the vector. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cArgs + 2 >= cArgsAllocated)
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cArgsAllocated *= 2;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync papszArgs = (char **)suplibHardenedReAlloc(papszArgs, sizeof(char *) * cArgsAllocated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
96d40ac897d5f0fd08ee7112800b4beab249179evboxsync papszArgs[cArgs++] = pszSrc;
96d40ac897d5f0fd08ee7112800b4beab249179evboxsync papszArgs[cArgs] = NULL;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync /* Unquote and unescape the string. */
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync char *pszDst = pszSrc++;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync bool fQuoted = false;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync do
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync if (ch == '"')
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync fQuoted = !fQuoted;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync else if (ch != '\\' || (*pszSrc != '\\' && *pszSrc != '"'))
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync *pszDst++ = ch;
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync else
46b9d3cd08a855c5d0e968e4fff0e89dea3fc2dfvboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync unsigned cSlashes = 0;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync while ((ch = *pszSrc++) == '\\')
9f997e760f610c92e3a365be21ead6972bc46130vboxsync cSlashes++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (ch == '"')
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cSlashes >= 2)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cSlashes -= 2;
693b87e00c4a89605b2f8d8ab443414186aeaa06vboxsync *pszDst++ = '\\';
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (cSlashes)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync *pszDst++ = '"';
9f997e760f610c92e3a365be21ead6972bc46130vboxsync else
9f997e760f610c92e3a365be21ead6972bc46130vboxsync fQuoted = !fQuoted;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync else
96d40ac897d5f0fd08ee7112800b4beab249179evboxsync {
9f997e760f610c92e3a365be21ead6972bc46130vboxsync pszSrc--;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync while (cSlashes-- > 0)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync *pszDst++ = '\\';
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync ch = *pszSrc++;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync } while (ch != '\0' && (fQuoted || !suplibCommandLineIsArgSeparator(ch)));
9f997e760f610c92e3a365be21ead6972bc46130vboxsync
9f997e760f610c92e3a365be21ead6972bc46130vboxsync /* Terminate the argument. */
9f997e760f610c92e3a365be21ead6972bc46130vboxsync *pszDst = '\0';
9f997e760f610c92e3a365be21ead6972bc46130vboxsync if (!ch)
9f997e760f610c92e3a365be21ead6972bc46130vboxsync break;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync }
693b87e00c4a89605b2f8d8ab443414186aeaa06vboxsync
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync *pcArgs = cArgs;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync return papszArgs;
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync}
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync/**
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * Logs information about a file from a protection product.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync *
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * The purpose here is to better see which version of the product is installed
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * and not needing to depend on the user supplying the correct information.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync *
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * @param pwszFile The NT path to the file.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsyncstatic void supR3HardenedLogAdversarialFile(PCRTUTF16 pwszFile)
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync{
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync /*
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync * Open the file.
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync */
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
e352c25b01398e5503235fed02436cb2992f1021vboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync UNICODE_STRING UniStrName;
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync UniStrName.Buffer = (WCHAR *)pwszFile;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync UniStrName.Length = (USHORT)(RTUtf16Len(pwszFile) * sizeof(WCHAR));
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync UniStrName.MaximumLength = UniStrName.Length + sizeof(WCHAR);
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync OBJECT_ATTRIBUTES ObjAttr;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync InitializeObjectAttributes(&ObjAttr, &UniStrName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync NTSTATUS rcNt = NtCreateFile(&hFile,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync GENERIC_READ,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync &ObjAttr,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync &Ios,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync NULL /* Allocation Size*/,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync FILE_ATTRIBUTE_NORMAL,
4db69c2a1302fa56bc5dd7181377b9f47cfd875evboxsync FILE_SHARE_READ,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync FILE_OPEN,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync FILE_NON_DIRECTORY_FILE,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync NULL /*EaBuffer*/,
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync 0 /*EaLength*/);
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync if (NT_SUCCESS(rcNt))
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync rcNt = Ios.Status;
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync if (NT_SUCCESS(rcNt))
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync {
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync SUP_DPRINTF(("%ls:\n", pwszFile));
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync union
85f99ad10a7b126cf312171061d363fe56302bdavboxsync {
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync uint64_t u64AlignmentInsurance;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync FILE_BASIC_INFORMATION BasicInfo;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync FILE_STANDARD_INFORMATION StdInfo;
9f997e760f610c92e3a365be21ead6972bc46130vboxsync uint8_t abBuf[32768];
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync RTUTF16 awcBuf[16384];
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync IMAGE_DOS_HEADER MzHdr;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync } u;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync RTTIMESPEC TimeSpec;
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync char szTmp[64];
0c2ffca957882f38c677fc23f324cfd695b96947vboxsync
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync /*
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync * Print basic file information available via NtQueryInformationFile.
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync */
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
5de281ea9954eecffbd1ba604603cc8e8347e700vboxsync rcNt = NtQueryInformationFile(hFile, &Ios, &u.BasicInfo, sizeof(u.BasicInfo), FileBasicInformation);
693b87e00c4a89605b2f8d8ab443414186aeaa06vboxsync if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
7d6ce198fd361f58bd1ebdeee7772f76b4e58966vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" CreationTime: %s\n", RTTimeSpecToString(RTTimeSpecSetNtTime(&TimeSpec, u.BasicInfo.CreationTime.QuadPart), szTmp, sizeof(szTmp))));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*SUP_DPRINTF((" LastAccessTime: %s\n", RTTimeSpecToString(RTTimeSpecSetNtTime(&TimeSpec, u.BasicInfo.LastAccessTime.QuadPart), szTmp, sizeof(szTmp))));*/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" LastWriteTime: %s\n", RTTimeSpecToString(RTTimeSpecSetNtTime(&TimeSpec, u.BasicInfo.LastWriteTime.QuadPart), szTmp, sizeof(szTmp))));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" ChangeTime: %s\n", RTTimeSpecToString(RTTimeSpecSetNtTime(&TimeSpec, u.BasicInfo.ChangeTime.QuadPart), szTmp, sizeof(szTmp))));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" FileAttributes: %#x\n", u.BasicInfo.FileAttributes));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" FileBasicInformation -> %#x %#x\n", rcNt, Ios.Status));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNt = NtQueryInformationFile(hFile, &Ios, &u.StdInfo, sizeof(u.StdInfo), FileStandardInformation);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" Size: %#llx\n", u.StdInfo.EndOfFile.QuadPart));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" FileStandardInformation -> %#x %#x\n", rcNt, Ios.Status));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Read the image header and extract the timestamp and other useful info.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(u);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync LARGE_INTEGER offRead;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync offRead.QuadPart = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNt = NtReadFile(hFile, NULL /*hEvent*/, NULL /*ApcRoutine*/, NULL /*ApcContext*/, &Ios,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync &u, (ULONG)sizeof(u), &offRead, NULL);
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t offNtHdrs = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (u.MzHdr.e_magic == IMAGE_DOS_SIGNATURE)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync offNtHdrs = u.MzHdr.e_lfanew;
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync if (offNtHdrs < sizeof(u) - sizeof(IMAGE_NT_HEADERS))
3c520cf6887d9039d9aa7cf3bbe81fd7de1ffd4cvboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PIMAGE_NT_HEADERS64 pNtHdrs64 = (PIMAGE_NT_HEADERS64)&u.abBuf[offNtHdrs];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PIMAGE_NT_HEADERS32 pNtHdrs32 = (PIMAGE_NT_HEADERS32)&u.abBuf[offNtHdrs];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pNtHdrs64->Signature == IMAGE_NT_SIGNATURE)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" NT Headers: %#x\n", offNtHdrs));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" Timestamp: %#x\n", pNtHdrs64->FileHeader.TimeDateStamp));
30f07af559efcbd967e801903746fc21f81ee533vboxsync SUP_DPRINTF((" Machine: %#x%s\n", pNtHdrs64->FileHeader.Machine,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pNtHdrs64->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ? " - i386"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync : pNtHdrs64->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ? " - amd64" : ""));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" Timestamp: %#x\n", pNtHdrs64->FileHeader.TimeDateStamp));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" Image Version: %u.%u\n",
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pNtHdrs64->OptionalHeader.MajorImageVersion, pNtHdrs64->OptionalHeader.MinorImageVersion));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" SizeOfImage: %#x (%u)\n", pNtHdrs64->OptionalHeader.SizeOfImage, pNtHdrs64->OptionalHeader.SizeOfImage));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Very crude way to extract info from the file version resource.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PIMAGE_SECTION_HEADER paSectHdrs = (PIMAGE_SECTION_HEADER)( (uintptr_t)&pNtHdrs64->OptionalHeader
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync + pNtHdrs64->FileHeader.SizeOfOptionalHeader);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync IMAGE_DATA_DIRECTORY RsrcDir = { 0, 0 };
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pNtHdrs64->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64)
30f07af559efcbd967e801903746fc21f81ee533vboxsync && pNtHdrs64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RsrcDir = pNtHdrs64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if ( pNtHdrs64->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pNtHdrs32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RsrcDir = pNtHdrs32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync SUP_DPRINTF((" Resource Dir: %#x LB %#x\n", RsrcDir.VirtualAddress, RsrcDir.Size));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( RsrcDir.VirtualAddress > offNtHdrs
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && RsrcDir.Size > 0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && (uintptr_t)&u + sizeof(u) - (uintptr_t)paSectHdrs
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync >= pNtHdrs64->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER) )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync offRead.QuadPart = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync for (uint32_t i = 0; i < pNtHdrs64->FileHeader.NumberOfSections; i++)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( paSectHdrs[i].VirtualAddress - RsrcDir.VirtualAddress < paSectHdrs[i].SizeOfRawData
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && paSectHdrs[i].PointerToRawData > offNtHdrs)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync offRead.QuadPart = paSectHdrs[i].PointerToRawData
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync + (paSectHdrs[i].VirtualAddress - RsrcDir.VirtualAddress);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync break;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (offRead.QuadPart > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(u);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rcNt = NtReadFile(hFile, NULL /*hEvent*/, NULL /*ApcRoutine*/, NULL /*ApcContext*/, &Ios,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync &u, (ULONG)sizeof(u), &offRead, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync static const struct { PCRTUTF16 pwsz; size_t cb; } s_abFields[] =
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define MY_WIDE_STR_TUPLE(a_sz) { L ## a_sz, sizeof(L ## a_sz) - sizeof(RTUTF16) }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("ProductName"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("ProductVersion"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("FileVersion"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("SpecialBuild"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("PrivateBuild"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync MY_WIDE_STR_TUPLE("FileDescription"),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#undef MY_WIDE_STR_TUPLE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync };
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(s_abFields); i++)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync size_t cwcLeft = (sizeof(u) - s_abFields[i].cb - 10) / sizeof(RTUTF16);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTUTF16 pwc = u.awcBuf;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTUTF16 const wcFirst = *s_abFields[i].pwsz;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while (cwcLeft-- > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pwc[0] == 1 /* wType == text */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pwc[1] == wcFirst)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (memcmp(pwc + 1, s_abFields[i].pwsz, s_abFields[i].cb + sizeof(RTUTF16)) == 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync size_t cwcField = s_abFields[i].cb / sizeof(RTUTF16);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pwc += cwcField + 2;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cwcLeft -= cwcField + 2;
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (uint32_t iPadding = 0; iPadding < 3; iPadding++, pwc++, cwcLeft--)
85f99ad10a7b126cf312171061d363fe56302bdavboxsync if (*pwc)
100b161379af7255c69e27587cc746e5f76ff050vboxsync break;
100b161379af7255c69e27587cc746e5f76ff050vboxsync int rc = RTUtf16ValidateEncodingEx(pwc, cwcLeft,
100b161379af7255c69e27587cc746e5f76ff050vboxsync RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (RT_SUCCESS(rc))
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" %ls:%*s %ls",
85f99ad10a7b126cf312171061d363fe56302bdavboxsync s_abFields[i].pwsz, cwcField < 15 ? 15 - cwcField : 0, "", pwc));
85f99ad10a7b126cf312171061d363fe56302bdavboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" %ls:%*s rc=%Rrc",
85f99ad10a7b126cf312171061d363fe56302bdavboxsync s_abFields[i].pwsz, cwcField < 15 ? 15 - cwcField : 0, "", rc));
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync break;
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync pwc++;
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" NtReadFile @%#llx -> %#x %#x\n", offRead.QuadPart, rcNt, Ios.Status));
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" Resource section not found.\n"));
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" Nt Headers @%#x: Invalid signature\n", offNtHdrs));
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" Nt Headers @%#x: out side buffer\n", offNtHdrs));
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF((" NtReadFile @0 -> %#x %#x\n", rcNt, Ios.Status));
100b161379af7255c69e27587cc746e5f76ff050vboxsync NtClose(hFile);
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync}
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync/**
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Scans the Driver directory for drivers which may invade our processes.
100b161379af7255c69e27587cc746e5f76ff050vboxsync *
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @returns Mask of SUPHARDNT_ADVERSARY_XXX flags.
100b161379af7255c69e27587cc746e5f76ff050vboxsync *
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @remarks The enumeration of \Driver normally requires administrator
100b161379af7255c69e27587cc746e5f76ff050vboxsync * privileges. So, the detection we're doing here isn't always gonna
100b161379af7255c69e27587cc746e5f76ff050vboxsync * work just based on that.
100b161379af7255c69e27587cc746e5f76ff050vboxsync *
100b161379af7255c69e27587cc746e5f76ff050vboxsync * @todo Find drivers in \FileSystems as well, then we could detect VrNsdDrv
100b161379af7255c69e27587cc746e5f76ff050vboxsync * from ViRobot APT Shield 2.0.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsyncstatic uint32_t supR3HardenedWinFindAdversaries(void)
100b161379af7255c69e27587cc746e5f76ff050vboxsync{
100b161379af7255c69e27587cc746e5f76ff050vboxsync static const struct
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync uint32_t fAdversary;
100b161379af7255c69e27587cc746e5f76ff050vboxsync const char *pszDriver;
100b161379af7255c69e27587cc746e5f76ff050vboxsync } s_aDrivers[] =
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SRTSPX" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymDS" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymEvent" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymIRON" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymNetS" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswHwid" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswMonFlt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswRdr2" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswRvrt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswSnx" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswsp" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswStm" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, "aswVmm" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmcomm" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmactmon" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmevtmgr" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmtdi" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmebc64" }, /* Titanium internet security, not officescan. */
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmeevw" }, /* Titanium internet security, not officescan. */
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, "tmciesc" }, /* Titanium internet security, not officescan. */
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "cfwids" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "McPvDrv" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfeapfk" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfeavfk" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfefirek" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfehidk" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfencbdc" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, "mfewfpk" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "kl1" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "klflt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "klif" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "KLIM6" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "klkbdflt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "klmouflt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "kltdi" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, "kneps" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, "MBAMWebAccessControl" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, "mbam" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, "mbamchameleon" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, "mwav" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, "mbamswissarmy" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, "avgfwfd" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, "avgtdia" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINAflt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINFile" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINKNC" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINProc" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINProt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSINReg" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "PSKMAD" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSAlpc" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSHttp" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNShttps" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSIds" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSNAHSL" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSpicc" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSPihsw" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSPop3" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSProt" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSPrv" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSSmtp" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNSStrm" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, "NNStlsc" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MSE, "NisDrv" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*{ SUPHARDNT_ADVERSARY_COMODO, "cmdguard" }, file system */
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, "inspect" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, "cmdHlp" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync };
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync static const struct
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync uint32_t fAdversary;
100b161379af7255c69e27587cc746e5f76ff050vboxsync PCRTUTF16 pwszFile;
100b161379af7255c69e27587cc746e5f76ff050vboxsync } s_aFiles[] =
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\SysPlant.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\sysfer.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\sysferThunk.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\ccsetx64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\ironx64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\srtsp64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\srtspx64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\symds64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\symefa64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\symelam.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\symnets.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\symevent64x86.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswHwid.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswMonFlt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswRdr2.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswRvrt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswSnx.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswsp.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswStm.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVAST, L"\\SystemRoot\\System32\\drivers\\aswVmm.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmcomm.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmactmon.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmevtmgr.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmtdi.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmebc64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmeevw.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_TRENDMICRO, L"\\SystemRoot\\System32\\drivers\\tmciesc.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\cfwids.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\McPvDrv.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfeapfk.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfeavfk.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfefirek.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfehidk.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfencbdc.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MCAFEE, L"\\SystemRoot\\System32\\drivers\\mfewfpk.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\kl1.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\klflt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\klif.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\klim6.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\klkbdflt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\klmouflt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\kltdi.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\drivers\\kneps.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_KASPERSKY, L"\\SystemRoot\\System32\\klfphc.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, L"\\SystemRoot\\System32\\drivers\\MBAMSwissArmy.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, L"\\SystemRoot\\System32\\drivers\\mwac.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, L"\\SystemRoot\\System32\\drivers\\mbamchameleon.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MBAM, L"\\SystemRoot\\System32\\drivers\\mbam.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgrkx64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgmfx64.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgidsdrivera.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgidsha.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgtdia.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgloga.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgldx64.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_AVG, L"\\SystemRoot\\System32\\drivers\\avgdiska.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINAflt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINFile.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINKNC.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINProc.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINProt.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSINReg.sys" },
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\PSKMAD.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSAlpc.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSHttp.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNShttps.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSIds.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSNAHSL.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSpicc.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSPihsw.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSPop3.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSProt.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSPrv.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSSmtp.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNSStrm.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_PANDA, L"\\SystemRoot\\System32\\drivers\\NNStlsc.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MSE, L"\\SystemRoot\\System32\\drivers\\MpFilter.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_MSE, L"\\SystemRoot\\System32\\drivers\\NisDrvWFP.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\cmdguard.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\cmderd.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\inspect.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\cmdhlp.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\cfrmd.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\drivers\\hmd.sys" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\guard64.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\cmdvrt64.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\cmdkbd64.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync { SUPHARDNT_ADVERSARY_COMODO, L"\\SystemRoot\\System32\\cmdcsr.dll" },
100b161379af7255c69e27587cc746e5f76ff050vboxsync };
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync uint32_t fFound = 0;
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Open the driver object directory.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync UNICODE_STRING NtDirName = RTNT_CONSTANT_UNISTR(L"\\Driver");
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync OBJECT_ATTRIBUTES ObjAttr;
100b161379af7255c69e27587cc746e5f76ff050vboxsync InitializeObjectAttributes(&ObjAttr, &NtDirName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync HANDLE hDir;
100b161379af7255c69e27587cc746e5f76ff050vboxsync NTSTATUS rcNt = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY | FILE_LIST_DIRECTORY, &ObjAttr);
100b161379af7255c69e27587cc746e5f76ff050vboxsync#ifdef VBOX_STRICT
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUPR3HARDENED_ASSERT_NT_SUCCESS(rcNt);
100b161379af7255c69e27587cc746e5f76ff050vboxsync#endif
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (NT_SUCCESS(rcNt))
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Enumerate it, looking for the driver.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync ULONG uObjDirCtx = 0;
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (;;)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync uint32_t abBuffer[_64K + _1K];
100b161379af7255c69e27587cc746e5f76ff050vboxsync ULONG cbActual;
100b161379af7255c69e27587cc746e5f76ff050vboxsync rcNt = NtQueryDirectoryObject(hDir,
100b161379af7255c69e27587cc746e5f76ff050vboxsync abBuffer,
100b161379af7255c69e27587cc746e5f76ff050vboxsync sizeof(abBuffer) - 4, /* minus four for string terminator space. */
100b161379af7255c69e27587cc746e5f76ff050vboxsync FALSE /*ReturnSingleEntry */,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FALSE /*RestartScan*/,
100b161379af7255c69e27587cc746e5f76ff050vboxsync &uObjDirCtx,
100b161379af7255c69e27587cc746e5f76ff050vboxsync &cbActual);
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (!NT_SUCCESS(rcNt) || cbActual < sizeof(OBJECT_DIRECTORY_INFORMATION))
100b161379af7255c69e27587cc746e5f76ff050vboxsync break;
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync POBJECT_DIRECTORY_INFORMATION pObjDir = (POBJECT_DIRECTORY_INFORMATION)abBuffer;
100b161379af7255c69e27587cc746e5f76ff050vboxsync while (pObjDir->Name.Length != 0)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync WCHAR wcSaved = pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)];
100b161379af7255c69e27587cc746e5f76ff050vboxsync pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)] = '\0';
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(s_aDrivers); i++)
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (RTUtf16ICmpAscii(pObjDir->Name.Buffer, s_aDrivers[i].pszDriver) == 0)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync fFound |= s_aDrivers[i].fAdversary;
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF(("Found driver %s (%#x)\n", s_aDrivers[i].pszDriver, s_aDrivers[i].fAdversary));
100b161379af7255c69e27587cc746e5f76ff050vboxsync break;
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync
a6c871653045073d6ef74d0589de345ae62b607dvboxsync pObjDir->Name.Buffer[pObjDir->Name.Length / sizeof(WCHAR)] = wcSaved;
a6c871653045073d6ef74d0589de345ae62b607dvboxsync
a6c871653045073d6ef74d0589de345ae62b607dvboxsync /* Next directory entry. */
a6c871653045073d6ef74d0589de345ae62b607dvboxsync pObjDir++;
a6c871653045073d6ef74d0589de345ae62b607dvboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync NtClose(hDir);
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync else
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF(("NtOpenDirectoryObject failed on \\Driver: %#x\n", rcNt));
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Look for files.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(s_aFiles); i++)
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
100b161379af7255c69e27587cc746e5f76ff050vboxsync IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
100b161379af7255c69e27587cc746e5f76ff050vboxsync UNICODE_STRING UniStrName;
100b161379af7255c69e27587cc746e5f76ff050vboxsync UniStrName.Buffer = (WCHAR *)s_aFiles[i].pwszFile;
100b161379af7255c69e27587cc746e5f76ff050vboxsync UniStrName.Length = (USHORT)(RTUtf16Len(s_aFiles[i].pwszFile) * sizeof(WCHAR));
100b161379af7255c69e27587cc746e5f76ff050vboxsync UniStrName.MaximumLength = UniStrName.Length + sizeof(WCHAR);
100b161379af7255c69e27587cc746e5f76ff050vboxsync InitializeObjectAttributes(&ObjAttr, &UniStrName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
100b161379af7255c69e27587cc746e5f76ff050vboxsync rcNt = NtCreateFile(&hFile, GENERIC_READ, &ObjAttr, &Ios, NULL /* Allocation Size*/, FILE_ATTRIBUTE_NORMAL,
100b161379af7255c69e27587cc746e5f76ff050vboxsync FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL /*EaBuffer*/, 0 /*EaLength*/);
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
100b161379af7255c69e27587cc746e5f76ff050vboxsync {
100b161379af7255c69e27587cc746e5f76ff050vboxsync fFound |= s_aFiles[i].fAdversary;
100b161379af7255c69e27587cc746e5f76ff050vboxsync NtClose(hFile);
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync }
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Log details.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF(("supR3HardenedWinFindAdversaries: %#x\n", fFound));
100b161379af7255c69e27587cc746e5f76ff050vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(s_aFiles); i++)
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (fFound & s_aFiles[i].fAdversary)
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedLogAdversarialFile(s_aFiles[i].pwszFile);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync return fFound;
100b161379af7255c69e27587cc746e5f76ff050vboxsync}
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsyncextern "C" int main(int argc, char **argv, char **envp);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync/**
100b161379af7255c69e27587cc746e5f76ff050vboxsync * The executable entry point.
100b161379af7255c69e27587cc746e5f76ff050vboxsync *
100b161379af7255c69e27587cc746e5f76ff050vboxsync * This is normally taken care of by the C runtime library, but we don't want to
100b161379af7255c69e27587cc746e5f76ff050vboxsync * get involved with anything as complicated like the CRT in this setup. So, we
100b161379af7255c69e27587cc746e5f76ff050vboxsync * it everything ourselves, including parameter parsing.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsyncextern "C" void __stdcall suplibHardenedWindowsMain(void)
100b161379af7255c69e27587cc746e5f76ff050vboxsync{
100b161379af7255c69e27587cc746e5f76ff050vboxsync RTEXITCODE rcExit = RTEXITCODE_FAILURE;
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync g_cSuplibHardenedWindowsMainCalls++;
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Initialize the NTDLL API wrappers. This aims at bypassing patched NTDLL
100b161379af7255c69e27587cc746e5f76ff050vboxsync * in all the processes leading up the VM process.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedWinInitImports();
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * After having resolved imports we patch the LdrInitializeThunk code so
100b161379af7255c69e27587cc746e5f76ff050vboxsync * that it's more difficult to invade our privacy by CreateRemoteThread.
100b161379af7255c69e27587cc746e5f76ff050vboxsync * We'll re-enable this after opening the driver or temporarily while respawning.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedWinDisableThreadCreation();
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Init g_uNtVerCombined. (The code is shared with SUPR3.lib and lives in
100b161379af7255c69e27587cc746e5f76ff050vboxsync * SUPHardenedVerfiyImage-win.cpp.)
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedWinInitVersion();
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Convert the arguments to UTF-8 and open the log file if specified.
100b161379af7255c69e27587cc746e5f76ff050vboxsync * This must be done as early as possible since the code below may fail.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync PUNICODE_STRING pCmdLineStr = &NtCurrentPeb()->ProcessParameters->CommandLine;
100b161379af7255c69e27587cc746e5f76ff050vboxsync int cArgs;
100b161379af7255c69e27587cc746e5f76ff050vboxsync char **papszArgs = suplibCommandLineToArgvWStub(pCmdLineStr->Buffer, pCmdLineStr->Length / sizeof(WCHAR), &cArgs);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedOpenLog(&cArgs, papszArgs);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Scan the system for adversaries.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync g_fSupAdversaries = supR3HardenedWinFindAdversaries();
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Get the executable name.
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync DWORD cwcExecName = GetModuleFileNameW(GetModuleHandleW(NULL), g_wszSupLibHardenedExePath,
100b161379af7255c69e27587cc746e5f76ff050vboxsync RT_ELEMENTS(g_wszSupLibHardenedExePath));
100b161379af7255c69e27587cc746e5f76ff050vboxsync if (cwcExecName >= RT_ELEMENTS(g_wszSupLibHardenedExePath))
a6c871653045073d6ef74d0589de345ae62b607dvboxsync supR3HardenedFatalMsg("suplibHardenedWindowsMain", kSupInitOp_Integrity, VERR_BUFFER_OVERFLOW,
a6c871653045073d6ef74d0589de345ae62b607dvboxsync "The executable path is too long.");
a6c871653045073d6ef74d0589de345ae62b607dvboxsync
a6c871653045073d6ef74d0589de345ae62b607dvboxsync /* The NT version. */
a6c871653045073d6ef74d0589de345ae62b607dvboxsync HANDLE hFile = CreateFileW(g_wszSupLibHardenedExePath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecurityAttributes*/,
a6c871653045073d6ef74d0589de345ae62b607dvboxsync OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL /*hTemplateFile*/);
a6c871653045073d6ef74d0589de345ae62b607dvboxsync if (hFile == NULL || hFile == INVALID_HANDLE_VALUE)
a6c871653045073d6ef74d0589de345ae62b607dvboxsync supR3HardenedFatalMsg("suplibHardenedWindowsMain", kSupInitOp_Integrity, RTErrConvertFromWin32(GetLastError()),
a6c871653045073d6ef74d0589de345ae62b607dvboxsync "Error opening the executable: %u (%ls).", GetLastError());
a6c871653045073d6ef74d0589de345ae62b607dvboxsync RT_ZERO(g_SupLibHardenedExeNtPath);
a6c871653045073d6ef74d0589de345ae62b607dvboxsync ULONG cbIgn;
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsync NTSTATUS rcNt = NtQueryObject(hFile, ObjectNameInformation, &g_SupLibHardenedExeNtPath,
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsync sizeof(g_SupLibHardenedExeNtPath) - sizeof(WCHAR), &cbIgn);
55f0ad00baf08057a3d6087ca698d4fd86e7b4a7vboxsync if (!NT_SUCCESS(rcNt))
100b161379af7255c69e27587cc746e5f76ff050vboxsync supR3HardenedFatalMsg("suplibHardenedWindowsMain", kSupInitOp_Integrity, RTErrConvertFromNtStatus(rcNt),
100b161379af7255c69e27587cc746e5f76ff050vboxsync "NtQueryObject -> %#x (on %ls)\n", rcNt, g_wszSupLibHardenedExePath);
100b161379af7255c69e27587cc746e5f76ff050vboxsync NtClose(hFile);
100b161379af7255c69e27587cc746e5f76ff050vboxsync
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync /* The NT executable name offset / dir path length. */
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync g_offSupLibHardenedExeNtName = g_SupLibHardenedExeNtPath.UniStr.Length / sizeof(WCHAR);
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync while ( g_offSupLibHardenedExeNtName > 1
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync && g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] != '\\' )
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync g_offSupLibHardenedExeNtName--;
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync /*
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync * Call the C/C++ main function.
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync */
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync SUP_DPRINTF(("Calling main()\n"));
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync rcExit = (RTEXITCODE)main(cArgs, papszArgs, NULL);
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync
beed5fc4d17b85d6d05516ae63e6308af82ad96fvboxsync /*
100b161379af7255c69e27587cc746e5f76ff050vboxsync * Exit the process (never return).
100b161379af7255c69e27587cc746e5f76ff050vboxsync */
100b161379af7255c69e27587cc746e5f76ff050vboxsync SUP_DPRINTF(("Terminating the normal way: rcExit=%d\n", rcExit));
100b161379af7255c69e27587cc746e5f76ff050vboxsync suplibHardenedExit(rcExit);
100b161379af7255c69e27587cc746e5f76ff050vboxsync}
100b161379af7255c69e27587cc746e5f76ff050vboxsync
100b161379af7255c69e27587cc746e5f76ff050vboxsync