How to verify the embedded signature of a Windows PE file?
By | Published: May 29, 2009
In this post, I’m introducing the API which can be used to verify the signature of a Portable Executable (PE) file under windows. The applications like Process Explorer allows to verify the signature of the executables.
We can do the same thing using it using WinVerifyTrust. MSDN has a samplesnippet on the usage of this API. Let me put the same snippet (with some small modifications).
See the snippet list. It’s necessary to use Wide Character string(UNICODE) path to the file to use this function.
[sourcecode language='cpp']
BOOLVerifyEmbeddedSignature(LPCWSTR pwszSourceFile)
{
LONG lStatus;
DWORD dwLastError;
// Initialize the WinVerifyTrust input data structure.
// Default all fields to 0.
memset(&WinTrustData, 0, sizeof(WinTrustData));
WinTrustData.cbStruct = sizeof(WinTrustData);
// This is not applicable if there is no UI because it changes
// the UI to accommodate running applications instead of
// installing applications.
WinTrustData.dwUIContext = 0;
// Set pFile.
WinTrustData.pFile = &FileData;
// WinVerifyTrust verifies signatures as specified by the GUID
// and Wintrust_Data.
lStatus = WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData);
switch (lStatus)
{
case ERROR_SUCCESS:
{
CString strMessage;
strMessage.Format( _T( “The file \”%s\” is signed and the signature was verified.\n”),
pwszSourceFile);
AfxMessageBox( strMessage );
bRet = TRUE;
break;
}
case TRUST_E_NOSIGNATURE:
// The file was not signed or had a signature
// that was not valid.
// Get the reason for no signature.
dwLastError = GetLastError();
if (TRUST_E_NOSIGNATURE == dwLastError ||
TRUST_E_SUBJECT_FORM_UNKNOWN == dwLastError ||
TRUST_E_PROVIDER_UNKNOWN == dwLastError)
{
CString strMessage;
// The file was not signed.
strMessage.Format( _T( “The file \”%s\” is not signed.\n”), pwszSourceFile);
AfxMessageBox( strMessage );
}
else
{
// The signature was not valid or there was an error
// opening the file.
CString strMessage;
strMessage.Format( _T( “An unknown error occurred trying to ”
L”verify the signature of the \”%s\” file.\n”),
pwszSourceFile);
AfxMessageBox(strMessage);
}
break;
case TRUST_E_EXPLICIT_DISTRUST:
// The hash that represents the subject or the publisher
// is not allowed by the admin or user.
AfxMessageBox(L”The signature is present, but specifically disallowed.\n”);
break;
case TRUST_E_SUBJECT_NOT_TRUSTED:
// The user clicked “No” when asked to install and run.
AfxMessageBox( _T( “The signature is present, but not trusted.\n”));
break;
case CRYPT_E_SECURITY_SETTINGS:
/*
The hash that represents the subject or the publisher
was not explicitly trusted by the admin and the
admin policy has disabled user trust. No signature,
publisher or time stamp errors.
*/
MessageBoxW(L”CRYPT_E_SECURITY_SETTINGS – The hash ”
L”representing the subject or the publisher wasn’t ”
L”explicitly trusted by the admin and admin policy ”
L”has disabled user trust. No signature, publisher ”
L”or timestamp errors.\n”);
break;
default:
// The UI was disabled in dwUIChoice or the admin policy
// has disabled user trust. lStatus contains the
// publisher or time stamp chain error.
{
CString strMessage;
strMessage.Format( _T( “Error is: 0x%x.\n”), lStatus );
AfxMessageBox( strMessage );
break;
}
}
return bRet;
}
[/sourcecode]
How to verify the embedded signature of a Windows PE file?
In this post, I’m introducing the API which can be used to verify the signature of a Portable Executable (PE) file under windows. The applications like Process Explorer allows to verify the signature of the executables.
We can do the same thing using it using WinVerifyTrust. MSDN has a samplesnippet on the usage of this API. Let me put the same snippet (with some small modifications).
See the snippet list. It’s necessary to use Wide Character string(UNICODE) path to the file to use this function.
[sourcecode language='cpp']
BOOLVerifyEmbeddedSignature(LPCWSTR pwszSourceFile)
{
LONG lStatus;
DWORD dwLastError;
BOOL bRet = FALSE;
WINTRUST_FILE_INFO FileData;
memset(&FileData, 0, sizeof(FileData));
FileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
FileData.pcwszFilePath = pwszSourceFile;
FileData.hFile = NULL;
FileData.pgKnownSubject = NULL;
GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA WinTrustData;
// Initialize the WinVerifyTrust input data structure.
// Default all fields to 0.
memset(&WinTrustData, 0, sizeof(WinTrustData));
WinTrustData.cbStruct = sizeof(WinTrustData);
WinTrustData.pPolicyCallbackData = NULL;
WinTrustData.pSIPClientData = NULL;
WinTrustData.dwUIChoice = WTD_UI_NONE;
WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
// Verify an embedded signature on a file.
WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
WinTrustData.dwStateAction = 0;
WinTrustData.hWVTStateData = NULL;
WinTrustData.pwszURLReference = NULL;
// Default.
WinTrustData.dwProvFlags = WTD_SAFER_FLAG;
// This is not applicable if there is no UI because it changes
// the UI to accommodate running applications instead of
// installing applications.
WinTrustData.dwUIContext = 0;
// Set pFile.
WinTrustData.pFile = &FileData;
// WinVerifyTrust verifies signatures as specified by the GUID
// and Wintrust_Data.
lStatus = WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData);
switch (lStatus)
{
case ERROR_SUCCESS:
{
CString strMessage;
strMessage.Format( _T( “The file \”%s\” is signed and the signature was verified.\n”),
pwszSourceFile);
AfxMessageBox( strMessage );
bRet = TRUE;
break;
}
case TRUST_E_NOSIGNATURE:
// The file was not signed or had a signature
// that was not valid.
// Get the reason for no signature.
dwLastError = GetLastError();
if (TRUST_E_NOSIGNATURE == dwLastError ||
TRUST_E_SUBJECT_FORM_UNKNOWN == dwLastError ||
TRUST_E_PROVIDER_UNKNOWN == dwLastError)
{
CString strMessage;
// The file was not signed.
strMessage.Format( _T( “The file \”%s\” is not signed.\n”), pwszSourceFile);
AfxMessageBox( strMessage );
}
else
{
// The signature was not valid or there was an error
// opening the file.
CString strMessage;
strMessage.Format( _T( “An unknown error occurred trying to ”
L”verify the signature of the \”%s\” file.\n”),
pwszSourceFile);
AfxMessageBox(strMessage);
}
break;
case TRUST_E_EXPLICIT_DISTRUST:
// The hash that represents the subject or the publisher
// is not allowed by the admin or user.
AfxMessageBox(L”The signature is present, but specifically disallowed.\n”);
break;
case TRUST_E_SUBJECT_NOT_TRUSTED:
// The user clicked “No” when asked to install and run.
AfxMessageBox( _T( “The signature is present, but not trusted.\n”));
break;
case CRYPT_E_SECURITY_SETTINGS:
/*
The hash that represents the subject or the publisher
was not explicitly trusted by the admin and the
admin policy has disabled user trust. No signature,
publisher or time stamp errors.
*/
MessageBoxW(L”CRYPT_E_SECURITY_SETTINGS – The hash ”
L”representing the subject or the publisher wasn’t ”
L”explicitly trusted by the admin and admin policy ”
L”has disabled user trust. No signature, publisher ”
L”or timestamp errors.\n”);
break;
default:
// The UI was disabled in dwUIChoice or the admin policy
// has disabled user trust. lStatus contains the
// publisher or time stamp chain error.
{
CString strMessage;
strMessage.Format( _T( “Error is: 0x%x.\n”), lStatus );
AfxMessageBox( strMessage );
break;
}
}
return bRet;
}
[/sourcecode]