2

我已经搜索了一种从数字签名的 PE 文件中检索信息的方法。我需要发布者、发布者链接、发行者名称和主题名称。我需要 winapi / c / c++ 代码(函数),我需要一个快速的方法,我不需要检查签名是否有效。

4

2 回答 2

7

这是我为我的一个项目编写的代码。它以 type 的结构返回详细信息NSIGINFO。随意使用它 - 无需署名,但如果您能保持版权完整,我将不胜感激。

如果缺少任何功能(我必须从几个不同的地方整合一些东西,所以我可能遗漏了一些东西)请告诉我,我会做出必要的调整。

让我知道这对你有用。祝你好运。

头文件,NAuthenticode.h

// NAuthenticode.h: Functions for checking signatures in files
//
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <nikb@bougalis.net>

#ifndef B82FBB5B_C0F8_43A5_9A31_619BB690706C
#define B82FBB5B_C0F8_43A5_9A31_619BB690706C

#include <wintrust.h>
#include <softpub.h>
#include <imagehlp.h>

struct NSIGINFO
{
    LONG lValidationResult;

    LPTSTR lpszPublisher;
    LPTSTR lpszPublisherEmail;
    LPTSTR lpszPublisherUrl;
    LPTSTR lpszAuthority;
    LPTSTR lpszFriendlyName;
    LPTSTR lpszProgramName;
    LPTSTR lpszPublisherLink;
    LPTSTR lpszMoreInfoLink;
    LPTSTR lpszSignature;
    LPTSTR lpszSerial;
    BOOL bHasSigTime;
    SYSTEMTIME stSigTime;
};

VOID NCertFreeSigInfo(NSIGINFO *pSigInfo);

BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle = INVALID_HANDLE_VALUE);

BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType,
    DWORD dwFlags, LPTSTR *lpszNameString);

BOOL NCheckFileCertificates(HANDLE hFile, 
    VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam);

#endif

实施,NAuthenticode.cpp

// NAuthenticode.cpp: Various routines related to validating file signatures
//
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <nikb@bougalis.net>


#include "stdafx.h"
#include "NAuthenticode.h"

//////////////////////////////////////////////////////////////////////////
#pragma comment(lib, "crypt32")
#pragma comment(lib, "imagehlp")
#pragma comment(lib, "wintrust")

//////////////////////////////////////////////////////////////////////////
#define SIG_ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)

//////////////////////////////////////////////////////////////////////////
// Some utility functions
LPVOID NHeapAlloc(SIZE_T dwBytes)
{
    if(dwBytes == 0)
        return NULL;

    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes);
}

//////////////////////////////////////////////////////////////////////////
LPVOID NHeapFree(LPVOID lpMem)
{
    if(lpMem != NULL)
        HeapFree(GetProcessHeap(), 0, lpMem);

    return NULL;
}

//////////////////////////////////////////////////////////////////////////
LPSTR NConvertW2A(LPCWSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

    int ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, NULL, 0, NULL, NULL);

    if(ret <= 0)
        return NULL;

    LPSTR lpszOutString = (LPSTR)NHeapAlloc((ret + 1) * sizeof(CHAR));

    if(lpszOutString == NULL)
        return NULL;

    ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, lpszOutString, ret, NULL, NULL);

    if(ret <= 0)
        lpszOutString = (LPSTR)NHeapFree(lpszOutString);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NDupString(LPCWSTR lpszString, int nLen)
{
    if(nLen == -1)
        nLen = (int)wcslen(lpszString);

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((2 + nLen) * sizeof(WCHAR));

    if((lpszOutString != NULL) && (nLen != 0))
        wcsncpy(lpszOutString, lpszString, nLen + 1);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPTSTR NConvertW2T(LPCWSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

#ifndef UNICODE
    return (LPTSTR)NConvertW2A(lpszString, nLen, nCodePage);
#else
    return (LPTSTR)NDupString(lpszString, nLen);
#endif
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NConvertA2W(LPCSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

    int ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, NULL, 0);

    if(ret <= 0)  
        return NULL;

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((ret + 1) * sizeof(WCHAR));

    if(lpszOutString == NULL)
        return NULL;

    ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, lpszOutString, ret);

    if(ret <= 0)
        lpszOutString = (LPWSTR)NHeapFree(lpszOutString);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NConvertT2W(LPCTSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

#ifndef UNICODE
    return NConvertA2W((LPCSTR)lpszString, nLen, nCodePage);
#else
    return NDupString((LPWSTR)lpszString, nLen);
#endif
}

//////////////////////////////////////////////////////////////////////////
VOID NCertFreeSigInfo(NSIGINFO *pSigInfo)
{
    if(pSigInfo == NULL)
        return;

    __try
    { // Be extra careful
        if(pSigInfo->lpszPublisher)
            pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszPublisherEmail)
            pSigInfo->lpszPublisherEmail = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherEmail);

        if(pSigInfo->lpszPublisherUrl)
            pSigInfo->lpszPublisherUrl = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherUrl);

        if(pSigInfo->lpszAuthority)
            pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority);

        if(pSigInfo->lpszProgramName)
            pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszPublisherLink)
            pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszMoreInfoLink)
            pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink);

        if(pSigInfo->lpszSignature)
            pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature);

        if(pSigInfo->lpszSerial)
            pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    }
}

//////////////////////////////////////////////////////////////////////////
static BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, LPTSTR *lpszNameString)
{
    if(pCertContext == NULL)
        return FALSE;

    DWORD dwData = CertGetNameString(pCertContext, dwType, 0, NULL, NULL, 0);

    if(dwData == 0)
        return FALSE;

    *lpszNameString = (LPTSTR)NHeapAlloc((dwData + 1) * sizeof(TCHAR));

    if(*lpszNameString == NULL)
        return FALSE;

    dwData = CertGetNameString(pCertContext, dwType, dwFlags, NULL, *lpszNameString, dwData);

    if(dwData == 0)
    {
        NHeapFree(*lpszNameString);
        return FALSE;
    }

    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in_bcount(cbEncoded) const BYTE *pbEncoded, __in DWORD cbEncoded,
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0)
{   
    if(((pBuffer == NULL) && (dwBuffer != 0)) || ((dwBuffer == 0) && (pBuffer != NULL)))
    { // What? You're passing a NULL pointer an a non-zero size? You so crazy!!!!
        ASSERT(FALSE);
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pbEncoded, cbEncoded, dwFlags, pBuffer, &dwBuffer);
}   

//////////////////////////////////////////////////////////////////////////
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in PCRYPT_ATTR_BLOB pObject,
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0)
{   
    if((pObject == NULL) || ((dwBuffer == 0) && (pBuffer != NULL)) || ((dwBuffer != 0) && (pBuffer == NULL)))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }   

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pObject->pbData, pObject->cbData, dwFlags, pBuffer, &dwBuffer);
}   

//////////////////////////////////////////////////////////////////////////
static BOOL WGetSignTimestamp(PCRYPT_ATTRIBUTES pAttributes, SYSTEMTIME &stTime, LPCSTR lpszObjId)
{
    if((pAttributes == NULL) || (pAttributes->cAttr == 0) || (lpszObjId == NULL) || (*lpszObjId == 0))
        return FALSE;

    for(DWORD dwAttr = 0; dwAttr < pAttributes->cAttr; dwAttr++)
    {           
        if(strcmp(lpszObjId, pAttributes->rgAttr[dwAttr].pszObjId) == 0)
        {               
            DWORD dwSize = sizeof(FILETIME);
            FILETIME ftCert;

            if(NCryptDecodeObject(lpszObjId, &pAttributes->rgAttr[dwAttr].rgValue[0], dwSize, (PVOID)&ftCert))
            {
                FILETIME ftLocal;

                if(FileTimeToLocalFileTime(&ftCert, &ftLocal) && FileTimeToSystemTime(&ftLocal, &stTime))
                    return TRUE;
            }
        }
    }

    return FALSE;
}

//////////////////////////////////////////////////////////////////////////
static BOOL NVerifyFileSignatureWorker(LPWSTR lpszFileName, WINTRUST_DATA &wtData, NSIGINFO *pSigInfo)
{
    if(pSigInfo != NULL)
        memset(pSigInfo, 0, sizeof(NSIGINFO));

    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;    
    BOOL bVerified = FALSE;

    LONG lRet = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &wtData);

    if(lRet != 0)
    {
        if(pSigInfo != NULL)
            pSigInfo->lValidationResult = lRet;

        return FALSE;
    }

    if(pSigInfo == NULL)
        return TRUE;

    HCERTSTORE hStore = NULL;
    HCRYPTMSG hMsg = NULL;

    if(!CryptQueryObject(CERT_QUERY_OBJECT_FILE, lpszFileName, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, &hStore, &hMsg, NULL))
        return FALSE;

    PCMSG_SIGNER_INFO pSignerInfo = NULL, pCounterSignerInfo = NULL;
    DWORD dwSignerInfo = 0, dwCounterSignerInfo = 0;

    if(CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo) && (dwSignerInfo != 0))
        pSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwSignerInfo);

    if((pSignerInfo != NULL) && CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo))
    {   
        for(DWORD dwAttr = 0; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++)
        {   
            if((strcmp(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) != 0))
                continue;

            PSPC_SP_OPUS_INFO pOpus = NULL;
            DWORD dwData = 0;

            if(NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData) && (dwData != 0))
                pOpus = (PSPC_SP_OPUS_INFO)NHeapAlloc(dwData);

            if((pOpus != NULL) && NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)pOpus))
            {     
                pSigInfo->lpszProgramName = NConvertW2T(pOpus->pwszProgramName);

                if(pOpus->pPublisherInfo != NULL)
                {
                    switch(pOpus->pPublisherInfo->dwLinkChoice)
                    {
                    case SPC_URL_LINK_CHOICE:
                        pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszUrl);
                        break;

                    case SPC_FILE_LINK_CHOICE:
                        pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszFile);
                        break;
                    }
                }

                if(pOpus->pMoreInfo != NULL)
                {
                    switch (pOpus->pMoreInfo->dwLinkChoice)
                    {
                    case SPC_URL_LINK_CHOICE:
                        pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszUrl);
                        break;

                    case SPC_FILE_LINK_CHOICE:
                        pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszFile);
                        break;
                    }
                }                                       
            }    

            if(pOpus != NULL)
                NHeapFree(pOpus);

            break;
        }

        CERT_INFO ci; 

        ci.Issuer = pSignerInfo->Issuer;
        ci.SerialNumber = pSignerInfo->SerialNumber;

        PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore, SIG_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&ci, NULL);

        if(pCertContext != NULL)
        {      
            if(pCertContext->pCertInfo->SerialNumber.cbData != 0)
            {
                pSigInfo->lpszSerial = (LPTSTR)NHeapAlloc(((pCertContext->pCertInfo->SerialNumber.cbData * 2) + 1) * sizeof(TCHAR));

                if(pSigInfo->lpszSerial != NULL)
                {
                    LPTSTR lpszPointer = pSigInfo->lpszSerial;

                    for(DWORD dwCount = pCertContext->pCertInfo->SerialNumber.cbData; dwCount != 0; dwCount--)
                        lpszPointer += _stprintf(lpszPointer, _T("%02X"), pCertContext->pCertInfo->SerialNumber.pbData[dwCount - 1]);
                }
            }

            if(!NCertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszFriendlyName))
                pSigInfo->lpszFriendlyName = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszAuthority))
                pSigInfo->lpszAuthority = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, &pSigInfo->lpszPublisher))
                pSigInfo->lpszPublisher = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_URL_TYPE, 0, &pSigInfo->lpszPublisherUrl))
                pSigInfo->lpszPublisherUrl = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_EMAIL_TYPE, 0, &pSigInfo->lpszPublisherEmail))
                pSigInfo->lpszPublisherEmail = NULL;

            CertFreeCertificateContext(pCertContext);
        }

        for(DWORD dwAttr = 0, dwData; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++)
        {           
            if((strcmp(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) == 0) && (pSignerInfo->AuthAttrs.rgAttr[dwAttr].cValue != 0))
            {   
                FILETIME ftCert;

                dwData = sizeof(FILETIME);

                if(NCryptDecodeObject(szOID_RSA_signingTime, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)&ftCert))
                {
                    FILETIME ftLocal;

                    if(!FileTimeToLocalFileTime(&ftCert, &ftLocal))
                    {
                        if(!FileTimeToSystemTime(&ftLocal, &pSigInfo->stSigTime))
                            memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME));
                    }                   
                }
            }           
        } 

        for(DWORD dwAttr = 0; dwAttr < pSignerInfo->UnauthAttrs.cAttr; dwAttr++)
        {
            if(strcmp(pSignerInfo->UnauthAttrs.rgAttr[dwAttr].pszObjId, szOID_RSA_counterSign) == 0)
            {
                if(NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo) && (dwCounterSignerInfo != 0))
                    pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwCounterSignerInfo);

                if((pCounterSignerInfo != NULL) && !NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo, pCounterSignerInfo))
                    pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapFree(pCounterSignerInfo);

                break;
            }
        }

        if(pCounterSignerInfo != NULL)
        {
            pSigInfo->bHasSigTime = WGetSignTimestamp(&pCounterSignerInfo->AuthAttrs, pSigInfo->stSigTime, szOID_RSA_signingTime);

            if(!pSigInfo->bHasSigTime)
                memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME));
        }   
    }   

    if(pSignerInfo != NULL)
        NHeapFree(pSignerInfo);

    if(pCounterSignerInfo != NULL)
        NHeapFree(pCounterSignerInfo);

    if(hStore != NULL)
        CertCloseStore(hStore, 0);

    if(hMsg != NULL)
        CryptMsgClose(hMsg);

    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle)
{
    if(pSigInfo != NULL)    
        memset(pSigInfo, 0, sizeof(NSIGINFO));

    if(lpszFileName == NULL)
        return FALSE;

    if((lpszFileName[0] != 0) && (_tcsnicmp(lpszFileName, _T("\\??\\"), 4) == 0))
        lpszFileName += 4;

    if(lpszFileName[0] == 0)
        return FALSE;

    LPWSTR lpwszFileName = NConvertT2W(lpszFileName);

    if(lpwszFileName == NULL)
        return FALSE;

    BOOL bOK = FALSE;

    __try
    { // be very careful... 
        WINTRUST_FILE_INFO wtFileInfo;
        memset(&wtFileInfo, 0, sizeof(WINTRUST_FILE_INFO));

        wtFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
        wtFileInfo.pcwszFilePath = lpwszFileName;

        if(hHandle != INVALID_HANDLE_VALUE)
            wtFileInfo.hFile = hHandle;

        WINTRUST_DATA wtData;
        memset(&wtData, 0, sizeof(WINTRUST_DATA));
        wtData.cbStruct = sizeof(WINTRUST_DATA);
        wtData.dwUIChoice = WTD_UI_NONE;
        wtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
        wtData.dwUnionChoice = WTD_CHOICE_FILE;
        wtData.pFile = &wtFileInfo;

        if(NVerifyFileSignatureWorker(lpwszFileName, wtData, pSigInfo))
            bOK = TRUE;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        if(pSigInfo != NULL)
        {
            if(pSigInfo->lpszPublisher)
                pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszAuthority)
                pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority);

            if(pSigInfo->lpszProgramName)
                pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszPublisherLink)
                pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszMoreInfoLink)
                pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink);

            if(pSigInfo->lpszSignature)
                pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature);

            if(pSigInfo->lpszSerial)
                pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial);
        }

        bOK = FALSE;
    }

    NHeapFree(lpwszFileName);

    return bOK;
}

//////////////////////////////////////////////////////////////////////////
BOOL NCheckFileCertificates(HANDLE hFile, VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam)
{
    DWORD dwCerts = 0;

    if(!ImageEnumerateCertificates(hFile, CERT_SECTION_TYPE_ANY, &dwCerts, NULL, 0))
        return FALSE;

    for(DWORD dwCount = 0; dwCount < dwCerts; dwCount++)
    {
        WIN_CERTIFICATE wcHdr;
        memset(&wcHdr, 0, sizeof(WIN_CERTIFICATE));
        wcHdr.dwLength = 0;
        wcHdr.wRevision = WIN_CERT_REVISION_1_0;

        if(!ImageGetCertificateHeader(hFile, dwCount, &wcHdr))
            return FALSE;

        DWORD dwLen = sizeof(WIN_CERTIFICATE) + wcHdr.dwLength;

        WIN_CERTIFICATE *pWinCert = (WIN_CERTIFICATE *)NHeapAlloc(dwLen);

        if(pWinCert == NULL)
            return FALSE;

        if(!ImageGetCertificateData(hFile, dwCount, pWinCert, &dwLen))
        { // problem getting certificate, return failure
            NHeapFree(pWinCert);
            return FALSE;
        }

        // extract the PKCS7 signed data     
        CRYPT_VERIFY_MESSAGE_PARA cvmp;
        memset(&cvmp, 0, sizeof(CRYPT_VERIFY_MESSAGE_PARA));
        cvmp.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
        cvmp.dwMsgAndCertEncodingType = SIG_ENCODING;

        PCCERT_CONTEXT pCertContext = NULL;

        if(!CryptVerifyMessageSignature(&cvmp, dwCount, pWinCert->bCertificate, pWinCert->dwLength, NULL, NULL, &pCertContext))
        {
            NHeapFree(pWinCert);
            return FALSE;
        }

        // Now, pass this context on to our callback function (if any)
        if(pCallback != NULL)
            pCallback(pCertContext, pParam);

        if(!CertFreeCertificateContext(pCertContext))
        {
            NHeapFree(pWinCert);
            return FALSE;
        }

        NHeapFree(pWinCert);
    }

    return TRUE;
}
于 2013-02-22T17:50:39.667 回答
4

Microsoft 在此支持链接中提供了一种方法:How To Get Information from Authenticode Signed Executables

您可以使用 WinVerifyTrust() API 来验证 Authenticode 签名的可执行文件。

尽管验证了签名,但程序可能还必须执行以下操作:

  • 确定签署可执行文件的证书的详细信息。
  • 确定文件加盖时间戳的日期和时间。
  • 检索与文件关联的 URL 链接。
  • 检索时间戳证书。

本文演示如何使用 CryptQueryObject() API 从 Authenticode 签名的可执行文件中检索详细信息。

于 2013-02-27T12:41:29.110 回答