我有一個應用程序試圖驗證mmc.exe(服務)簽名。 (我認爲應用程序的上下文無關緊要)我嘗試使用winapi函數,這兩個函數都失敗,並且WinVerifyTrust爲 。當我嘗試從目錄中進行驗證時,我收到了TRUST_E_BAD_DIGEST,當從文件信息中嘗試時,我收到了TRUST_E_NOSIGNATURE 。提及我的功能在win7,XP上成功,但在win8上失敗是非常重要的。在Windows 8上從mmc.exe獲取數字簽名
這是功能
CATALOG_INFO InfoStruct = {0};
InfoStruct.cbStruct = sizeof(CATALOG_INFO);
WINTRUST_CATALOG_INFO WintrustCatalogStructure = {0};
WintrustCatalogStructure.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
WINTRUST_FILE_INFO WintrustFileStructure = {0};
WintrustFileStructure.cbStruct = sizeof(WINTRUST_FILE_INFO);
GUID ActionGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
//Get a context for signature verification.
HCATADMIN Context = NULL;
if(!::CryptCATAdminAcquireContext(&Context, NULL, 0)){
return false;
}
//Open file.
cx_handle hFile(::CreateFileW(filename_.c_str(), GENERIC_READ, 7, NULL, OPEN_EXISTING, 0, NULL));
if(INVALID_HANDLE_VALUE == (HANDLE)hFile)
{
CryptCATAdminReleaseContext(Context, 0);
return false;
}
//Get the size we need for our hash.
DWORD HashSize = 0;
::CryptCATAdminCalcHashFromFileHandle(hFile, &HashSize, NULL, 0);
if(HashSize == 0)
{
//0-sized has means error!
::CryptCATAdminReleaseContext(Context, 0);
return false;
}
//Allocate memory.
buffer hashbuf(HashSize);
//Actually calculate the hash
if(!CryptCATAdminCalcHashFromFileHandle(hFile, &HashSize, hashbuf.data, 0))
{
CryptCATAdminReleaseContext(Context, 0);
return false;
}
//Convert the hash to a string.
buffer MemberTag(((HashSize * 2) + 1) * sizeof(wchar_t));
for(unsigned int i = 0; i < HashSize; i++){
swprintf(&((PWCHAR)MemberTag.data)[i * 2], L"%02X", hashbuf.data[i ]);
}
//Get catalog for our context.
HCATINFO CatalogContext = CryptCATAdminEnumCatalogFromHash(Context, hashbuf, HashSize, 0, NULL);
if (CatalogContext)
{
//If we couldn't get information
if (!CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0))
{
//Release the context and set the context to null so it gets picked up below.
CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);
CatalogContext = NULL;
}
}
//If we have a valid context, we got our info.
//Otherwise, we attempt to verify the internal signature.
WINTRUST_DATA WintrustStructure = {0};
WintrustStructure.cbStruct = sizeof(WINTRUST_DATA);
if(!CatalogContext)
{
load_signature_verification_from_file_info(WintrustFileStructure, WintrustStructure);
}
else
{
load_signature_verification_from_catalog(WintrustStructure, WintrustCatalogStructure, InfoStruct, MemberTag);
}
//Call our verification function.
long verification_res = ::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
//Check return.
bool is_success = SUCCEEDED(verification_res) ? true : false;
// if failed with CatalogContext, try with FILE_INFO
if(!is_success && CatalogContext && verification_res != TRUST_E_NOSIGNATURE)
{
//warning2(L"Failed verification with Catalog Context: 0x%x %s ; Retrying with FILE_INFO.", verification_res, (const wchar_t*)format_last_error(verification_res));
load_signature_verification_from_file_info(WintrustFileStructure, WintrustStructure);
verification_res = ::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
is_success = SUCCEEDED(verification_res) ? true : false;
}
if(perr && !is_success && verification_res != TRUST_E_NOSIGNATURE)
{
perr->code = verification_res;
perr->description = format_last_error(verification_res);
}
//Free context.
if(CatalogContext){
::CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);
}
//If we successfully verified, we need to free.
if(is_success)
{
WintrustStructure.dwStateAction = WTD_STATEACTION_CLOSE;
::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
}
::CryptCATAdminReleaseContext(Context, 0);
return is_success;
我不認爲任何事情的代碼片段在此功能就變也從Win7贏得8等什麼可能出問題?
UPDATE
我也注意到,我的功能確實爲任務管理器工作在贏8 但再次爲MMC這是行不通的。
是有辦法避免使用那些功能?我不確定他們是否支持win xp和win 7. – whIsrael 2014-10-06 15:27:13
@whIsrael你是對的;根據文檔,它們只能在Windows 8/Windows Server 2012及更高版本上使用。所以...只是不要打電話給他們。所有這些函數都是手動動態鏈接的,因此有條件地調用正確的代碼路徑。 – 2014-10-06 15:39:43