Changeset 52735 in vbox
- Timestamp:
- Sep 13, 2014 8:38:33 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 96076
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r52575 r52735 41 41 #include <iprt/process.h> 42 42 #include <iprt/power.h> 43 #include <iprt/rand.h> 43 44 #include <iprt/spinlock.h> 44 45 #include <iprt/string.h> … … 208 209 # define SUPDRVNTPROTECT_MAGIC_DEAD UINT32_C(0x19880508) 209 210 211 /** Pointer to ObGetObjectType. */ 212 typedef POBJECT_TYPE (NTAPI *PFNOBGETOBJECTTYPE)(PVOID); 210 213 /** Pointer to ObRegisterCallbacks. */ 211 214 typedef NTSTATUS (NTAPI *PFNOBREGISTERCALLBACKS)(POB_CALLBACK_REGISTRATION, PVOID *); … … 218 221 /** Pointer to PsIsProtectedProcessLight. */ 219 222 typedef BOOLEAN (NTAPI *PFNPSISPROTECTEDPROCESSLIGHT)(PEPROCESS); 223 /** Pointer to ZwAlpcCreatePort. */ 224 typedef NTSTATUS (NTAPI *PFNZWALPCCREATEPORT)(PHANDLE, POBJECT_ATTRIBUTES, struct _ALPC_PORT_ATTRIBUTES *); 220 225 221 226 #endif /* VBOX_WITH_HARDENINIG */ … … 316 321 /** Combined windows NT version number. See SUP_MAKE_NT_VER_COMBINED. */ 317 322 uint32_t g_uNtVerCombined = 0; 323 /** Pointer to ObGetObjectType if available.. */ 324 static PFNOBGETOBJECTTYPE g_pfnObGetObjectType = NULL; 318 325 /** Pointer to ObRegisterCallbacks if available.. */ 319 326 static PFNOBREGISTERCALLBACKS g_pfnObRegisterCallbacks = NULL; … … 326 333 /** Pointer to PsIsProtectedProcessLight. */ 327 334 static PFNPSISPROTECTEDPROCESSLIGHT g_pfnPsIsProtectedProcessLight = NULL; 335 /** Pointer to ZwAlpcCreatePort. */ 336 static PFNZWALPCCREATEPORT g_pfnZwAlpcCreatePort = NULL; 328 337 329 338 # ifdef RT_ARCH_AMD64 … … 337 346 } 338 347 # endif 348 /** The primary ALPC port object type. (LpcPortObjectType at init time.) */ 349 static POBJECT_TYPE g_pAlpcPortObjectType1 = NULL; 350 /** The secondary ALPC port object type. (Sampled at runtime.) */ 351 static POBJECT_TYPE volatile g_pAlpcPortObjectType2 = NULL; 352 339 353 #endif 340 354 … … 2120 2134 2121 2135 2136 static 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; 2149 SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: %ls\n", pwszPortNm); 2150 NTSTATUS rcNt = g_pfnZwAlpcCreatePort(&hPort, &ObjAttr, NULL /*pPortAttribs*/); 2151 if (NT_SUCCESS(rcNt)) 2152 { 2153 SUPR0Printf("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 { 2159 SUPR0Printf("supdrvNtProtectGetAlpcPortObjectType2: pvObject=%p\n", pvObject); 2160 POBJECT_TYPE pObjType = g_pfnObGetObjectType(pvObject); 2161 SUPR0Printf("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 2175 static 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 2122 2262 /** 2123 2263 * Called in the context of VBoxDrvNtCreate to determin the CSRSS for the … … 2142 2282 * down the CSRSS process. So, we start by constructing a path to it. 2143 2283 */ 2144 int rc;2284 int rc; 2145 2285 uint32_t uSessionId = PsGetProcessSessionId(PsGetCurrentProcess()); 2286 char szSessionId[16]; 2146 2287 WCHAR wszApiPort[48]; 2147 2288 if (uSessionId == 0) 2289 { 2290 szSessionId[0] = '0'; 2291 szSessionId[1] = '\0'; 2148 2292 rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort"); 2293 } 2149 2294 else 2150 2295 { 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); 2153 2297 AssertReturn(cchTmp > 0, (int)cchTmp); 2154 2298 rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Sessions\\"); 2155 2299 if (RT_SUCCESS(rc)) 2156 rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), sz Tmp);2300 rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), szSessionId); 2157 2301 if (RT_SUCCESS(rc)) 2158 2302 rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort"); … … 2173 2317 NULL /*pAccessState*/, 2174 2318 STANDARD_RIGHTS_READ, 2175 *LpcPortObjectType,2319 g_pAlpcPortObjectType1, 2176 2320 KernelMode, 2177 2321 NULL /*pvParseContext*/, 2178 2322 &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); 2179 2344 if (!NT_SUCCESS(rcNt)) 2180 2345 { 2181 2346 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; 2183 2348 } 2184 2349 … … 3653 3818 UNICODE_STRING RoutineName; 3654 3819 3820 RtlInitUnicodeString(&RoutineName, L"ObGetObjectType"); 3821 g_pfnObGetObjectType = (PFNOBGETOBJECTTYPE)MmGetSystemRoutineAddress(&RoutineName); 3822 3655 3823 RtlInitUnicodeString(&RoutineName, L"ObRegisterCallbacks"); 3656 3824 g_pfnObRegisterCallbacks = (PFNOBREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName); … … 3667 3835 RtlInitUnicodeString(&RoutineName, L"PsIsProtectedProcessLight"); 3668 3836 g_pfnPsIsProtectedProcessLight = (PFNPSISPROTECTEDPROCESSLIGHT)MmGetSystemRoutineAddress(&RoutineName); 3837 3838 RtlInitUnicodeString(&RoutineName, L"ZwAlpcCreatePort"); 3839 g_pfnZwAlpcCreatePort = (PFNZWALPCCREATEPORT)MmGetSystemRoutineAddress(&RoutineName); 3669 3840 3670 3841 RtlInitUnicodeString(&RoutineName, L"ZwQueryVirtualMemory"); /* Yes, using Zw version here. */ … … 3748 3919 } 3749 3920 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 3750 3930 3751 3931 /* The spinlock protecting our structures. */
Note:
See TracChangeset
for help on using the changeset viewer.