I need to verify if a driver is verified or not. Basically, do exactly what SigCheck (or the verify button in process explorer does) does in my code. I have been able, using WinVerifyTrust, to verify a driver that is signed with a certificate (it has a Digital Signatures tab). But for drivers that are WHQL signed i have not been able to verify. I noticed on Process Explorer that when a driver is WQHL it changes the company field to: Microsoft Windows Component Publisher. Any tips or where to look on how to verify a WQHL driver would be much appreciated.
Also, I tried WinVerifyTrust with the DRIVER_ACTION_VERIFY flag (it seemed to be what I wanted) but when I try it on a driver (i8042ptr.sys for instance). It returns CRYPT_E_FILE_ERROR. So maybe thats the right flag, but I'm sending in the wrong parameter.
Well, think I came up with a solution... found out I had to actually find the .CAT file.... not sure if anyone is familiar with this stuff. But, if you are, and see something that is not right, or could be improved, would greatly apprecieate the feedback. Thanks!
BOOL VerifyEmbeddedSignature(LPCWSTR pwszSourceFile)
{
LONG lStatus;
GUID WintrustVerifyGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
GUID DriverActionGuid = DRIVER_ACTION_VERIFY;
HANDLE hFile;
DWORD dwHash;
BYTE bHash[100];
HCATINFO hCatInfo;
HCATADMIN hCatAdmin;
WINTRUST_DATA wd = { 0 };
WINTRUST_FILE_INFO wfi = { 0 };
WINTRUST_CATALOG_INFO wci = { 0 };
////set up structs to verify files with cert signatures
memset(&wfi, 0, sizeof(wfi));
wfi.cbStruct = sizeof( WINTRUST_FILE_INFO );
wfi.pcwszFilePath = pwszSourceFile;
wfi.hFile = NULL;
wfi.pgKnownSubject = NULL;
memset(&wd, 0, sizeof(wd));
wd.cbStruct = sizeof( WINTRUST_DATA );
wd.dwUnionChoice = WTD_CHOICE_FILE;
wd.pFile = &wfi;
wd.dwUIChoice = WTD_UI_NONE;
wd.fdwRevocationChecks = WTD_REVOKE_NONE;
wd.dwStateAction = 0;
wd.dwProvFlags = WTD_SAFER_FLAG;
wd.hWVTStateData = NULL;
wd.pwszURLReference = NULL;
wd.pPolicyCallbackData = NULL;
wd.pSIPClientData = NULL;
wd.dwUIContext = 0;
lStatus = WinVerifyTrust( NULL, &WintrustVerifyGuid, &wd );
////if failed, try to verify using catalog files
if (lStatus != ERROR_SUCCESS)
{
//open the file
hFile = CreateFileW(pwszSourceFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
dwHash = sizeof(bHash);
if (!CryptCATAdminCalcHashFromFileHandle(hFile, &dwHash, bHash, 0))
{
CloseHandle(hFile);
return FALSE;
}
//Create a string form of the hash (used later in pszMemberTag)
LPWSTR pszMemberTag = new WCHAR[dwHash * 2 + 1];
for ( DWORD dw = 0; dw < dwHash; ++dw )
{
wsprintfW( &pszMemberTag[dw * 2], L"%02X", bHash[dw] );
}
if (!CryptCATAdminAcquireContext(&hCatAdmin, &DriverActionGuid, 0))
{
CloseHandle(hFile);
return FALSE;
}
//find the catalog which contains the hash
hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, bHash, dwHash, 0, NULL);
if ( hCatInfo )
{
CATALOG_INFO ci = { 0 };
CryptCATCatalogInfoFromContext( hCatInfo, &ci, 0 );
memset(&wci, 0, sizeof(wci));
wci.cbStruct = sizeof( WINTRUST_CATALOG_INFO );
wci.pcwszCatalogFilePath = ci.wszCatalogFile;
wci.pcwszMemberFilePath = pwszSourceFile;
wci.pcwszMemberTag = pszMemberTag;
memset(&wd, 0, sizeof(wd));
wd.cbStruct = sizeof( WINTRUST_DATA );
wd.dwUnionChoice = WTD_CHOICE_CATALOG;
wd.pCatalog = &wci;
wd.dwUIChoice = WTD_UI_NONE;
wd.fdwRevocationChecks = WTD_STATEACTION_VERIFY;
wd.dwProvFlags = 0;
wd.hWVTStateData = NULL;
wd.pwszURLReference = NULL;
wd.pPolicyCallbackData = NULL;
wd.pSIPClientData = NULL;
wd.dwUIContext = 0;
lStatus = WinVerifyTrust( NULL, &WintrustVerifyGuid, &wd );
CryptCATAdminReleaseCatalogContext( hCatAdmin, hCatInfo, 0 );
}
CryptCATAdminReleaseContext( hCatAdmin, 0 );
delete[] pszMemberTag;
CloseHandle(hFile);
}
if (lStatus != ERROR_SUCCESS)
return false;
else
return true;
}
No comments:
Post a Comment