VirtualBox

Changeset 52735 in vbox


Ignore:
Timestamp:
Sep 13, 2014 8:38:33 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96076
Message:

SUPDrv-win.cpp: Alternative way of obtaining the ALPC Port object type.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r52575 r52735  
    4141#include <iprt/process.h>
    4242#include <iprt/power.h>
     43#include <iprt/rand.h>
    4344#include <iprt/spinlock.h>
    4445#include <iprt/string.h>
     
    208209# define SUPDRVNTPROTECT_MAGIC_DEAD UINT32_C(0x19880508)
    209210
     211/** Pointer to ObGetObjectType. */
     212typedef POBJECT_TYPE (NTAPI *PFNOBGETOBJECTTYPE)(PVOID);
    210213/** Pointer to ObRegisterCallbacks. */
    211214typedef NTSTATUS (NTAPI *PFNOBREGISTERCALLBACKS)(POB_CALLBACK_REGISTRATION, PVOID *);
     
    218221/** Pointer to PsIsProtectedProcessLight. */
    219222typedef BOOLEAN  (NTAPI *PFNPSISPROTECTEDPROCESSLIGHT)(PEPROCESS);
     223/** Pointer to ZwAlpcCreatePort. */
     224typedef NTSTATUS (NTAPI *PFNZWALPCCREATEPORT)(PHANDLE, POBJECT_ATTRIBUTES, struct _ALPC_PORT_ATTRIBUTES *);
    220225
    221226#endif /* VBOX_WITH_HARDENINIG */
     
    316321/** Combined windows NT version number.  See SUP_MAKE_NT_VER_COMBINED. */
    317322uint32_t                            g_uNtVerCombined = 0;
     323/** Pointer to ObGetObjectType if available.. */
     324static PFNOBGETOBJECTTYPE           g_pfnObGetObjectType = NULL;
    318325/** Pointer to ObRegisterCallbacks if available.. */
    319326static PFNOBREGISTERCALLBACKS       g_pfnObRegisterCallbacks = NULL;
     
    326333/** Pointer to PsIsProtectedProcessLight. */
    327334static PFNPSISPROTECTEDPROCESSLIGHT g_pfnPsIsProtectedProcessLight = NULL;
     335/** Pointer to ZwAlpcCreatePort. */
     336static PFNZWALPCCREATEPORT          g_pfnZwAlpcCreatePort = NULL;
    328337
    329338# ifdef RT_ARCH_AMD64
     
    337346}
    338347# endif
     348/** The primary ALPC port object type. (LpcPortObjectType at init time.) */
     349static POBJECT_TYPE                 g_pAlpcPortObjectType1 = NULL;
     350/** The secondary ALPC port object type. (Sampled at runtime.) */
     351static POBJECT_TYPE volatile        g_pAlpcPortObjectType2 = NULL;
     352
    339353#endif
    340354
     
    21202134
    21212135
     2136static bool supdrvNtProtectGetAlpcPortObjectType2(PCRTUTF16 pwszPortNm, POBJECT_TYPE *ppObjType)
     2137{
     2138    bool fDone = false;
     2139
     2140    UNICODE_STRING UniStrPortNm;
     2141    UniStrPortNm.Buffer = (WCHAR *)pwszPortNm;
     2142    UniStrPortNm.Length = (USHORT)(RTUtf16Len(pwszPortNm) * sizeof(WCHAR));
     2143    UniStrPortNm.MaximumLength = UniStrPortNm.Length + sizeof(WCHAR);
     2144
     2145    OBJECT_ATTRIBUTES ObjAttr;
     2146    InitializeObjectAttributes(&ObjAttr, &UniStrPortNm, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
     2147
     2148    HANDLE hPort;
     2149SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: %ls\n", pwszPortNm);
     2150    NTSTATUS rcNt = g_pfnZwAlpcCreatePort(&hPort, &ObjAttr, NULL /*pPortAttribs*/);
     2151    if (NT_SUCCESS(rcNt))
     2152    {
     2153SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: Opened %p\n", hPort);
     2154        PVOID pvObject;
     2155        rcNt = ObReferenceObjectByHandle(hPort, 0 /*DesiredAccess*/, NULL /*pObjectType*/,
     2156                                         KernelMode, &pvObject, NULL /*pHandleInfo*/);
     2157        if (NT_SUCCESS(rcNt))
     2158        {
     2159SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: pvObject=%p\n", pvObject);
     2160            POBJECT_TYPE pObjType = g_pfnObGetObjectType(pvObject);
     2161SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: pObjType=%p (vs %p)\n", pObjType, *ppObjType);
     2162            if (pObjType)
     2163            {
     2164                *ppObjType = pObjType;
     2165                fDone = true;
     2166            }
     2167            ObDereferenceObject(pvObject);
     2168        }
     2169        NtClose(hPort);
     2170    }
     2171    return fDone;
     2172}
     2173
     2174
     2175static POBJECT_TYPE supdrvNtProtectGetAlpcPortObjectType(uint32_t uSessionId, const char *pszSessionId)
     2176{
     2177    POBJECT_TYPE pObjType = *LpcPortObjectType;
     2178
     2179    if (   g_pfnZwAlpcCreatePort
     2180        && g_pfnObGetObjectType)
     2181    {
     2182        int     rc;
     2183        ssize_t cchTmp; NOREF(cchTmp);
     2184        char    szTmp[16];
     2185        RTUTF16 wszPortNm[128];
     2186        size_t  offRand;
     2187
     2188        /*
     2189         * First attempt is in the session directory.
     2190         */
     2191        rc  = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\Sessions\\");
     2192        rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), pszSessionId);
     2193        rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\VBoxDrv-");
     2194        cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
     2195        Assert(cchTmp > 0);
     2196        rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2197        rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "-");
     2198        offRand = RTUtf16Len(wszPortNm);
     2199        cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
     2200        Assert(cchTmp > 0);
     2201        rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2202        AssertRCSuccess(rc);
     2203
     2204        bool fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
     2205        if (!fDone)
     2206        {
     2207            wszPortNm[offRand] = '\0';
     2208            cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0); Assert(cchTmp > 0);
     2209            rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2210            AssertRCSuccess(rc);
     2211
     2212            fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
     2213        }
     2214        if (!fDone)
     2215        {
     2216            /*
     2217             * Try base names.
     2218             */
     2219            if (uSessionId == 0)
     2220                rc  = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\BaseNamedObjects\\VBoxDrv-");
     2221            else
     2222            {
     2223                rc  = RTUtf16CopyAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\Sessions\\");
     2224                rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), pszSessionId);
     2225                rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "\\BaseNamedObjects\\VBoxDrv-");
     2226            }
     2227            cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), (uint32_t)(uintptr_t)PsGetProcessId(PsGetCurrentProcess()), 16, 0, 0, 0);
     2228            Assert(cchTmp > 0);
     2229            rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2230            rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), "-");
     2231            offRand = RTUtf16Len(wszPortNm);
     2232            cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
     2233            Assert(cchTmp > 0);
     2234            rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2235            AssertRCSuccess(rc);
     2236
     2237            bool fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
     2238            if (!fDone)
     2239            {
     2240                wszPortNm[offRand] = '\0';
     2241                cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), RTRandU32(), 16, 0, 0, 0);
     2242                Assert(cchTmp > 0);
     2243                rc |= RTUtf16CatAscii(wszPortNm, RT_ELEMENTS(wszPortNm), szTmp);
     2244                AssertRCSuccess(rc);
     2245
     2246                fDone = supdrvNtProtectGetAlpcPortObjectType2(wszPortNm, &pObjType);
     2247            }
     2248        }
     2249
     2250        /* Cache the result in g_pAlpcPortObjectType2. */
     2251        if (   g_pAlpcPortObjectType2 == NULL
     2252            && pObjType != g_pAlpcPortObjectType1
     2253            && fDone)
     2254            g_pAlpcPortObjectType2 = pObjType;
     2255
     2256    }
     2257
     2258    return pObjType;
     2259}
     2260
     2261
    21222262/**
    21232263 * Called in the context of VBoxDrvNtCreate to determin the CSRSS for the
     
    21422282     * down the CSRSS process. So, we start by constructing a path to it.
    21432283     */
    2144     int rc;
     2284    int         rc;
    21452285    uint32_t    uSessionId = PsGetProcessSessionId(PsGetCurrentProcess());
     2286    char        szSessionId[16];
    21462287    WCHAR       wszApiPort[48];
    21472288    if (uSessionId == 0)
     2289    {
     2290        szSessionId[0] = '0';
     2291        szSessionId[1] = '\0';
    21482292        rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort");
     2293    }
    21492294    else
    21502295    {
    2151         char szTmp[64];
    2152         ssize_t cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), uSessionId, 10, 0, 0, 0);
     2296        ssize_t cchTmp = RTStrFormatU32(szSessionId, sizeof(szSessionId), uSessionId, 10, 0, 0, 0);
    21532297        AssertReturn(cchTmp > 0, (int)cchTmp);
    21542298        rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Sessions\\");
    21552299        if (RT_SUCCESS(rc))
    2156             rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), szTmp);
     2300            rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), szSessionId);
    21572301        if (RT_SUCCESS(rc))
    21582302            rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort");
     
    21732317                                            NULL /*pAccessState*/,
    21742318                                            STANDARD_RIGHTS_READ,
    2175                                             *LpcPortObjectType,
     2319                                            g_pAlpcPortObjectType1,
    21762320                                            KernelMode,
    21772321                                            NULL /*pvParseContext*/,
    21782322                                            &pvApiPortObj);
     2323    if (   rcNt == STATUS_OBJECT_TYPE_MISMATCH
     2324        && g_pAlpcPortObjectType2 != NULL)
     2325        rcNt = ObReferenceObjectByName(&ApiPortStr,
     2326                                       0,
     2327                                       NULL /*pAccessState*/,
     2328                                       STANDARD_RIGHTS_READ,
     2329                                       g_pAlpcPortObjectType2,
     2330                                       KernelMode,
     2331                                       NULL /*pvParseContext*/,
     2332                                       &pvApiPortObj);
     2333    if (   rcNt == STATUS_OBJECT_TYPE_MISMATCH
     2334        && g_pfnObGetObjectType
     2335        && g_pfnZwAlpcCreatePort)
     2336        rcNt = ObReferenceObjectByName(&ApiPortStr,
     2337                                       0,
     2338                                       NULL /*pAccessState*/,
     2339                                       STANDARD_RIGHTS_READ,
     2340                                       supdrvNtProtectGetAlpcPortObjectType(uSessionId, szSessionId),
     2341                                       KernelMode,
     2342                                       NULL /*pvParseContext*/,
     2343                                       &pvApiPortObj);
    21792344    if (!NT_SUCCESS(rcNt))
    21802345    {
    21812346        SUPR0Printf("vboxdrv: Error opening '%ls': %#x\n", wszApiPort, rcNt);
    2182         return VERR_SUPDRV_APIPORT_OPEN_ERROR;
     2347        return rcNt == STATUS_OBJECT_TYPE_MISMATCH ? VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE : VERR_SUPDRV_APIPORT_OPEN_ERROR;
    21832348    }
    21842349
     
    36533818    UNICODE_STRING RoutineName;
    36543819
     3820    RtlInitUnicodeString(&RoutineName, L"ObGetObjectType");
     3821    g_pfnObGetObjectType = (PFNOBGETOBJECTTYPE)MmGetSystemRoutineAddress(&RoutineName);
     3822
    36553823    RtlInitUnicodeString(&RoutineName, L"ObRegisterCallbacks");
    36563824    g_pfnObRegisterCallbacks   = (PFNOBREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName);
     
    36673835    RtlInitUnicodeString(&RoutineName, L"PsIsProtectedProcessLight");
    36683836    g_pfnPsIsProtectedProcessLight = (PFNPSISPROTECTEDPROCESSLIGHT)MmGetSystemRoutineAddress(&RoutineName);
     3837
     3838    RtlInitUnicodeString(&RoutineName, L"ZwAlpcCreatePort");
     3839    g_pfnZwAlpcCreatePort = (PFNZWALPCCREATEPORT)MmGetSystemRoutineAddress(&RoutineName);
    36693840
    36703841    RtlInitUnicodeString(&RoutineName, L"ZwQueryVirtualMemory"); /* Yes, using Zw version here. */
     
    37483919    }
    37493920
     3921# ifdef VBOX_STRICT
     3922    if (   g_uNtVerCombined >= SUP_NT_VER_W70
     3923        && (   g_pfnObGetObjectType == NULL
     3924            || g_pfnZwAlpcCreatePort == NULL) )
     3925    {
     3926        LogRel(("vboxdrv: g_pfnObGetObjectType=%p g_pfnZwAlpcCreatePort=%p.\n", g_pfnObGetObjectType, g_pfnZwAlpcCreatePort));
     3927        return STATUS_PROCEDURE_NOT_FOUND;
     3928    }
     3929# endif
    37503930
    37513931    /* The spinlock protecting our structures. */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette