郁金香灬老师 游戏安全  驱动 逆向调试 C/C++编程  脚本 UE4/UE5

找回密码
立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
发新帖
课程大纲和价格
官方联系方式2024在线课大纲QQ咨询

34万

积分

125

好友

132

主题
发表于 2023-6-7 18:52:57 | 查看: 3348| 回复: 0


提供一个示例代码,演示如何检查所有嵌入(和嵌套)叶子(不在证书链中间)证书。

BOOL CheckCertificateIssuer(HANDLE hWVTStateData, const std::set<CString> &stValidIssuers)
{
    CRYPT_PROVIDER_DATA *pCryptProvData = WTHelperProvDataFromStateData(hWVTStateData);
    CRYPT_PROVIDER_SGNR *pSigner = WTHelperGetProvSignerFromChain(pCryptProvData, 0, FALSE, 0);
    CRYPT_PROVIDER_CERT *pCert = WTHelperGetProvCertFromChain(pSigner, 0);

    CString sIssuer;
    int nLength = CertGetNameString(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
    if (!nLength)
    {
        ASSERT(FALSE && "Cannot get the length of the Issuer string");
        return FALSE;
    }

    if (!CertGetNameString(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, sIssuer.GetBuffer(nLength), nLength))
    {
        ASSERT(FALSE && "Cannot get the Issuer string");
        return FALSE;
    }
    sIssuer.ReleaseBuffer(nLength);
    if (stValidIssuers.find(sIssuer) == stValidIssuers.end())
    {
        ASSERT(FALSE && "Certificate issuer is invalid");
        return FALSE;
    }
    return TRUE;
}
BOOL CheckCertificate(CString filename)
{
    std::set<CString> stValidIssuers;
    stValidIssuers.insert(L"VeriSign Class 3 Code Signing 2010 CA");
    stValidIssuers.insert(L"Symantec Class 3 SHA256 Code Signing CA");

    bool UseStrongSigPolicy = false;

    DWORD Error = ERROR_SUCCESS;
    bool WintrustCalled = false;
    GUID GenericActionId = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_DATA WintrustData = {};
    WINTRUST_FILE_INFO FileInfo = {};
    WINTRUST_SIGNATURE_SETTINGS SignatureSettings = {};
    CERT_STRONG_SIGN_PARA StrongSigPolicy = {};

    // Setup data structures for calling WinVerifyTrust
    WintrustData.cbStruct = sizeof(WINTRUST_DATA);
    WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
    WintrustData.dwUIChoice = WTD_UI_NONE;
    WintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    WintrustData.dwUnionChoice = WTD_CHOICE_FILE;

    FileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO_);
    FileInfo.pcwszFilePath = filename;
    WintrustData.pFile = &FileInfo;

    //
    // First verify the primary signature (index 0) to determine how many secondary signatures
    // are present. We use WSS_VERIFY_SPECIFIC and dwIndex to do this, also setting
    // WSS_GET_SECONDARY_SIG_COUNT to have the number of secondary signatures returned.
    //
    SignatureSettings.cbStruct = sizeof(WINTRUST_SIGNATURE_SETTINGS);
    SignatureSettings.dwFlags = WSS_GET_SECONDARY_SIG_COUNT | WSS_VERIFY_SPECIFIC;
    SignatureSettings.dwIndex = 0;
    WintrustData.pSignatureSettings = &SignatureSettings;

    if (UseStrongSigPolicy != false)
    {
        StrongSigPolicy.cbSize = sizeof(CERT_STRONG_SIGN_PARA);
        StrongSigPolicy.dwInfoChoice = CERT_STRONG_SIGN_OID_INFO_CHOICE;
        StrongSigPolicy.pszOID = szOID_CERT_STRONG_SIGN_OS_CURRENT;
        WintrustData.pSignatureSettings->pCryptoPolicy = &StrongSigPolicy;
    }
    BOOL bResult = E_NOT_SET;
    TRACE(L"Verifying primary signature... ");
    Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
    WintrustCalled = true;
    if (Error == ERROR_SUCCESS)
    {
        if (CheckCertificateIssuer(WintrustData.hWVTStateData, stValidIssuers))
        {
            if (bResult == E_NOT_SET)
                bResult = TRUE;
        }
        else
        {
            bResult = FALSE;
        }

        TRACE(L"Success!\n");

        TRACE(L"Found %d secondary signatures\n", WintrustData.pSignatureSettings->cSecondarySigs);

        // Now attempt to verify all secondary signatures that were found
        for (DWORD x = 1; x <= WintrustData.pSignatureSettings->cSecondarySigs; x++)
        {
            TRACE(L"Verify secondary signature at index %d... ", x);

            // Need to clear the previous state data from the last call to WinVerifyTrust
            WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
            Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
            if (Error != ERROR_SUCCESS)
            {
                //No need to call WinVerifyTrust again
                WintrustCalled = false;
                TRACE(L"%s", utils::error::getText(Error));
                ASSERT(FALSE);
                break;
            }

            WintrustData.hWVTStateData = NULL;

            // Caller must reset dwStateAction as it may have been changed during the last call
            WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
            WintrustData.pSignatureSettings->dwIndex = x;
            Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
            if (Error != ERROR_SUCCESS)
            {
                TRACE(L"%s", utils::error::getText(Error));
                ASSERT(FALSE);
                break;
            }

            if (CheckCertificateIssuer(WintrustData.hWVTStateData, stValidIssuers))
            {
                if (bResult == E_NOT_SET)
                    bResult = TRUE;
            }
            else
            {
                bResult = FALSE;
            }


            TRACE(L"Success!\n");
        }
    }
    else
    {
        TRACE(utils::error::getText(Error));
        ASSERT(FALSE);
    }

    //
    // Caller must call WinVerifyTrust with WTD_STATEACTION_CLOSE to free memory
    // allocate by WinVerifyTrust
    //
    if (WintrustCalled != false)
    {
        WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
        WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
    }

    return bResult;

}
游戏安全课程 学员办理咨询联系QQ150330575 手机 139 9636 2600  免费课程 在 www.bilibili.com 搜 郁金香灬老师
您需要登录后才可以回帖 登录 | 立即注册

QQ咨询

QQ|Archiver|手机版|小黑屋|郁金香游戏技术

GMT+8, 2024-5-8 20:11 , Processed in 0.087924 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表