Win32 API功能封装
+ -

获取应用程序数字签名

2021-08-30 185 0

一般的应用程序在正式发布前都会进行数字签名。
如我们经常听歌的酷狗音乐,其通过查看文件属性,可以看到数字签名如下:

数字签名

那么怎么通过编程来获取数字签名的内容?
数字签名的获取一般是需要动态载入以下DLL:

  • Wintrust.dll
  • Crypt32.dll

相关的函数

#define C_WinVerifyTrust    "WinVerifyTrust"
#define C_WTHelperProvDataFromStateData    "WTHelperProvDataFromStateData"
#define C_WTHelperGetProvSignerFromChain    "WTHelperGetProvSignerFromChain"
#define C_WTHelperGetProvCertFromChain        "WTHelperGetProvCertFromChain"
#define C_CertGetNameStringA                "CertGetNameStringA"

函数原型:

typedef    LONG(__stdcall *FUN_WinVerifyTrust)(HWND hwnd, GUID *pgActionID, LPVOID pWVTData);
typedef CRYPT_PROVIDER_DATA* (__stdcall *FUN_WTHelperProvDataFromStateData)(HANDLE hStateData);
typedef CRYPT_PROVIDER_SGNR * (__stdcall *FUN_WTHelperGetProvSignerFromChain)(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner, DWORD idxCounterSigner);
typedef CRYPT_PROVIDER_CERT * (__stdcall *FUN_WTHelperGetProvCertFromChain)(CRYPT_PROVIDER_SGNR *pSgnr,    DWORD idxCert);

typedef WINCRYPT32API DWORD(__stdcall * FUN_CertGetNameStringA)(PCCERT_CONTEXT pCertContext,DWORD dwType,DWORD dwFlags,void *pvTypePara,LPSTR pszNameString,DWORD cchNameString);

typedef HMODULE (__stdcall *FUN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef PVOID(__stdcall *FUN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);

全部代码如下:


#include <windows.h>
#include <Softpub.h>
#include <Wincrypt.h>


#define DLL_WINTRUST    "Wintrust.dll"
#define    DLL_CRYPT32        "Crypt32.dll"

#define C_WinVerifyTrust    "WinVerifyTrust"
#define C_WTHelperProvDataFromStateData    "WTHelperProvDataFromStateData"
#define C_WTHelperGetProvSignerFromChain    "WTHelperGetProvSignerFromChain"
#define C_WTHelperGetProvCertFromChain        "WTHelperGetProvCertFromChain"
#define C_CertGetNameStringA                "CertGetNameStringA"


typedef    LONG(__stdcall *FUN_WinVerifyTrust)(HWND hwnd, GUID *pgActionID, LPVOID pWVTData);
typedef CRYPT_PROVIDER_DATA* (__stdcall *FUN_WTHelperProvDataFromStateData)(HANDLE hStateData);
typedef CRYPT_PROVIDER_SGNR * (__stdcall *FUN_WTHelperGetProvSignerFromChain)(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner, DWORD idxCounterSigner);
typedef CRYPT_PROVIDER_CERT * (__stdcall *FUN_WTHelperGetProvCertFromChain)(CRYPT_PROVIDER_SGNR *pSgnr,    DWORD idxCert);

typedef WINCRYPT32API DWORD(__stdcall * FUN_CertGetNameStringA)(PCCERT_CONTEXT pCertContext,DWORD dwType,DWORD dwFlags,void *pvTypePara,LPSTR pszNameString,DWORD cchNameString);


typedef HMODULE (__stdcall *FUN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef PVOID(__stdcall *FUN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);

typedef struct _DLL_STRUCT
{
    FUN_LoadLibraryA pLoadLibraryA;
    FUN_GetProcAddress pGetProcAddress;
    char StrBuff[128];

    ULONG WinTrusDll;
    ULONG Crypt32Dll;
    ULONG WinVerifyTrust;
    ULONG WTHelperProvDataFromStateData;
    ULONG WTHelperGetProvSignerFromChain;
    ULONG WTHelperGetProvCertFromChain;
    ULONG CertGetNameStringA;
}DLL_STRUCT,*PDLL_STRUCT;

BOOL CheckProcessValid(WCHAR* pProcessName, PDLL_STRUCT pDllST)
{
    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_FILE_INFO sWintrustFileInfo;
    WINTRUST_DATA      sWintrustData;
    HRESULT            hr = 0;


    sWintrustFileInfo.cbStruct = 0;
    sWintrustFileInfo.hFile = 0;
    sWintrustFileInfo.pcwszFilePath = 0;
    sWintrustFileInfo.pgKnownSubject = 0;

    sWintrustData.cbStruct = 0;
    sWintrustData.dwProvFlags = 0;
    sWintrustData.dwStateAction = 0;
    sWintrustData.dwUIChoice = 0;
    sWintrustData.dwUnionChoice = 0;
    sWintrustData.fdwRevocationChecks = 0;
    sWintrustData.hWVTStateData = 0;
    sWintrustData.pBlob = 0;
    sWintrustData.pCatalog = 0;
    sWintrustData.pCert = 0;
    sWintrustData.pFile = 0;
    sWintrustData.pPolicyCallbackData = 0;
    sWintrustData.pSgnr = 0;
    sWintrustData.pSignatureSettings = 0;
    sWintrustData.pSIPClientData = 0;
    sWintrustData.pwszURLReference = 0;



    sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
    sWintrustFileInfo.pcwszFilePath = pProcessName;
    sWintrustFileInfo.hFile = NULL;

    sWintrustData.cbStruct = sizeof(WINTRUST_DATA);
    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    sWintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    sWintrustData.pFile = &sWintrustFileInfo;
    sWintrustData.dwStateAction = WTD_STATEACTION_VERIFY;



    HMODULE hWintrust = pDllST->pLoadLibraryA(DLL_WINTRUST);
    FUN_WinVerifyTrust pFUN_WinVerifyTrust = NULL;
    FUN_WTHelperProvDataFromStateData pWTHelperProvDataFromStateData = NULL;
    FUN_WTHelperGetProvSignerFromChain pWTHelperGetProvSignerFromChain = NULL;
    FUN_WTHelperGetProvCertFromChain pWTHelperGetProvCertFromChain = NULL;

    HMODULE hCrypt32 = pDllST->pLoadLibraryA(DLL_CRYPT32);
    FUN_CertGetNameStringA pCertGetNameStringA = NULL;

    do
    {
        if (hWintrust == NULL)
        {
            break;;
        }

        pFUN_WinVerifyTrust = (FUN_WinVerifyTrust)pDllST->pGetProcAddress(hWintrust, C_WinVerifyTrust);
        if (pFUN_WinVerifyTrust == NULL)
        {
            break;
        }
        pWTHelperProvDataFromStateData = (FUN_WTHelperProvDataFromStateData)pDllST->pGetProcAddress(hWintrust, C_WTHelperProvDataFromStateData);
        if (pWTHelperProvDataFromStateData == NULL)
        {
            break;
        }

        pWTHelperGetProvSignerFromChain = (FUN_WTHelperGetProvSignerFromChain)pDllST->pGetProcAddress(hWintrust, C_WTHelperGetProvSignerFromChain);
        if (pWTHelperGetProvSignerFromChain == NULL)
        {
            break;
        }

        pWTHelperGetProvCertFromChain = (FUN_WTHelperGetProvCertFromChain)pDllST->pGetProcAddress(hWintrust, C_WTHelperGetProvCertFromChain);
        if (pWTHelperGetProvCertFromChain == NULL)
        {
            break;
        }


        if (hCrypt32 == NULL)
        {
            break;
        }
        pCertGetNameStringA = (FUN_CertGetNameStringA)pDllST->pGetProcAddress(hCrypt32, C_CertGetNameStringA);
        if (pCertGetNameStringA == NULL)
        {
            break;
        }


        hr = pFUN_WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

        if (TRUST_E_NOSIGNATURE == hr)
        {
        //    _tprintf(_T("No signature found on the file.\n"));
            break;
        }
        else if (TRUST_E_BAD_DIGEST == hr)
        {
            //_tprintf(_T("The signature of the file is invalid\n"));
            break;
        }
        else if (TRUST_E_PROVIDER_UNKNOWN == hr)
        {
            //_tprintf(_T("No trust provider on this machine can verify this type of files.\n"));
            break;
        }
        else if (S_OK != hr)
        {
        //    _tprintf(_T("WinVerifyTrust failed with error 0x%.8X\n"), hr);
            break;
        }
        else
        {

            // retreive the signer certificate and display its information
            CRYPT_PROVIDER_DATA const *psProvData = NULL;
            CRYPT_PROVIDER_SGNR       *psProvSigner = NULL;
            CRYPT_PROVIDER_CERT       *psProvCert = NULL;
            FILETIME                   localFt;
            SYSTEMTIME                 sysTime;

            psProvData = pWTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
            if (psProvData)
            {
                psProvSigner = pWTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0, FALSE, 0);
                if (psProvSigner)
                {
                    FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
                    FileTimeToSystemTime(&localFt, &sysTime);

                    _tprintf(_T("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

                    psProvCert = pWTHelperGetProvCertFromChain(psProvSigner, 0);
                    if (psProvCert)
                    {
                        DWORD dwStrType;
                        DWORD dwCount;
                        LPTSTR szSubjectRDN = NULL;
                        char buff[2048] = { 0 };

                        dwStrType = CERT_X500_NAME_STR;
                        dwCount = pCertGetNameStringA(psProvCert->pCert,
                            CERT_NAME_RDN_TYPE,
                            0,
                            &dwStrType,
                            buff,
                            sizeof(buff));
                        printf("%s\n", buff);
                        dwCount = dwCount;
                    }


                }
            }
        }

    } while (0);

    if (hWintrust)
    {
        FreeLibrary(hWintrust);
    }

    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    PWCHAR pProcessName = L"D:\\KuGou.exe";

    DLL_STRUCT dll;
    dll.pLoadLibraryA = LoadLibraryA;
    dll.pGetProcAddress = (FUN_GetProcAddress)GetProcAddress;
    dll.WinTrusDll = 0;
    memcpy(dll.StrBuff + 0, DLL_WINTRUST, (ULONG)strlen(DLL_WINTRUST) + 1);

    dll.Crypt32Dll = dll.WinTrusDll + (ULONG)strlen(DLL_WINTRUST) + 1;
    memcpy(dll.StrBuff + dll.Crypt32Dll, DLL_CRYPT32, (ULONG)strlen(DLL_CRYPT32) + 1);

    dll.WinVerifyTrust = dll.Crypt32Dll + (ULONG)strlen(DLL_CRYPT32) + 1;
    memcpy(dll.StrBuff + dll.WinVerifyTrust, C_WinVerifyTrust, (ULONG)strlen(C_WinVerifyTrust) + 1);

    dll.WTHelperProvDataFromStateData = dll.WinVerifyTrust + (ULONG)strlen(C_WinVerifyTrust) + 1;
    memcpy(dll.StrBuff + dll.WTHelperProvDataFromStateData, C_WTHelperProvDataFromStateData, (ULONG)strlen(C_WTHelperProvDataFromStateData) + 1);

    dll.WTHelperGetProvSignerFromChain = dll.WTHelperProvDataFromStateData + (ULONG)strlen(C_WTHelperProvDataFromStateData) + 1;
    memcpy(dll.StrBuff + dll.WTHelperGetProvSignerFromChain, C_WTHelperGetProvSignerFromChain, (ULONG)strlen(C_WTHelperGetProvSignerFromChain) + 1);

    dll.WTHelperGetProvCertFromChain = dll.WTHelperGetProvSignerFromChain + (ULONG)strlen(C_WTHelperGetProvSignerFromChain) + 1;
    memcpy(dll.StrBuff + dll.WTHelperGetProvCertFromChain, C_WTHelperGetProvCertFromChain, (ULONG)strlen(C_WTHelperGetProvCertFromChain) + 1);

    dll.CertGetNameStringA = dll.WTHelperGetProvCertFromChain + (ULONG)strlen(C_WTHelperGetProvCertFromChain) + 1;
    memcpy(dll.StrBuff + dll.CertGetNameStringA, C_CertGetNameStringA, (ULONG)strlen(C_CertGetNameStringA) + 1);

    CheckProcessValid(pProcessName, &dll);

    return 0;
}

运行结果:

Signature Date = 13/08/2020 at 22:15:50
C=CN, S=Guangdong, L=Guangzhou, O="Guangzhou KuGou Computer Technology Co., Ltd.", OU=IT, CN="Guangzhou KuGou Computer Technology Co., Ltd."

运行结果

0 篇笔记 写笔记

获取应用程序数字签名
一般的应用程序在正式发布前都会进行数字签名。如我们经常听歌的酷狗音乐,其通过查看文件属性,可以看到数字签名如下:那么怎么通过编程来获取数字签名的内容?数字签名的获取一般是需要动态载入以下DLL:Wintrust.dllCrypt32.dll相关的函数#define C_WinVerify......
win10企业版64位如何永久禁用驱动数字签名
在win10下用一个命令就可以禁用驱动程序强制签名禁止强制签名,以管理员的身份运行cmd 执行以下命令bcdedit.exe /set nointegritychecks on恢复默认验证,执行如下命令即可:bcdedit.exe /set nointegritychecks off......
win10,Win11如何关闭数字签名认证
数字签名认证可以让系统不加载未经过WHQL或者EV授权的的驱动程序的加载。但是我们在实际使用过程中,经常要调试,所以关闭数字签名证书就很有必要。win10,Win11如何关闭数字签名认证1、在桌面开始菜单中击右键,在弹出的菜单中选择“以管理员身份运行命令行窗口”页面。2、在打开的命令窗口页面中输入......
Win11怎么禁用驱动程序强制签名? 关闭Win11驱动强制签名的技巧
什么是驱动程序签名驱动程序签名又叫做驱动程序的数字签名,它是由微软的Windows硬件设备质量实验室完成的。硬件开发商将自己的硬件设备和相应的驱动程序交给该实验室,由实验室对其进行测试,测试合格后实验室将在其驱动程序中添加数字签名。由于数字签名是由微软完成的。Win11设备只有安装了驱动才能正常使......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!