获取应用程序数字签名
2021-08-30
212
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."