Changeset 106239 in vbox
- Timestamp:
- Oct 8, 2024 2:47:35 PM (4 months ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Installer/Loader
- Files:
-
- 2 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Installer/Loader/Makefile.kmk
r106061 r106239 69 69 70 70 71 # Signing certificate. 72 ifdef VBOX_SIGNING_MODE 73 if1of ($(VBOX_SIGNING_MODE), test) 74 # If signing the installer, the loader stub must be signed as well. 75 # Hack alert! Using POST_CMDS.win to place the signing after VBoxPeSetVersion. 76 VBoxWindowsAdditions_POST_CMDS.win = $(call VBOX_SIGN_IMAGE_FN,$(out),,2) 77 VBoxWindowsAdditions_ORDERDEPS = $(VBOX_SIGN_IMAGE_ORDERDEPS) 78 endif 79 VBoxWindowsAdditions_DEFS += VBOX_SIGNING_MODE 80 VBoxWindowsAdditions_INCS += $(VBoxWindowsAdditions_0_OUTDIR) 81 VBoxWindowsAdditions_INTERMEDIATES = $(VBoxWindowsAdditions_0_OUTDIR)/BuildCert.h 82 83 # Dummy signed program that we can extract the signature from. 84 BLDPROGS += bldAddSignedDummy 85 bldAddSignedDummy_TEMPLATE := VBoxBldProg 86 bldAddSignedDummy_SOURCES := bldAddSignedDummy.cpp 87 bldAddSignedDummy_ORDERDEPS = $(VBOX_SIGN_IMAGE_ORDERDEPS) 88 bldAddSignedDummy_POST_CMDS = $(call VBOX_SIGN_IMAGE_FN,$(out),,2) 89 90 # The certificate include file. 91 $$(VBoxWindowsAdditions_0_OUTDIR)/BuildCert.h: \ 92 $(VBOX_BIN2C) \ 93 $(VBOX_RTSIGNTOOL) \ 94 $$(bldAddSignedDummy_1_TARGET) \ 95 | $$(dir $$@) 96 $(QUIET)$(RM) -f -- "$@" "[email protected]" 97 $(VBOX_RTSIGNTOOL) extract-exe-signer-cert --exe "$(bldAddSignedDummy_1_TARGET)" --output "[email protected]" --der 98 $(VBOX_BIN2C) -ascii --append BuildCert "[email protected]" "$@" 99 $(QUIET)$(RM) -f -- [email protected] 100 101 OTHER_CLEAN += $(VBOX_SUP_WIN_CERTS_FILE) 102 103 endif # VBOX_SIGNING_MODE 104 105 71 106 include $(FILE_KBUILD_SUB_FOOTER) 72 107 -
trunk/src/VBox/Additions/WINNT/Installer/Loader/VBoxWindowsAdditions.cpp
r106061 r106239 32 32 * Header Files * 33 33 *********************************************************************************************************************************/ 34 #define UNICODE /* For resource related macros. */ 34 35 #include <iprt/cdefs.h> 35 36 #include <iprt/win/windows.h> 37 #include <Wintrust.h> 38 #include <Softpub.h> 36 39 #ifndef ERROR_ELEVATION_REQUIRED /* Windows Vista and later. */ 37 40 # define ERROR_ELEVATION_REQUIRED 740 … … 43 46 #include "NoCrtOutput.h" 44 47 48 #ifdef VBOX_SIGNING_MODE 49 # include "BuildCert.h" 50 #endif 51 52 53 #ifdef VBOX_SIGNING_MODE 54 55 /** 56 * Checks the file signatures of both this stub program and the actual installer 57 * binary, making sure they use the same certificate as at build time and that 58 * the signature verifies correctly. 59 * 60 * @returns 0 on success, non-zero exit code on failure. 61 */ 62 static int CheckFileSignatures(wchar_t const *pwszExePath, HANDLE hFileExe, wchar_t const *pwszSelfPath, HANDLE hFileSelf) 63 { 64 /* 65 * Check the OS version (bypassing shims). 66 * 67 * The RtlGetVersion API was added in windows 2000, so it's precense is a 68 * provides a minimum OS version indicator already. 69 */ 70 LONG (__stdcall *pfnRtlGetVersion)(OSVERSIONINFOEXW *); 71 *(FARPROC *)&pfnRtlGetVersion = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); 72 if (!pfnRtlGetVersion) 73 { 74 /* double check it. */ 75 DWORD const dwVersion = GetVersion(); 76 if ((dwVersion & 0xff) < 5) 77 return 0; 78 return ErrorMsgRcSUS(40, "RtlGetVersion not present while Windows version is 5.0 or higher (", dwVersion, ")"); 79 } 80 OSVERSIONINFOEXW WinOsInfoEx = { sizeof(WinOsInfoEx) }; 81 NTSTATUS const rcNt = pfnRtlGetVersion(&WinOsInfoEx); 82 if (!RT_SUCCESS(rcNt)) 83 return ErrorMsgRcSU(41, "RtlGetVersion failed: ", rcNt); 84 85 /* Skip both of these checks if pre-XP. */ 86 if ( (WinOsInfoEx.dwMajorVersion == 5 && WinOsInfoEx.dwMinorVersion < 1) 87 || WinOsInfoEx.dwMajorVersion < 4) 88 return 0; 89 90 /* 91 * We need to find the system32 directory to load the WinVerifyTrust API. 92 */ 93 static wchar_t const s_wszSlashWinTrustDll[] = L"\\Wintrust.dll"; 94 95 /* Call GetSystemWindowsDirectoryW/GetSystemDirectoryW. */ 96 wchar_t wszSysDll[MAX_PATH + sizeof(s_wszSlashWinTrustDll)] = { 0 }; 97 UINT const cwcSystem32 = GetSystemDirectoryW(wszSysDll, MAX_PATH); 98 if (!cwcSystem32 || cwcSystem32 >= MAX_PATH) 99 return ErrorMsgRc(42, "GetSystemDirectoryW failed"); 100 101 /* Load it: */ 102 memcpy(&wszSysDll[cwcSystem32], s_wszSlashWinTrustDll, sizeof(s_wszSlashWinTrustDll)); 103 DWORD fLoadFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; 104 HMODULE hModWinTrustDll = LoadLibraryExW(wszSysDll, NULL, fLoadFlags); 105 if (!hModWinTrustDll && GetLastError() == ERROR_INVALID_PARAMETER) 106 { 107 fLoadFlags = 0; 108 hModWinTrustDll = LoadLibraryExW(wszSysDll, NULL, fLoadFlags); 109 } 110 if (!hModWinTrustDll) 111 return ErrorMsgRcSWSU(43, "Failed to load '", wszSysDll, "': ", GetLastError()); 112 113 /* Resolve API: */ 114 decltype(WinVerifyTrust) * const pfnWinVerifyTrust 115 = (decltype(WinVerifyTrust) *)GetProcAddress(hModWinTrustDll, "WinVerifyTrust"); 116 if (!pfnWinVerifyTrust) 117 return ErrorMsgRc(44, "WinVerifyTrust not found"); 118 119 /* 120 * We also need the Crypt32.dll for CryptQueryObject and CryptMsgGetParam. 121 */ 122 /* Load it: */ 123 static wchar_t const s_wszSlashCrypt32Dll[] = L"\\Crypt32.dll"; 124 AssertCompile(sizeof(s_wszSlashCrypt32Dll) <= sizeof(s_wszSlashWinTrustDll)); 125 memcpy(&wszSysDll[cwcSystem32], s_wszSlashCrypt32Dll, sizeof(s_wszSlashCrypt32Dll)); 126 HMODULE const hModCrypt32Dll = LoadLibraryExW(wszSysDll, NULL, fLoadFlags); 127 if (!hModCrypt32Dll) 128 return ErrorMsgRcSWSU(45, "Failed to load '", wszSysDll, "': ", GetLastError()); 129 130 /* Resolve APIs: */ 131 decltype(CryptQueryObject) * const pfnCryptQueryObject 132 = (decltype(CryptQueryObject) *)GetProcAddress(hModCrypt32Dll, "CryptQueryObject"); 133 if (!pfnCryptQueryObject) 134 return ErrorMsgRc(46, "CryptQueryObject not found"); 135 136 decltype(CryptMsgClose) * const pfnCryptMsgClose 137 = (decltype(CryptMsgClose) *)GetProcAddress(hModCrypt32Dll, "CryptMsgClose"); 138 if (!pfnCryptQueryObject) 139 return ErrorMsgRc(47, "CryptMsgClose not found"); 140 141 decltype(CryptMsgGetParam) * const pfnCryptMsgGetParam 142 = (decltype(CryptMsgGetParam) *)GetProcAddress(hModCrypt32Dll, "CryptMsgGetParam"); 143 if (!pfnCryptQueryObject) 144 return ErrorMsgRc(48, "CryptMsgGetParam not found"); 145 146 /* 147 * We'll verify the primary signer certificate first as that's something that 148 * should work even if SHA-256 isn't supported by the Windows crypto code. 149 */ 150 struct 151 { 152 HANDLE hFile; 153 wchar_t const *pwszFile; 154 155 DWORD fEncoding; 156 DWORD dwContentType; 157 DWORD dwFormatType; 158 HCERTSTORE hCertStore; 159 HCRYPTMSG hMsg; 160 161 DWORD cbCert; 162 uint8_t *pbCert; 163 } aExes[] = 164 { 165 { hFileSelf, pwszSelfPath, 0, 0, 0, NULL, NULL, 0, NULL }, 166 { hFileExe, pwszExePath, 0, 0, 0, NULL, NULL, 0, NULL }, 167 }; 168 169 HANDLE const hHeap = GetProcessHeap(); 170 int rcExit = 0; 171 for (unsigned i = 0; i < RT_ELEMENTS(aExes) && rcExit == 0; i++) 172 { 173 if (!pfnCryptQueryObject(CERT_QUERY_OBJECT_FILE, 174 aExes[i].pwszFile, 175 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, 176 CERT_QUERY_FORMAT_FLAG_BINARY, 177 0 /*fFlags*/, 178 &aExes[i].fEncoding, 179 &aExes[i].dwContentType, 180 &aExes[i].dwFormatType, 181 &aExes[i].hCertStore, 182 &aExes[i].hMsg, 183 NULL /*ppvContext*/)) 184 rcExit = ErrorMsgRcSWSU(50 + i*4, "CryptQueryObject/FILE on '", aExes[i].pwszFile, "': ", GetLastError()); 185 else if (!pfnCryptMsgGetParam(aExes[i].hMsg, CMSG_CERT_PARAM, 0, NULL, &aExes[i].cbCert)) 186 rcExit = ErrorMsgRcSWSU(51 + i*4, "CryptMsgGetParam/CMSG_CERT_PARAM/size failed on '", 187 aExes[i].pwszFile, "': ", GetLastError()); 188 else 189 { 190 DWORD const cbCert = aExes[i].cbCert; 191 aExes[i].pbCert = (uint8_t *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbCert); 192 if (!aExes[i].pbCert) 193 rcExit = ErrorMsgRcSUS(52 + i*4, "Out of memory (", cbCert, " bytes) for signing certificate information"); 194 else if (!pfnCryptMsgGetParam(aExes[i].hMsg, CMSG_CERT_PARAM, 0, aExes[i].pbCert, &aExes[i].cbCert)) 195 rcExit = ErrorMsgRcSWSU(53 + i*4, "CryptMsgGetParam/CMSG_CERT_PARAM failed on '", aExes[i].pwszFile, "': ", 196 GetLastError()); 197 } 198 } 199 200 if (rcExit == 0) 201 { 202 /* Do the two match? */ 203 if ( aExes[0].cbCert != aExes[1].cbCert 204 || memcmp(aExes[0].pbCert, aExes[1].pbCert, aExes[0].cbCert) != 0) 205 rcExit = ErrorMsgRcSWS(58, "The certificate on '", pwszExePath, "' does not match."); 206 /* The two match, now do they match the one we're expecting to use? */ 207 else if ( aExes[0].cbCert != g_cbBuildCert 208 || memcmp(aExes[0].pbCert, g_abBuildCert, g_cbBuildCert) != 0) 209 rcExit = ErrorMsgRcSWS(59, "The signing certificate of '", pwszExePath, "' differs from the build certificate"); 210 /* else: it all looks fine */ 211 } 212 213 /* cleanup */ 214 for (unsigned i = 0; i < RT_ELEMENTS(aExes); i++) 215 { 216 if (aExes[i].pbCert) 217 { 218 HeapFree(hHeap, 0, aExes[i].pbCert); 219 aExes[i].pbCert = NULL; 220 } 221 if (aExes[i].hMsg) 222 { 223 pfnCryptMsgClose(aExes[i].hMsg); 224 aExes[i].hMsg = NULL; 225 } 226 } 227 if (rcExit != 0) 228 return rcExit; 229 230 /* 231 * ASSUMING we're using SHA-256 for signing, we do a windows OS cutoff at Windows 7. 232 * For Windows Vista and older we skip this step. 233 */ 234 if ( (WinOsInfoEx.dwMajorVersion == 6 && WinOsInfoEx.dwMinorVersion == 0) 235 || WinOsInfoEx.dwMajorVersion < 6) 236 return 0; 237 238 /* 239 * Construct input WinVerifyTrust parameters and call it on each of the executables in turn. 240 * This code was borrowed from SUPHardNt. 241 */ 242 for (unsigned i = 0; i < RT_ELEMENTS(aExes); i++) 243 { 244 WINTRUST_FILE_INFO FileInfo = { 0 }; 245 FileInfo.cbStruct = sizeof(FileInfo); 246 FileInfo.pcwszFilePath = aExes[i].pwszFile; 247 FileInfo.hFile = aExes[i].hFile; 248 249 GUID PolicyActionGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2; 250 251 WINTRUST_DATA TrustData = { 0 }; 252 TrustData.cbStruct = sizeof(TrustData); 253 TrustData.fdwRevocationChecks = WTD_REVOKE_NONE; /* Keep simple for now. */ 254 TrustData.dwStateAction = WTD_STATEACTION_VERIFY; 255 TrustData.dwUIChoice = WTD_UI_NONE; 256 TrustData.dwProvFlags = 0; 257 if (WinOsInfoEx.dwMajorVersion >= 6) 258 TrustData.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL; 259 else 260 TrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE; 261 TrustData.dwUnionChoice = WTD_CHOICE_FILE; 262 TrustData.pFile = &FileInfo; 263 264 HRESULT hrc = pfnWinVerifyTrust(NULL /*hwnd*/, &PolicyActionGuid, &TrustData); 265 if (hrc != S_OK) 266 { 267 /* Translate the eror constant */ 268 const char *pszErrConst = NULL; 269 switch (hrc) 270 { 271 case TRUST_E_SYSTEM_ERROR: pszErrConst = "TRUST_E_SYSTEM_ERROR"; break; 272 case TRUST_E_NO_SIGNER_CERT: pszErrConst = "TRUST_E_NO_SIGNER_CERT"; break; 273 case TRUST_E_COUNTER_SIGNER: pszErrConst = "TRUST_E_COUNTER_SIGNER"; break; 274 case TRUST_E_CERT_SIGNATURE: pszErrConst = "TRUST_E_CERT_SIGNATURE"; break; 275 case TRUST_E_TIME_STAMP: pszErrConst = "TRUST_E_TIME_STAMP"; break; 276 case TRUST_E_BAD_DIGEST: pszErrConst = "TRUST_E_BAD_DIGEST"; break; 277 case TRUST_E_BASIC_CONSTRAINTS: pszErrConst = "TRUST_E_BASIC_CONSTRAINTS"; break; 278 case TRUST_E_FINANCIAL_CRITERIA: pszErrConst = "TRUST_E_FINANCIAL_CRITERIA"; break; 279 case TRUST_E_PROVIDER_UNKNOWN: pszErrConst = "TRUST_E_PROVIDER_UNKNOWN"; break; 280 case TRUST_E_ACTION_UNKNOWN: pszErrConst = "TRUST_E_ACTION_UNKNOWN"; break; 281 case TRUST_E_SUBJECT_FORM_UNKNOWN: pszErrConst = "TRUST_E_SUBJECT_FORM_UNKNOWN"; break; 282 case TRUST_E_SUBJECT_NOT_TRUSTED: pszErrConst = "TRUST_E_SUBJECT_NOT_TRUSTED"; break; 283 case TRUST_E_NOSIGNATURE: pszErrConst = "TRUST_E_NOSIGNATURE"; break; 284 case TRUST_E_FAIL: pszErrConst = "TRUST_E_FAIL"; break; 285 case TRUST_E_EXPLICIT_DISTRUST: pszErrConst = "TRUST_E_EXPLICIT_DISTRUST"; break; 286 case CERT_E_EXPIRED: pszErrConst = "CERT_E_EXPIRED"; break; 287 case CERT_E_VALIDITYPERIODNESTING: pszErrConst = "CERT_E_VALIDITYPERIODNESTING"; break; 288 case CERT_E_ROLE: pszErrConst = "CERT_E_ROLE"; break; 289 case CERT_E_PATHLENCONST: pszErrConst = "CERT_E_PATHLENCONST"; break; 290 case CERT_E_CRITICAL: pszErrConst = "CERT_E_CRITICAL"; break; 291 case CERT_E_PURPOSE: pszErrConst = "CERT_E_PURPOSE"; break; 292 case CERT_E_ISSUERCHAINING: pszErrConst = "CERT_E_ISSUERCHAINING"; break; 293 case CERT_E_MALFORMED: pszErrConst = "CERT_E_MALFORMED"; break; 294 case CERT_E_UNTRUSTEDROOT: pszErrConst = "CERT_E_UNTRUSTEDROOT"; break; 295 case CERT_E_CHAINING: pszErrConst = "CERT_E_CHAINING"; break; 296 case CERT_E_REVOKED: pszErrConst = "CERT_E_REVOKED"; break; 297 case CERT_E_UNTRUSTEDTESTROOT: pszErrConst = "CERT_E_UNTRUSTEDTESTROOT"; break; 298 case CERT_E_REVOCATION_FAILURE: pszErrConst = "CERT_E_REVOCATION_FAILURE"; break; 299 case CERT_E_CN_NO_MATCH: pszErrConst = "CERT_E_CN_NO_MATCH"; break; 300 case CERT_E_WRONG_USAGE: pszErrConst = "CERT_E_WRONG_USAGE"; break; 301 case CERT_E_UNTRUSTEDCA: pszErrConst = "CERT_E_UNTRUSTEDCA"; break; 302 case CERT_E_INVALID_POLICY: pszErrConst = "CERT_E_INVALID_POLICY"; break; 303 case CERT_E_INVALID_NAME: pszErrConst = "CERT_E_INVALID_NAME"; break; 304 case CRYPT_E_FILE_ERROR: pszErrConst = "CRYPT_E_FILE_ERROR"; break; 305 case CRYPT_E_REVOKED: pszErrConst = "CRYPT_E_REVOKED"; break; 306 } 307 if (pszErrConst) 308 rcExit = ErrorMsgRcSWSS(60 + i, "WinVerifyTrust failed on '", pwszExePath, "': ", pszErrConst); 309 else 310 rcExit = ErrorMsgRcSWSX(60 + i, "WinVerifyTrust failed on '", pwszExePath, "': ", hrc); 311 } 312 313 /* clean up state data. */ 314 TrustData.dwStateAction = WTD_STATEACTION_CLOSE; 315 FileInfo.hFile = NULL; 316 hrc = pfnWinVerifyTrust(NULL /*hwnd*/, &PolicyActionGuid, &TrustData); 317 } 318 319 return rcExit; 320 } 321 322 #endif /* VBOX_SIGNING_MODE */ 323 324 /** 325 * strstr for haystacks w/o null termination. 326 */ 327 static const char *MyStrStrN(const char *pchHaystack, size_t cbHaystack, const char *pszNeedle) 328 { 329 size_t const cchNeedle = strlen(pszNeedle); 330 char const chFirst = *pszNeedle; 331 if (cbHaystack >= cchNeedle) 332 { 333 cbHaystack -= cchNeedle - 1; 334 while (cbHaystack > 0) 335 { 336 const char *pchHit = (const char *)memchr(pchHaystack, chFirst, cbHaystack); 337 if (pchHit) 338 { 339 if (memcmp(pchHit, pszNeedle, cchNeedle) == 0) 340 return pchHit; 341 pchHit++; 342 cbHaystack -= pchHit - pchHaystack; 343 pchHaystack = pchHit; 344 } 345 else 346 break; 347 } 348 } 349 return NULL; 350 } 351 352 /** 353 * Check that the executable file is "related" the one for the current process. 354 */ 355 static int CheckThatFileIsRelated(wchar_t const *pwszExePath, wchar_t const *pwszSelfPath) 356 { 357 /* 358 * Start by checking version info. 359 */ 360 /* 361 * Query the version info for the files: 362 */ 363 DWORD const cbExeVerInfo = GetFileVersionInfoSizeW(pwszExePath, NULL); 364 if (!cbExeVerInfo) 365 return ErrorMsgRcSWSU(20, "GetFileVersionInfoSizeW failed on '", pwszExePath, "': ", GetLastError()); 366 367 DWORD const cbSelfVerInfo = GetFileVersionInfoSizeW(pwszSelfPath, NULL); 368 if (!cbSelfVerInfo) 369 return ErrorMsgRcSWSU(21, "GetFileVersionInfoSizeW failed on '", pwszSelfPath, "': ", GetLastError()); 370 371 HANDLE const hHeap = GetProcessHeap(); 372 DWORD const cbBothVerInfo = RT_ALIGN_32(cbExeVerInfo, 64) + RT_ALIGN_32(cbSelfVerInfo, 64); 373 void * const pvExeVerInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBothVerInfo); 374 void * const pvSelfVerInfo = (uint8_t *)pvExeVerInfo + RT_ALIGN_32(cbExeVerInfo, 64); 375 if (!pvExeVerInfo) 376 return ErrorMsgRcSUS(22, "Out of memory (", cbBothVerInfo, " bytes) for version info"); 377 378 int rcExit = 0; 379 if (!GetFileVersionInfoW(pwszExePath, 0, cbExeVerInfo, pvExeVerInfo)) 380 rcExit = ErrorMsgRcSWSU(23, "GetFileVersionInfoW failed on '", pwszExePath, "': ", GetLastError()); 381 else if (!GetFileVersionInfoW(pwszSelfPath, 0, cbSelfVerInfo, pvSelfVerInfo)) 382 rcExit = ErrorMsgRcSWSU(24, "GetFileVersionInfoW failed on '", pwszSelfPath, "': ", GetLastError()); 383 384 /* 385 * Compare the product and company strings, which should be identical. 386 */ 387 static struct 388 { 389 wchar_t const *pwszQueryItem; 390 const char *pszQueryErrorMsg1; 391 const char *pszCompareErrorMsg1; 392 } const s_aIdenticalItems[] = 393 { 394 { L"\\StringFileInfo\\040904b0\\ProductName", "VerQueryValueW/ProductName failed on '", "Product string of '" }, 395 { L"\\StringFileInfo\\040904b0\\CompanyName", "VerQueryValueW/CompanyName failed on '", "Company string of '" }, 396 }; 397 398 for (unsigned i = 0; i < RT_ELEMENTS(s_aIdenticalItems) && rcExit == 0; i++) 399 { 400 void *pvExeInfoItem = NULL; 401 UINT cbExeInfoItem = 0; 402 void *pvSelfInfoItem = NULL; 403 UINT cbSelfInfoItem = 0; 404 if (!VerQueryValueW(pvExeVerInfo, s_aIdenticalItems[i].pwszQueryItem, &pvExeInfoItem, &cbExeInfoItem)) 405 rcExit = ErrorMsgRcSWSU(25 + i*3, s_aIdenticalItems[i].pszQueryErrorMsg1 , pwszExePath, "': ", GetLastError()); 406 else if (!VerQueryValueW(pvSelfVerInfo, s_aIdenticalItems[i].pwszQueryItem, &pvSelfInfoItem, &cbSelfInfoItem)) 407 rcExit = ErrorMsgRcSWSU(26 + i*3, s_aIdenticalItems[i].pszQueryErrorMsg1, pwszSelfPath, "': ", GetLastError()); 408 else if ( cbExeInfoItem != cbSelfInfoItem 409 || memcmp(pvExeInfoItem, pvSelfInfoItem, cbSelfInfoItem) != 0) 410 rcExit = ErrorMsgRcSWS(27 + i*3, s_aIdenticalItems[i].pszCompareErrorMsg1, pwszExePath, "' does not match"); 411 } 412 413 HeapFree(hHeap, 0, pvExeVerInfo); 414 415 /* 416 * Check that the file has a manifest that looks like it may belong to 417 * an NSIS installer. 418 */ 419 if (rcExit == 0) 420 { 421 HMODULE hMod = LoadLibraryExW(pwszExePath, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); 422 if (!hMod && GetLastError() == ERROR_INVALID_PARAMETER) 423 hMod = LoadLibraryExW(pwszExePath, NULL, LOAD_LIBRARY_AS_DATAFILE); 424 if (hMod) 425 { 426 HRSRC const hRsrcMt = FindResourceExW(hMod, RT_MANIFEST, MAKEINTRESOURCEW(1), 427 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); 428 if (hRsrcMt) 429 { 430 DWORD const cbManifest = SizeofResource(hMod, hRsrcMt); 431 HGLOBAL const hGlobalMt = LoadResource(hMod, hRsrcMt); 432 if (hGlobalMt) 433 { 434 const char * const pchManifest = (const char *)LockResource(hGlobalMt); 435 if (pchManifest) 436 { 437 /* Just look for a few strings we expect to always find the manifest. */ 438 if (!MyStrStrN(pchManifest, cbManifest, "Nullsoft.NSIS.exehead")) 439 rcExit = 36; 440 else if (!MyStrStrN(pchManifest, cbManifest, "requestedPrivileges")) 441 rcExit = 37; 442 else if (!MyStrStrN(pchManifest, cbManifest, "highestAvailable")) 443 rcExit = 38; 444 if (rcExit) 445 rcExit = ErrorMsgRcSWSU(rcExit, "Manifest check of '", pwszExePath, "' failed: ", rcExit); 446 } 447 else 448 rcExit = ErrorMsgRc(35, "LockResource/Manifest failed"); 449 } 450 else 451 rcExit = ErrorMsgRcSU(34, "LoadResource/Manifest failed: ", GetLastError()); 452 } 453 else 454 rcExit = ErrorMsgRcSU(33, "FindResourceExW/Manifest failed: ", GetLastError()); 455 } 456 else 457 rcExit = ErrorMsgRcSWSU(32, "LoadLibraryExW of '", pwszExePath, "' as datafile failed: ", GetLastError()); 458 } 459 460 return rcExit; 461 } 45 462 46 463 static BOOL IsWow64(void) … … 137 554 if (cwcExePath == 0 || cwcExePath >= sizeof(wszExePath)) 138 555 return ErrorMsgRcLastErrSUR(13, "GetModuleFileNameW failed: ", cwcExePath); 556 557 WCHAR wszSelfPath[MAX_PATH]; 558 memcpy(wszSelfPath, wszExePath, sizeof(wszSelfPath)); 139 559 140 560 /* … … 221 641 222 642 /* 643 * Open the executable for this process. 644 */ 645 HANDLE hFileSelf = CreateFileW(wszSelfPath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttr*/, OPEN_EXISTING, 646 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OPEN_REPARSE_POINT, NULL); 647 if (hFileSelf == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER) 648 hFileSelf = CreateFileW(wszSelfPath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttr*/, OPEN_EXISTING, 649 FILE_ATTRIBUTE_NORMAL, NULL); 650 if (hFileSelf == INVALID_HANDLE_VALUE) 651 { 652 if (GetLastError() == ERROR_FILE_NOT_FOUND) 653 return ErrorMsgRcSW(17, "File not found: ", wszSelfPath); 654 return ErrorMsgRcSWSU(17, "Error opening '", wszSelfPath, "' for reading: ", GetLastError()); 655 } 656 657 658 /* 659 * Open the file we're about to execute. 660 */ 661 HANDLE hFileExe = CreateFileW(wszExePath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttr*/, OPEN_EXISTING, 662 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OPEN_REPARSE_POINT, NULL); 663 if (hFileExe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER) 664 hFileExe = CreateFileW(wszExePath, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttr*/, OPEN_EXISTING, 665 FILE_ATTRIBUTE_NORMAL, NULL); 666 if (hFileExe == INVALID_HANDLE_VALUE) 667 { 668 if (GetLastError() == ERROR_FILE_NOT_FOUND) 669 return ErrorMsgRcSW(18, "File not found: ", wszExePath); 670 return ErrorMsgRcSWSU(18, "Error opening '", wszExePath, "' for reading: ", GetLastError()); 671 } 672 673 /* 674 * Check that the file we're about to launch is related to us and safe to start. 675 */ 676 int rcExit = CheckThatFileIsRelated(wszExePath, wszSelfPath); 677 if (rcExit != 0) 678 return rcExit; 679 680 #ifdef VBOX_SIGNING_MODE 681 rcExit = CheckFileSignatures(wszExePath, hFileExe, wszSelfPath, hFileSelf); 682 if (rcExit != 0) 683 return rcExit; 684 #endif 685 686 /* 223 687 * Start the process. 224 688 */ 225 int rcExit = 0;226 689 STARTUPINFOW StartupInfo = { sizeof(StartupInfo), 0 }; 227 690 PROCESS_INFORMATION ProcInfo = { 0 }; -
trunk/src/VBox/Additions/WINNT/Installer/Loader/bldAddSignedDummy.cpp
r106221 r106239 1 1 /* $Id$ */ 2 2 /** @file 3 * V irtualBox Support Library- Dummy program for extracting signing certificate.3 * VBoxWindowsAdditions - Dummy program for extracting signing certificate. 4 4 */ 5 5
Note:
See TracChangeset
for help on using the changeset viewer.