验证PE文件数字签名是否有效
有时候加载文件前,需要先验证文件数字签名是否有效。
1 //------------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 // Example of verifying the embedded signature of a PE file by using 4 // the WinVerifyTrust function. 5 6 #define _UNICODE 1 7 #define UNICODE 1 8 9 #include <tchar.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <windows.h> 13 #include <Softpub.h> 14 #include <wincrypt.h> 15 #include <wintrust.h> 16 17 // Link with the Wintrust.lib file. 18 #pragma comment (lib, "wintrust") 19 20 BOOL VerifyEmbeddedSignature(LPCWSTR pwszSourceFile) 21 { 22 LONG lStatus; 23 DWORD dwLastError; 24 25 // Initialize the WINTRUST_FILE_INFO structure. 26 27 WINTRUST_FILE_INFO FileData; 28 memset(&FileData, 0, sizeof(FileData)); 29 FileData.cbStruct = sizeof(WINTRUST_FILE_INFO); 30 FileData.pcwszFilePath = pwszSourceFile; 31 FileData.hFile = NULL; 32 FileData.pgKnownSubject = NULL; 33 34 /* 35 WVTPolicyGUID specifies the policy to apply on the file 36 WINTRUST_ACTION_GENERIC_VERIFY_V2 policy checks: 37 38 1) The certificate used to sign the file chains up to a root 39 certificate located in the trusted root certificate store. This 40 implies that the identity of the publisher has been verified by 41 a certification authority. 42 43 2) In cases where user interface is displayed (which this example 44 does not do), WinVerifyTrust will check for whether the 45 end entity certificate is stored in the trusted publisher store, 46 implying that the user trusts content from this publisher. 47 48 3) The end entity certificate has sufficient permission to sign 49 code, as indicated by the presence of a code signing EKU or no 50 EKU. 51 */ 52 53 GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2; 54 WINTRUST_DATA WinTrustData; 55 56 // Initialize the WinVerifyTrust input data structure. 57 58 // Default all fields to 0. 59 memset(&WinTrustData, 0, sizeof(WinTrustData)); 60 61 WinTrustData.cbStruct = sizeof(WinTrustData); 62 63 // Use default code signing EKU. 64 WinTrustData.pPolicyCallbackData = NULL; 65 66 // No data to pass to SIP. 67 WinTrustData.pSIPClientData = NULL; 68 69 // Disable WVT UI. 70 WinTrustData.dwUIChoice = WTD_UI_NONE; 71 72 // No revocation checking. 73 WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; 74 75 // Verify an embedded signature on a file. 76 WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; 77 78 // Default verification. 79 WinTrustData.dwStateAction = 0; 80 81 // Not applicable for default verification of embedded signature. 82 WinTrustData.hWVTStateData = NULL; 83 84 // Not used. 85 WinTrustData.pwszURLReference = NULL; 86 87 // Default. 88 WinTrustData.dwProvFlags = WTD_SAFER_FLAG; 89 90 // This is not applicable if there is no UI because it changes 91 // the UI to accommodate running applications instead of 92 // installing applications. 93 WinTrustData.dwUIContext = 0; 94 95 // Set pFile. 96 WinTrustData.pFile = &FileData; 97 98 // WinVerifyTrust verifies signatures as specified by the GUID 99 // and Wintrust_Data. 100 lStatus = WinVerifyTrust( 101 NULL, 102 &WVTPolicyGUID, 103 &WinTrustData); 104 105 switch (lStatus) 106 { 107 case ERROR_SUCCESS: 108 /* 109 Signed file: 110 - Hash that represents the subject is trusted. 111 112 - Trusted publisher without any verification errors. 113 114 - UI was disabled in dwUIChoice. No publisher or 115 time stamp chain errors. 116 117 - UI was enabled in dwUIChoice and the user clicked 118 "Yes" when asked to install and run the signed 119 subject. 120 */ 121 wprintf_s(L"The file \"%s\" is signed and the signature " 122 L"was verified.\n", 123 pwszSourceFile); 124 break; 125 126 case TRUST_E_NOSIGNATURE: 127 // The file was not signed or had a signature 128 // that was not valid. 129 130 // Get the reason for no signature. 131 dwLastError = GetLastError(); 132 if (TRUST_E_NOSIGNATURE == dwLastError || 133 TRUST_E_SUBJECT_FORM_UNKNOWN == dwLastError || 134 TRUST_E_PROVIDER_UNKNOWN == dwLastError) 135 { 136 // The file was not signed. 137 wprintf_s(L"The file \"%s\" is not signed.\n", 138 pwszSourceFile); 139 } 140 else 141 { 142 // The signature was not valid or there was an error 143 // opening the file. 144 wprintf_s(L"An unknown error occurred trying to " 145 L"verify the signature of the \"%s\" file.\n", 146 pwszSourceFile); 147 } 148 149 break; 150 151 case TRUST_E_EXPLICIT_DISTRUST: 152 // The hash that represents the subject or the publisher 153 // is not allowed by the admin or user. 154 wprintf_s(L"The signature is present, but specifically " 155 L"disallowed.\n"); 156 break; 157 158 case TRUST_E_SUBJECT_NOT_TRUSTED: 159 // The user clicked "No" when asked to install and run. 160 wprintf_s(L"The signature is present, but not " 161 L"trusted.\n"); 162 break; 163 164 case CRYPT_E_SECURITY_SETTINGS: 165 /* 166 The hash that represents the subject or the publisher 167 was not explicitly trusted by the admin and the 168 admin policy has disabled user trust. No signature, 169 publisher or time stamp errors. 170 */ 171 wprintf_s(L"CRYPT_E_SECURITY_SETTINGS - The hash " 172 L"representing the subject or the publisher wasn't " 173 L"explicitly trusted by the admin and admin policy " 174 L"has disabled user trust. No signature, publisher " 175 L"or timestamp errors.\n"); 176 break; 177 178 default: 179 // The UI was disabled in dwUIChoice or the admin policy 180 // has disabled user trust. lStatus contains the 181 // publisher or time stamp chain error. 182 wprintf_s(L"Error is: 0x%x.\n", 183 lStatus); 184 break; 185 } 186 187 return true; 188 } 189 190 int _tmain(int argc, _TCHAR* argv[]) 191 { 192 if(argc > 1) 193 { 194 VerifyEmbeddedSignature(argv[1]); 195 } 196 197 return 0; 198 }