获取数字签名

  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #include <Mscat.h>  
  4. #include <wintrust.h>  
  5. #include <Softpub.h>  
  6. #include <assert.h>  
  7.   
  8. //删除数组  
  9. #define SafeDeleteArraySize(pData) { if(pData){delete []pData;pData=NULL;} }  
  10.   
  11. #pragma comment(lib, "Wintrust.lib")   
  12. #pragma comment(lib, "crypt32.lib")  
  13. #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)  
  14.   
  15.   
  16. //关闭文件重定向系统  
  17. BOOL DisableWow64FsRedirection(void)  
  18. {  
  19.     PVOID   pOldValue = NULL;  
  20.     typedef BOOL(WINAPI *pfnWow64DisableWow64FsRedirection)(PVOID *OldValue);  
  21.     static pfnWow64DisableWow64FsRedirection pWow64DisableWow64 = (pfnWow64DisableWow64FsRedirection)GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")), "Wow64DisableWow64FsRedirection");  
  22.   
  23.     //处理wow64  
  24.     //if (IsWowo64System())  
  25.     {  
  26.         if (pWow64DisableWow64)  
  27.         {  
  28.             return pWow64DisableWow64(&pOldValue);  
  29.         }  
  30.     }  
  31.   
  32.     return FALSE;  
  33. }  
  34.   
  35. //开启文件重定向系统  
  36. BOOL RevertWow64FsRedirection(void)  
  37. {  
  38.   
  39.     PVOID   pOldValue = NULL;  
  40.     typedef BOOL(WINAPI *pfnWow64RevertWow64FsRedirection)(PVOID OldValue);  
  41.     static pfnWow64RevertWow64FsRedirection pWow64RevertWow64 = (pfnWow64RevertWow64FsRedirection)GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")), "Wow64RevertWow64FsRedirection");  
  42.   
  43.     //if (IsWowo64System())  
  44.     {  
  45.         if (pWow64RevertWow64)  
  46.         {  
  47.             return pWow64RevertWow64(&pOldValue);  
  48.         }  
  49.     }  
  50.   
  51.     return FALSE;  
  52. }  
  53.   
  54. //带重定向打开文件  
  55. BOOL RedirectionCreateFile(const wchar_t* pFilePath, HANDLE& hFile)  
  56. {  
  57.     BOOL bRet = FALSE;  
  58.     assert(NULL != pFilePath);  
  59.   
  60.     //关闭文件重定向系统  
  61.     BOOL bDisableWow64FsRedirection = DisableWow64FsRedirection();  
  62.     hFile = CreateFile(pFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  
  63.     if (INVALID_HANDLE_VALUE != hFile)  
  64.     {  
  65.         bRet = TRUE;  
  66.     }  
  67.     //开启文件重定向系统  
  68.     if (bDisableWow64FsRedirection)  
  69.     {  
  70.         RevertWow64FsRedirection();  
  71.     }  
  72.     return bRet;  
  73. }  
  74.   
  75. //获取文件数字签名  
  76. wchar_t* GetCertName(wchar_t* pFilePath)  
  77. {  
  78.     HCERTSTORE hStore = NULL;  
  79.     HCRYPTMSG hMsg = NULL;  
  80.     PCCERT_CONTEXT pCertContext = NULL;  
  81.     BOOL bResult = FALSE;  
  82.     DWORD dwEncoding, dwContentType, dwFormatType;  
  83.     PCMSG_SIGNER_INFO pSignerInfo = NULL;  
  84.     DWORD dwSignerInfo = 0;  
  85.     CERT_INFO CertInfo;  
  86.     wchar_t* pCertName = NULL;  
  87.     DWORD dwData = 0;  
  88.     HANDLE hFile = INVALID_HANDLE_VALUE;  
  89.     DWORD NumberOfBytesRead = 0;  
  90.     DWORD dwFilesize = 0;  
  91.     BYTE* pBuff = NULL;  
  92.     BOOL bDisableWow64FsRedirection = FALSE;  
  93.     memset(&CertInfo, 0, sizeof(CertInfo));  
  94.     if (IsBadReadPtr(pFilePath, sizeof(DWORD)) != 0)  
  95.     {  
  96.         return NULL;  
  97.     }  
  98.   
  99.   
  100.     do  
  101.     {  
  102.   
  103.   
  104.         if (!RedirectionCreateFile(pFilePath, hFile))  
  105.             break;  
  106.   
  107.         dwFilesize = GetFileSize(hFile, NULL);  
  108.         pBuff = new BYTE[dwFilesize + 1];  
  109.         assert(NULL != pBuff);  
  110.         RtlZeroMemory(pBuff, dwFilesize + 1);  
  111.         if (ReadFile(hFile, pBuff, dwFilesize, &NumberOfBytesRead, NULL) == FALSE)  
  112.         {  
  113.             CloseHandle(hFile);  
  114.             break;  
  115.         }  
  116.         CloseHandle(hFile);  
  117.   
  118.       
  119.         CERT_BLOB Object = { 0 };  
  120.         Object.cbData = dwFilesize;  
  121.         Object.pbData = pBuff;  
  122.         bResult = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &Object  
  123.             , CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY  
  124.             , 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);  
  125.         if (!bResult)  
  126.         {  
  127.             // 如果失败,采用原有的判断方式再执行一遍,确保此次变更不会兼容以前的代码处理效果  
  128.             //关闭文件重定向系统  
  129.             bDisableWow64FsRedirection = DisableWow64FsRedirection();  
  130.             bResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE, pFilePath  
  131.                 , CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY  
  132.                 , 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);  
  133.             if (bDisableWow64FsRedirection)  
  134.             {  
  135.                 RevertWow64FsRedirection();  
  136.             }  
  137.             if (!bResult)break;  
  138.         }         
  139.   
  140.         bResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo);  
  141.         if (!bResult)break;  
  142.   
  143.         pSignerInfo = (PCMSG_SIGNER_INFO) new char[dwSignerInfo];  
  144.         if (NULL == pSignerInfo)break;  
  145.         ZeroMemory(pSignerInfo, dwSignerInfo);  
  146.   
  147.         bResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo);  
  148.         if (!bResult)break;  
  149.   
  150.         CertInfo.Issuer = pSignerInfo->Issuer;  
  151.         CertInfo.SerialNumber = pSignerInfo->SerialNumber;  
  152.         pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL);  
  153.         if (NULL == pCertContext)break;  
  154.   
  155.         dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);  
  156.         if (1 >= dwData)  
  157.             break;  
  158.   
  159.         pCertName = new wchar_t[dwData + 1];  
  160.         if (NULL == pCertName)break;  
  161.         ZeroMemory(pCertName, (dwData + 1) * sizeof(wchar_t));  
  162.   
  163.         if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pCertName, dwData)))  
  164.             break;  
  165.   
  166.   
  167.   
  168.     } while (FALSE);  
  169.   
  170.     SafeDeleteArraySize(pBuff);  
  171.     SafeDeleteArraySize(pSignerInfo);  
  172.     if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);  
  173.     if (hStore != NULL) CertCloseStore(hStore, 0);  
  174.     if (hMsg != NULL) CryptMsgClose(hMsg);  
  175.   
  176.     return pCertName;  
  177. }  
  178.   
  179. //检测文件是否有签名  
  180. wchar_t* GetFileCat(wchar_t* lpFileName)  
  181. {  
  182.     WINTRUST_DATA wd = { 0 };  
  183.     WINTRUST_FILE_INFO wfi = { 0 };  
  184.     WINTRUST_CATALOG_INFO wci = { 0 };  
  185.     CATALOG_INFO ci = { 0 };  
  186.     HCATADMIN hCatAdmin = NULL;  
  187.     HANDLE hFile = INVALID_HANDLE_VALUE;  
  188.     DWORD dwCnt = 0;  
  189.     PBYTE pbyHash = NULL;  
  190.     wchar_t* pszMemberTag = NULL;  
  191.     HCATINFO hCatInfo = NULL;  
  192.     HRESULT hr;  
  193.     static GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2;  
  194.     const GUID gSubsystem = DRIVER_ACTION_VERIFY;  
  195.     wchar_t* pCatalogFile = NULL;  
  196.   
  197.   
  198.   
  199.   
  200.     do  
  201.     {  
  202.   
  203.         if (!CryptCATAdminAcquireContext(&hCatAdmin, &gSubsystem, 0))  
  204.             break;  
  205.   
  206.         if (!RedirectionCreateFile(lpFileName, hFile))  
  207.             break;  
  208.   
  209.         if (CryptCATAdminCalcHashFromFileHandle(hFile, &dwCnt, pbyHash, 0) && dwCnt > 0 && ERROR_INSUFFICIENT_BUFFER == GetLastError())  
  210.         {  
  211.             pbyHash = new BYTE[dwCnt];  
  212.             ZeroMemory(pbyHash, dwCnt);  
  213.             if (CryptCATAdminCalcHashFromFileHandle(hFile, &dwCnt, pbyHash, 0) == FALSE)  
  214.             {  
  215.                 CloseHandle(hFile);  
  216.                 break;  
  217.             }  
  218.         }  
  219.         else  
  220.         {  
  221.             CloseHandle(hFile);  
  222.             break;  
  223.         }  
  224.         CloseHandle(hFile);  
  225.   
  226.         hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, pbyHash, dwCnt, 0, NULL);  
  227.         if (NULL == hCatInfo)  
  228.         {  
  229.             wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);  
  230.             wfi.pcwszFilePath = lpFileName;  
  231.             wfi.hFile = NULL;  
  232.             wfi.pgKnownSubject = NULL;  
  233.             wd.cbStruct = sizeof(WINTRUST_DATA);  
  234.             wd.dwUnionChoice = WTD_CHOICE_FILE;  
  235.             wd.pFile = &wfi;  
  236.             wd.dwUIChoice = WTD_UI_NONE;  
  237.             wd.fdwRevocationChecks = WTD_REVOKE_NONE;  
  238.             wd.dwStateAction = WTD_STATEACTION_IGNORE;  
  239.             wd.dwProvFlags = WTD_SAFER_FLAG;  
  240.             wd.hWVTStateData = NULL;  
  241.             wd.pwszURLReference = NULL;  
  242.         }  
  243.         else  
  244.         {  
  245.             if (CryptCATCatalogInfoFromContext(hCatInfo, &ci, 0))  
  246.             {  
  247.                 pszMemberTag = new wchar_t[dwCnt * 2 + 1];  
  248.                 ZeroMemory(pszMemberTag, (dwCnt * 2 + 1)*sizeof(wchar_t));  
  249.                 for (DWORD dw = 0; dw < dwCnt; ++dw)  
  250.                 {  
  251.                     wsprintfW(&pszMemberTag[dw * 2], L"%02X", pbyHash[dw]);  
  252.   
  253.                 }  
  254.   
  255.                 wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO);  
  256.                 wci.pcwszCatalogFilePath = ci.wszCatalogFile;  
  257.                 wci.pcwszMemberFilePath = lpFileName;  
  258.                 wci.pcwszMemberTag = pszMemberTag;  
  259.   
  260.                 wd.cbStruct = sizeof(WINTRUST_DATA);  
  261.                 wd.pCatalog = &wci;  
  262.                 wd.dwUIChoice = WTD_UI_NONE;  
  263.                 wd.dwUnionChoice = WTD_CHOICE_CATALOG;  
  264.                 wd.fdwRevocationChecks = WTD_STATEACTION_VERIFY;  
  265.                 wd.dwStateAction = WTD_STATEACTION_VERIFY;  
  266.                 wd.dwProvFlags = 0;  
  267.                 wd.hWVTStateData = NULL;  
  268.                 wd.pwszURLReference = NULL;  
  269.   
  270.             }  
  271.   
  272.   
  273.         }  
  274.   
  275.   
  276.         hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &action, &wd);  
  277.         if (SUCCEEDED(hr) || wcslen(ci.wszCatalogFile) > 0)  
  278.         {  
  279.             //返回cat文件  
  280.             pCatalogFile = new wchar_t[MAX_PATH];  
  281.             ZeroMemory(pCatalogFile, MAX_PATH*sizeof(wchar_t));  
  282.             CopyMemory(pCatalogFile, ci.wszCatalogFile, wcslen(ci.wszCatalogFile)*sizeof(wchar_t));  
  283.         }  
  284.         if (NULL != hCatInfo)  
  285.         {  
  286.             CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);  
  287.         }  
  288.   
  289.   
  290.     } while (FALSE);  
  291.   
  292.   
  293.     if (hCatAdmin)  
  294.     {  
  295.         CryptCATAdminReleaseContext(hCatAdmin, 0);  
  296.     }  
  297.   
  298.   
  299.   
  300.   
  301.     SafeDeleteArraySize(pbyHash);  
  302.     SafeDeleteArraySize(pszMemberTag);  
  303.     return pCatalogFile;  
  304. }  
  305.   
  306. //获取文件数字签名  
  307. wchar_t* GetFileCertName(wchar_t* pFilePath)  
  308. {  
  309.     wchar_t* pCertName = NULL;  
  310.     wchar_t* pCatFilePath = NULL;  
  311.   
  312.     //获取文件数字签名  
  313.     pCertName = GetCertName(pFilePath);  
  314.     if (pCertName == NULL)  
  315.     {  
  316.         //获取文件cat  
  317.         pCatFilePath = GetFileCat(pFilePath);  
  318.         if (pCatFilePath)  
  319.         {  
  320.             //获取cat文件数字签名  
  321.             pCertName = GetCertName(pCatFilePath);  
  322.         }  
  323.     }  
  324.   
  325.     SafeDeleteArraySize(pCatFilePath);  
  326.     return pCertName;  
  327. }  
  328.   
  329.   
  330. int main(void)  
  331. {  
  332.     getchar();  
  333.     GetFileCertName(L"C:\\Windows\\System32\\drivers\\http.sys");  
  334.     GetFileCertName(L"C:\\Windows\\System32\\drivers\\spsys.sys");  
  335.       
  336.   
  337.     getchar();  
  338.     getchar();  
  339.     return 0;  
  340. }  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值