- Timestamp:
- Apr 13, 2016 8:13:17 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/nt/nt.h
r59366 r60480 249 249 250 250 /** 251 * Converts a windows-style path to NT format and encoding. 252 * 253 * @returns IPRT status code. 254 * @param pNtName Where to return the NT name. Free using 255 * RTNtPathFree. 256 * @param phRootDir Where to return the root handle, if applicable. 257 * @param pszPath The UTF-8 path. 258 */ 259 RTDECL(int) RTNtPathFromWinUtf8(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath); 260 261 /** 251 262 * Converts a UTF-16 windows-style path to NT format. 252 263 * … … 263 274 264 275 /** 276 * Ensures that the NT string has sufficient storage to hold @a cwcMin RTUTF16 277 * chars plus a terminator. 278 * 279 * The NT string must have been returned by RTNtPathFromWinUtf8 or 280 * RTNtPathFromWinUtf16Ex. 281 * 282 * @returns IPRT status code. 283 * @param pNtName The NT path string. 284 * @param cwcMin The minimum number of RTUTF16 chars. Max 32767. 285 * @sa RTNtPathFree 286 */ 287 RTDECL(int) RTNtPathEnsureSpace(struct _UNICODE_STRING *pNtName, size_t cwcMin); 288 289 /** 265 290 * Frees the native path and root handle. 266 291 * 267 * @param pNtName The NT path after a successful 268 * RTNtPathFromWinUtf16Ex call. 269 * @param phRootDir The root handle variable after a successfull 270 * RTNtPathFromWinUtf16Ex call. 292 * @param pNtName The NT path from a successful call to 293 * RTNtPathFromWinUtf8 or RTNtPathFromWinUtf16Ex. 294 * @param phRootDir The root handle variable from the same call. 271 295 */ 272 296 RTDECL(void) RTNtPathFree(struct _UNICODE_STRING *pNtName, HANDLE *phRootDir); 297 298 299 /** 300 * Checks whether the path could be containing alternative 8.3 names generated 301 * by NTFS, FAT, or other similar file systems. 302 * 303 * @returns Pointer to the first component that might be an 8.3 name, NULL if 304 * not 8.3 path. 305 * @param pwszPath The path to check. 306 * 307 * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names, 308 * however, non-tilde 8.3 aliases are probably rare enough to not be 309 * worth all the extra code necessary to open each path component and 310 * check if we've got the short name or not. 311 */ 312 RTDECL(PRTUTF16) RTNtPathFindPossible8dot3Name(PCRTUTF16 pwszPath); 313 314 /** 315 * Fixes up a path possibly containing one or more alternative 8-dot-3 style 316 * components. 317 * 318 * The path is fixed up in place. Errors are ignored. 319 * 320 * @returns VINF_SUCCESS if it all went smoothly, informational status codes 321 * indicating the nature of last problem we ran into. 322 * 323 * @param pUniStr The path to fix up. MaximumLength is the max buffer 324 * length. 325 * @param fPathOnly Whether to only process the path and leave the filename 326 * as passed in. 327 */ 328 RTDECL(int) RTNtPathExpand8dot3Path(struct _UNICODE_STRING *pUniStr, bool fPathOnly); 273 329 274 330 -
trunk/src/VBox/HostDrivers/Support/Makefile.kmk
r60043 r60480 308 308 $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathChangeToUnixSlashes.cpp \ 309 309 $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathExt.cpp \ 310 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrPrintHexBytes.cpp \311 310 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16PrintHexBytes.cpp \ 312 311 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16ICmpAscii.cpp \ … … 375 374 win/SUPR3HardenedNoCrt-win.cpp \ 376 375 $(VBOX_PATH_RUNTIME_SRC)/nt/RTErrConvertFromNtStatus.cpp \ 376 $(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathFindPossible8dot3Name.cpp \ 377 $(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathExpand8dot3Path.cpp \ 377 378 $(VBOX_PATH_RUNTIME_SRC)/r3/nt/pathint-nt.cpp \ 378 379 $(VBOX_PATH_RUNTIME_SRC)/win/RTErrConvertFromWin32.cpp \ -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
r56733 r60480 76 76 DECLHIDDEN(int) supHardNtVpThread(HANDLE hProcess, HANDLE hThread, PRTERRINFO pErrInfo); 77 77 DECLHIDDEN(int) supHardNtVpDebugger(HANDLE hProcess, PRTERRINFO pErrInfo); 78 DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath);79 DECLHIDDEN(void) supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly);80 78 81 79 DECLHIDDEN(bool) supHardViUtf16PathIsEqualEx(PCRTUTF16 pawcLeft, size_t cwcLeft, const char *pszRight); -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
r60193 r60480 1090 1090 1091 1091 /** 1092 * Checks whether the path could be containing alternative 8.3 names generated1093 * by NTFS, FAT, or other similar file systems.1094 *1095 * @returns Pointer to the first component that might be an 8.3 name, NULL if1096 * not 8.3 path.1097 * @param pwszPath The path to check.1098 *1099 * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names,1100 * however, non-tilde 8.3 aliases are probably rare enough to not be1101 * worth all the extra code necessary to open each path component and1102 * check if we've got the short name or not.1103 */1104 DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath)1105 {1106 PCRTUTF16 pwszName = pwszPath;1107 for (;;)1108 {1109 RTUTF16 wc = *pwszPath++;1110 if (wc == '~')1111 {1112 /* Could check more here before jumping to conclusions... */1113 if (pwszPath - pwszName <= 8+1+3)1114 return (PRTUTF16)pwszName;1115 }1116 else if (wc == '\\' || wc == '/' || wc == ':')1117 pwszName = pwszPath;1118 else if (wc == 0)1119 break;1120 }1121 return NULL;1122 }1123 1124 1125 /**1126 * Fixes up a path possibly containing one or more alternative 8-dot-3 style1127 * components.1128 *1129 * The path is fixed up in place. Errors are ignored.1130 *1131 * @param pUniStr The path to fix up. MaximumLength is the max buffer1132 * length.1133 * @param fPathOnly Whether to only process the path and leave the filename1134 * as passed in.1135 */1136 DECLHIDDEN(void) supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly)1137 {1138 /*1139 * We could use FileNormalizedNameInformation here and slap the volume device1140 * path in front of the result, but it's only supported since windows 8.01141 * according to some docs... So we expand all supicious names.1142 */1143 union fix8dot3tmp1144 {1145 FILE_BOTH_DIR_INFORMATION Info;1146 uint8_t abBuffer[sizeof(FILE_BOTH_DIR_INFORMATION) + 2048 * sizeof(WCHAR)];1147 } *puBuf = NULL;1148 1149 1150 PRTUTF16 pwszFix = pUniStr->Buffer;1151 while (*pwszFix)1152 {1153 pwszFix = supHardNtVpIsPossible8dot3Path(pwszFix);1154 if (pwszFix == NULL)1155 break;1156 1157 RTUTF16 wc;1158 PRTUTF16 pwszFixEnd = pwszFix;1159 while ((wc = *pwszFixEnd) != '\0' && wc != '\\' && wc != '/')1160 pwszFixEnd++;1161 if (wc == '\0' && fPathOnly)1162 break;1163 1164 if (!puBuf)1165 {1166 puBuf = (union fix8dot3tmp *)RTMemAlloc(sizeof(*puBuf));1167 if (!puBuf)1168 break;1169 }1170 1171 RTUTF16 const wcSaved = *pwszFix;1172 *pwszFix = '\0'; /* paranoia. */1173 1174 UNICODE_STRING NtDir;1175 NtDir.Buffer = pUniStr->Buffer;1176 NtDir.Length = NtDir.MaximumLength = (USHORT)((pwszFix - pUniStr->Buffer) * sizeof(WCHAR));1177 1178 HANDLE hDir = RTNT_INVALID_HANDLE_VALUE;1179 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;1180 1181 OBJECT_ATTRIBUTES ObjAttr;1182 InitializeObjectAttributes(&ObjAttr, &NtDir, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);1183 #ifdef IN_RING01184 ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;1185 #endif1186 1187 NTSTATUS rcNt = NtCreateFile(&hDir,1188 FILE_READ_DATA | SYNCHRONIZE,1189 &ObjAttr,1190 &Ios,1191 NULL /* Allocation Size*/,1192 FILE_ATTRIBUTE_NORMAL,1193 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,1194 FILE_OPEN,1195 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,1196 NULL /*EaBuffer*/,1197 0 /*EaLength*/);1198 *pwszFix = wcSaved;1199 if (NT_SUCCESS(rcNt))1200 {1201 RT_ZERO(*puBuf);1202 1203 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;1204 UNICODE_STRING NtFilterStr;1205 NtFilterStr.Buffer = pwszFix;1206 NtFilterStr.Length = (USHORT)((uintptr_t)pwszFixEnd - (uintptr_t)pwszFix);1207 NtFilterStr.MaximumLength = NtFilterStr.Length;1208 rcNt = NtQueryDirectoryFile(hDir,1209 NULL /* Event */,1210 NULL /* ApcRoutine */,1211 NULL /* ApcContext */,1212 &Ios,1213 puBuf,1214 sizeof(*puBuf) - sizeof(WCHAR),1215 FileBothDirectoryInformation,1216 FALSE /*ReturnSingleEntry*/,1217 &NtFilterStr,1218 FALSE /*RestartScan */);1219 if (NT_SUCCESS(rcNt) && puBuf->Info.NextEntryOffset == 0) /* There shall only be one entry matching... */1220 {1221 uint32_t offName = puBuf->Info.FileNameLength / sizeof(WCHAR);1222 while (offName > 0 && puBuf->Info.FileName[offName - 1] != '\\' && puBuf->Info.FileName[offName - 1] != '/')1223 offName--;1224 uint32_t cwcNameNew = (puBuf->Info.FileNameLength / sizeof(WCHAR)) - offName;1225 uint32_t cwcNameOld = (uint32_t)(pwszFixEnd - pwszFix);1226 1227 if (cwcNameOld == cwcNameNew)1228 memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));1229 else if ( pUniStr->Length + cwcNameNew * sizeof(WCHAR) - cwcNameOld * sizeof(WCHAR) + sizeof(WCHAR)1230 <= pUniStr->MaximumLength)1231 {1232 size_t cwcLeft = pUniStr->Length - (pwszFixEnd - pUniStr->Buffer) * sizeof(WCHAR) + sizeof(WCHAR);1233 memmove(&pwszFix[cwcNameNew], pwszFixEnd, cwcLeft * sizeof(WCHAR));1234 pUniStr->Length -= (USHORT)(cwcNameOld * sizeof(WCHAR));1235 pUniStr->Length += (USHORT)(cwcNameNew * sizeof(WCHAR));1236 pwszFixEnd -= cwcNameOld;1237 pwszFixEnd -= cwcNameNew;1238 memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));1239 }1240 /* else: ignore overflow. */1241 }1242 /* else: ignore failure. */1243 1244 NtClose(hDir);1245 }1246 1247 /* Advance */1248 pwszFix = pwszFixEnd;1249 }1250 1251 if (puBuf)1252 RTMemFree(puBuf);1253 }1254 1255 1256 1257 /**1258 1092 * Matches two UNICODE_STRING structures in a case sensitive fashion. 1259 1093 * … … 1316 1150 */ 1317 1151 PUNICODE_STRING pLongName = &pImage->Name.UniStr; 1318 if ( supHardNtVpIsPossible8dot3Path(pLongName->Buffer))1152 if (RTNtPathFindPossible8dot3Name(pLongName->Buffer)) 1319 1153 { 1320 1154 AssertCompile(sizeof(pThis->abMemory) > sizeof(pImage->Name)); … … 1325 1159 memcpy(pTmp->Buffer, pLongName->Buffer, pLongName->Length + sizeof(RTUTF16)); 1326 1160 1327 supHardNtVpFix8dot3Path(pTmp, false /*fPathOnly*/);1161 RTNtPathExpand8dot3Path(pTmp, false /*fPathOnly*/); 1328 1162 Assert(pTmp->Buffer[pTmp->Length / sizeof(RTUTF16)] == '\0'); 1329 1163 -
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
r59811 r60480 1225 1225 } 1226 1226 1227 if (supHardNtVpIsPossible8dot3Path(uBuf.UniStr.Buffer)) 1227 if (!RTNtPathFindPossible8dot3Name(uBuf.UniStr.Buffer)) 1228 cbNameBuf += sizeof(WCHAR); 1229 else 1228 1230 { 1229 1231 uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128; 1230 supHardNtVpFix8dot3Path(&uBuf.UniStr, true /*fPathOnly*/); 1232 RTNtPathExpand8dot3Path(&uBuf.UniStr, true /*fPathOnly*/); 1233 cbNameBuf = (uintptr_t)uBuf.UniStr.Buffer + uBuf.UniStr.Length + sizeof(WCHAR) - (uintptr_t)&uBuf.abBuffer[0]; 1231 1234 } 1232 1235 -
trunk/src/VBox/Runtime/Makefile.kmk
r59754 r60480 784 784 generic/RTThreadGetNativeState-generic.cpp \ 785 785 nt/RTErrConvertFromNtStatus.cpp \ 786 nt/RTNtPathExpand8dot3Path.cpp \ 787 nt/RTNtPathFindPossible8dot3Name.cpp \ 786 788 r3/nt/fs-nt.cpp \ 787 789 r3/nt/pathint-nt.cpp \ … … 2171 2173 generic/RTMpGetCoreCount-generic.cpp \ 2172 2174 nt/RTErrConvertFromNtStatus.cpp \ 2175 nt/RTNtPathExpand8dot3Path.cpp \ 2176 nt/RTNtPathFindPossible8dot3Name.cpp \ 2173 2177 r0drv/generic/threadctxhooks-r0drv-generic.cpp \ 2174 2178 r0drv/alloc-ef-r0drv.cpp \
Note:
See TracChangeset
for help on using the changeset viewer.