Changeset 56733 in vbox for trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
- Timestamp:
- Jul 1, 2015 2:01:43 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
r56293 r56733 35 35 #endif 36 36 #ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR 37 # define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x200 38 # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 37 # define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR UINT32_C(0x100) 38 # define LOAD_LIBRARY_SEARCH_APPLICATION_DIR UINT32_C(0x200) 39 # define LOAD_LIBRARY_SEARCH_USER_DIRS UINT32_C(0x400) 40 # define LOAD_LIBRARY_SEARCH_SYSTEM32 UINT32_C(0x800) 39 41 #endif 40 42 … … 274 276 /** The NT path of the executable. */ 275 277 SUPSYSROOTDIRBUF g_SupLibHardenedExeNtPath; 278 /** The NT path of the application binary directory. */ 279 SUPSYSROOTDIRBUF g_SupLibHardenedAppBinNtPath; 276 280 /** The offset into g_SupLibHardenedExeNtPath of the executable name (WCHAR, 277 281 * not byte). This also gives the length of the exectuable directory path, 278 282 * including a trailing slash. */ 279 uint32_t g_offSupLibHardenedExeNtName; 283 static uint32_t g_offSupLibHardenedExeNtName; 284 /** Set if we need to use the LOAD_LIBRARY_SEARCH_USER_DIRS option. */ 285 bool g_fSupLibHardenedDllSearchUserDirs = false; 280 286 /** @} */ 281 287 … … 464 470 if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)) 465 471 { 466 fFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32; 467 if (!fSystem32Only) 468 fFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR; 472 fFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32; 473 if (!fSystem32Only) 474 { 475 fFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR; 476 if (g_fSupLibHardenedDllSearchUserDirs) 477 fFlags |= LOAD_LIBRARY_SEARCH_USER_DIRS; 478 } 469 479 } 470 480 … … 806 816 continue; 807 817 } 808 if (supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardened ExeNtPath.UniStr.Buffer,809 g_ offSupLibHardenedExeNtName,818 if (supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedAppBinNtPath.UniStr.Buffer, 819 g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(CHAR), 810 820 uBuf.szName) != NULL) 811 821 { … … 889 899 g_System32NtPath.UniStr.Length / sizeof(WCHAR), 890 900 pCur->szName) 891 && !supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardened ExeNtPath.UniStr.Buffer,892 g_ offSupLibHardenedExeNtName,901 && !supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedAppBinNtPath.UniStr.Buffer, 902 g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(WCHAR), 893 903 pCur->szName) 894 904 && ( pCur->cwcAltSearchDir == 0 … … 983 993 { 984 994 { g_System32NtPath.UniStr.Buffer, g_System32NtPath.UniStr.Length / sizeof(WCHAR) }, 985 { g_SupLibHardenedExeNtPath.UniStr.Buffer, g_ offSupLibHardenedExeNtName - 1},995 { g_SupLibHardenedExeNtPath.UniStr.Buffer, g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(WCHAR) }, 986 996 { pCur->pwszAltSearchDir, pCur->cwcAltSearchDir }, 987 997 }; … … 1352 1362 * 7. x86 variations of 4 & 5 - ditto. 1353 1363 */ 1354 Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');1355 1364 uint32_t fFlags = 0; 1356 1365 if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_System32NtPath.UniStr, true /*fCheckSlash*/)) … … 1358 1367 else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_WinSxSNtPath.UniStr, true /*fCheckSlash*/)) 1359 1368 fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER; 1360 else if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR), 1361 g_SupLibHardenedExeNtPath.UniStr.Buffer, 1362 g_offSupLibHardenedExeNtName, false /*fCheckSlash*/)) 1369 else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_SupLibHardenedAppBinNtPath.UniStr, true /*fCheckSlash*/)) 1363 1370 fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT; 1364 1371 # ifdef VBOX_PERMIT_MORE … … 1404 1411 * integrity checks. 1405 1412 */ 1406 Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');1407 1413 uint32_t fFlags = 0; 1408 if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR), 1409 g_SupLibHardenedExeNtPath.UniStr.Buffer, 1410 g_offSupLibHardenedExeNtName, false /*fCheckSlash*/)) 1414 if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_SupLibHardenedAppBinNtPath.UniStr, true /*fCheckSlash*/)) 1411 1415 fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT; 1412 1416 else … … 4649 4653 "Window Vista without any service pack installed is not supported. Please install the latest service pack."); 4650 4654 #endif 4655 } 4656 4657 4658 /** 4659 * Modifies the DLL search path for testcases. 4660 * 4661 * This makes sure the application binary path is in the search path. When 4662 * starting a testcase executable in the testcase/ subdirectory this isn't the 4663 * case by default. So, unless we do something about it we won't be able to 4664 * import VBox DLLs. 4665 * 4666 * @param fFlags The main flags (giving the location). 4667 * @param pszAppBinPath The path to the application binary directory 4668 * (windows style). 4669 */ 4670 DECLHIDDEN(void) supR3HardenedWinModifyDllSearchPath(uint32_t fFlags, const char *pszAppBinPath) 4671 { 4672 /* 4673 * For the testcases to work, we must add the app bin directory to the 4674 * DLL search list before the testcase dll is loaded or it won't be 4675 * able to find the VBox DLLs. This is done _after_ VBoxRT.dll is 4676 * initialized and sets its defaults. 4677 */ 4678 switch (fFlags & SUPSECMAIN_FLAGS_LOC_MASK) 4679 { 4680 case SUPSECMAIN_FLAGS_LOC_TESTCASE: 4681 break; 4682 default: 4683 return; 4684 } 4685 4686 /* 4687 * Dynamically resolve the two APIs we need (the latter uses forwarders on w7). 4688 */ 4689 HMODULE hModKernel32 = GetModuleHandleW(L"kernel32.dll"); 4690 4691 typedef BOOL (WINAPI *PFNSETDLLDIRECTORY)(LPCWSTR); 4692 PFNSETDLLDIRECTORY pfnSetDllDir; 4693 pfnSetDllDir = (PFNSETDLLDIRECTORY)GetProcAddress(hModKernel32, "SetDllDirectoryW"); 4694 4695 typedef BOOL (WINAPI *PFNSETDEFAULTDLLDIRECTORIES)(DWORD); 4696 PFNSETDEFAULTDLLDIRECTORIES pfnSetDefDllDirs; 4697 pfnSetDefDllDirs = (PFNSETDEFAULTDLLDIRECTORIES)GetProcAddress(hModKernel32, "SetDefaultDllDirectories"); 4698 4699 if (pfnSetDllDir != NULL) 4700 { 4701 /* 4702 * Convert the path to UTF-16 and try set it. 4703 */ 4704 PRTUTF16 pwszAppBinPath = NULL; 4705 int rc = RTStrToUtf16(pszAppBinPath, &pwszAppBinPath); 4706 if (RT_SUCCESS(rc)) 4707 { 4708 if (pfnSetDllDir(pwszAppBinPath)) 4709 { 4710 SUP_DPRINTF(("supR3HardenedWinModifyDllSearchPath: Set dll dir to '%ls'\n", pwszAppBinPath)); 4711 g_fSupLibHardenedDllSearchUserDirs = true; 4712 4713 /* 4714 * We set it alright, on W7 and later we also must modify the 4715 * default DLL search order. See @bugref{6861} for details on 4716 * why we don't do this on Vista (also see init-win.cpp in IPRT). 4717 */ 4718 if ( pfnSetDefDllDirs 4719 && g_uNtVerCombined >= SUP_NT_VER_W70) 4720 { 4721 if (pfnSetDefDllDirs( LOAD_LIBRARY_SEARCH_APPLICATION_DIR 4722 | LOAD_LIBRARY_SEARCH_SYSTEM32 4723 | LOAD_LIBRARY_SEARCH_USER_DIRS)) 4724 SUP_DPRINTF(("supR3HardenedWinModifyDllSearchPath: Successfully modified search dirs.\n")); 4725 else 4726 supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: SetDllDirectoryW(%ls) failed: %d\n", 4727 pwszAppBinPath, RtlGetLastWin32Error()); 4728 } 4729 } 4730 else 4731 supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: SetDllDirectoryW(%ls) failed: %d\n", 4732 pwszAppBinPath, RtlGetLastWin32Error()); 4733 RTUtf16Free(pwszAppBinPath); 4734 } 4735 else 4736 supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: RTStrToUtf16(%s) failed: %d\n", pszAppBinPath, rc); 4737 } 4738 } 4739 4740 4741 /** 4742 * Initializes the application binary directory path. 4743 * 4744 * This is called once or twice. 4745 * 4746 * @param fFlags The main flags (giving the location). 4747 */ 4748 DECLHIDDEN(void) supR3HardenedWinInitAppBin(uint32_t fFlags) 4749 { 4750 USHORT cwc = (USHORT)g_offSupLibHardenedExeNtName - 1; 4751 g_SupLibHardenedAppBinNtPath.UniStr.Buffer = g_SupLibHardenedAppBinNtPath.awcBuffer; 4752 memcpy(g_SupLibHardenedAppBinNtPath.UniStr.Buffer, g_SupLibHardenedExeNtPath.UniStr.Buffer, cwc * sizeof(WCHAR)); 4753 4754 switch (fFlags & SUPSECMAIN_FLAGS_LOC_MASK) 4755 { 4756 case SUPSECMAIN_FLAGS_LOC_APP_BIN: 4757 break; 4758 case SUPSECMAIN_FLAGS_LOC_TESTCASE: 4759 { 4760 /* Drop one directory level. */ 4761 USHORT off = cwc; 4762 WCHAR wc; 4763 while ( off > 1 4764 && (wc = g_SupLibHardenedAppBinNtPath.UniStr.Buffer[off - 1]) != '\0') 4765 if (wc != '\\' && wc != '/') 4766 off--; 4767 else 4768 { 4769 if (g_SupLibHardenedAppBinNtPath.UniStr.Buffer[off - 2] == ':') 4770 cwc = off; 4771 else 4772 cwc = off - 1; 4773 break; 4774 } 4775 break; 4776 } 4777 default: 4778 supR3HardenedFatal("supR3HardenedWinInitAppBin: Unknown program binary location: %#x\n", fFlags); 4779 } 4780 4781 g_SupLibHardenedAppBinNtPath.UniStr.Buffer[cwc] = '\0'; 4782 g_SupLibHardenedAppBinNtPath.UniStr.Length = cwc * sizeof(WCHAR); 4783 g_SupLibHardenedAppBinNtPath.UniStr.MaximumLength = sizeof(g_SupLibHardenedAppBinNtPath.awcBuffer); 4784 SUP_DPRINTF(("supR3HardenedWinInitAppBin(%#x): '%ls'\n", fFlags, g_SupLibHardenedAppBinNtPath.UniStr.Buffer)); 4651 4785 } 4652 4786 … … 5372 5506 5373 5507 /* 5508 * Preliminary app binary path init. May change when SUPR3HardenedMain is 5509 * called (via main below). 5510 */ 5511 supR3HardenedWinInitAppBin(SUPSECMAIN_FLAGS_LOC_APP_BIN); 5512 5513 /* 5374 5514 * If we've done early init already, register the DLL load notification 5375 5515 * callback and reinstall the NtDll patches. … … 5566 5706 5567 5707 /* 5708 * Preliminary app binary path init. May change when SUPR3HardenedMain is called. 5709 */ 5710 supR3HardenedWinInitAppBin(SUPSECMAIN_FLAGS_LOC_APP_BIN); 5711 5712 /* 5568 5713 * Initialize the image verification stuff (hooks LdrLoadDll and NtCreateSection). 5569 5714 */
Note:
See TracChangeset
for help on using the changeset viewer.