zoukankan      html  css  js  c++  java
  • 判断PE文件的数字签名信息

    工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。

    因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而是一个比较好的方法,但是如果只是判断数字签名是否有效也不够,别人只要用自己的证书重新签名就可以了,所以需要判断证书签名者信息。

    验证文件数字签名是否有效可以使用函数 WinVerifyTrust

    取得文件数字签名证书信息需要使用函数 CryptQueryObject

    下面是一段从网上搜到的获得文件数字签名证书信息的代码:

    1 #include <windows.h>
    2 #include <wincrypt.h>
    3 #include <wintrust.h>
    4 #include <stdio.h>
    5 #include <tchar.h>
    6  #pragma comment(lib, "crypt32.lib")
    7  #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
    8 typedef struct {
    9 LPWSTR lpszProgramName;
    10 LPWSTR lpszPublisherLink;
    11 LPWSTR lpszMoreInfoLink;
    12 } SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;
    13 BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
    14 PSPROG_PUBLISHERINFO Info);
    15 BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);
    16 BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);
    17 BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,
    18 PCMSG_SIGNER_INFO *pCounterSignerInfo);
    19  int _tmain(int argc, TCHAR *argv[])
    20 {
    21 WCHAR szFileName[MAX_PATH];
    22 HCERTSTORE hStore = NULL;
    23 HCRYPTMSG hMsg = NULL;
    24 PCCERT_CONTEXT pCertContext = NULL;
    25 BOOL fResult;
    26 DWORD dwEncoding, dwContentType, dwFormatType;
    27 PCMSG_SIGNER_INFO pSignerInfo = NULL;
    28 PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
    29 DWORD dwSignerInfo;
    30 CERT_INFO CertInfo;
    31 SPROG_PUBLISHERINFO ProgPubInfo;
    32 SYSTEMTIME st;
    33 ZeroMemory(&ProgPubInfo, sizeof(ProgPubInfo));
    34 __try
    35 {
    36 if (argc != 2)
    37 {
    38 _tprintf(_T("Usage: SignedFileInfo <filename>\n"));
    39 return 0;
    40 }
    41 #ifdef UNICODE
    42 lstrcpynW(szFileName, argv[1], MAX_PATH);
    43  #else
    44 if (mbstowcs(szFileName, argv[1], MAX_PATH) == -1)
    45 {
    46 printf("Unable to convert to unicode.\n");
    47 __leave;
    48 }
    49  #endif
    50 // Get message handle and store handle from the signed file.
    51   fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
    52 szFileName,
    53 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
    54 CERT_QUERY_FORMAT_FLAG_BINARY,
    55 0,
    56 &dwEncoding,
    57 &dwContentType,
    58 &dwFormatType,
    59 &hStore,
    60 &hMsg,
    61 NULL);
    62 if (!fResult)
    63 {
    64 _tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError());
    65 __leave;
    66 }
    67 // Get signer information size.
    68   fResult = CryptMsgGetParam(hMsg,
    69 CMSG_SIGNER_INFO_PARAM,
    70 0,
    71 NULL,
    72 &dwSignerInfo);
    73 if (!fResult)
    74 {
    75 _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
    76 __leave;
    77 }
    78 // Allocate memory for signer information.
    79   pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
    80 if (!pSignerInfo)
    81 {
    82 _tprintf(_T("Unable to allocate memory for Signer Info.\n"));
    83 __leave;
    84 }
    85 // Get Signer Information.
    86 fResult = CryptMsgGetParam(hMsg,
    87 CMSG_SIGNER_INFO_PARAM,
    88 0,
    89 (PVOID)pSignerInfo,
    90 &dwSignerInfo);
    91 if (!fResult)
    92 {
    93 _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
    94 __leave;
    95 }
    96 // Get program name and publisher information from
    97 // signer info structure.
    98 if (GetProgAndPublisherInfo(pSignerInfo, &ProgPubInfo))
    99 {
    100 if (ProgPubInfo.lpszProgramName != NULL)
    101 {
    102 wprintf(L"Program Name : %s\n",
    103 ProgPubInfo.lpszProgramName);
    104 }
    105 if (ProgPubInfo.lpszPublisherLink != NULL)
    106 {
    107 wprintf(L"Publisher Link : %s\n",
    108 ProgPubInfo.lpszPublisherLink);
    109 }
    110 if (ProgPubInfo.lpszMoreInfoLink != NULL)
    111 {
    112 wprintf(L"MoreInfo Link : %s\n",
    113 ProgPubInfo.lpszMoreInfoLink);
    114 }
    115 }
    116 _tprintf(_T("\n"));
    117 // Search for the signer certificate in the temporary
    118 // certificate store.
    119 CertInfo.Issuer = pSignerInfo->Issuer;
    120 CertInfo.SerialNumber = pSignerInfo->SerialNumber;
    121 pCertContext = CertFindCertificateInStore(hStore,
    122 ENCODING,
    123 0,
    124 CERT_FIND_SUBJECT_CERT,
    125 (PVOID)&CertInfo,
    126 NULL);
    127 if (!pCertContext)
    128 {
    129 _tprintf(_T("CertFindCertificateInStore failed with %x\n"),
    130 GetLastError());
    131 __leave;
    132 }
    133 // Print Signer certificate information.
    134 _tprintf(_T("Signer Certificate:\n\n"));
    135 PrintCertificateInfo(pCertContext);
    136 _tprintf(_T("\n"));
    137 // Get the timestamp certificate signerinfo structure.
    138 if (GetTimeStampSignerInfo(pSignerInfo, &pCounterSignerInfo))
    139 {
    140 // Search for Timestamp certificate in the temporary
    141 // certificate store.
    142 CertInfo.Issuer = pCounterSignerInfo->Issuer;
    143 CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber;
    144 pCertContext = CertFindCertificateInStore(hStore,
    145 ENCODING,
    146 0,
    147 CERT_FIND_SUBJECT_CERT,
    148 (PVOID)&CertInfo,
    149 NULL);
    150 if (!pCertContext)
    151 {
    152 _tprintf(_T("CertFindCertificateInStore failed with %x\n"),
    153 GetLastError());
    154 __leave;
    155 }
    156 // Print timestamp certificate information.
    157 _tprintf(_T("TimeStamp Certificate:\n\n"));
    158 PrintCertificateInfo(pCertContext);
    159 _tprintf(_T("\n"));
    160 // Find Date of timestamp.
    161 if (GetDateOfTimeStamp(pCounterSignerInfo, &st))
    162 {
    163 _tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"),
    164 st.wMonth,
    165 st.wDay,
    166 st.wYear,
    167 st.wHour,
    168 st.wMinute);
    169 }
    170 _tprintf(_T("\n"));
    171 }
    172 }
    173 __finally
    174 {
    175 // Clean up.
    176 if (ProgPubInfo.lpszProgramName != NULL)
    177 LocalFree(ProgPubInfo.lpszProgramName);
    178 if (ProgPubInfo.lpszPublisherLink != NULL)
    179 LocalFree(ProgPubInfo.lpszPublisherLink);
    180 if (ProgPubInfo.lpszMoreInfoLink != NULL)
    181 LocalFree(ProgPubInfo.lpszMoreInfoLink);
    182 if (pSignerInfo != NULL) LocalFree(pSignerInfo);
    183 if (pCounterSignerInfo != NULL) LocalFree(pCounterSignerInfo);
    184 if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
    185 if (hStore != NULL) CertCloseStore(hStore, 0);
    186 if (hMsg != NULL) CryptMsgClose(hMsg);
    187 }
    188 return 0;
    189 }
    190 BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
    191 {
    192 BOOL fReturn = FALSE;
    193 LPTSTR szName = NULL;
    194 DWORD dwData;
    195 __try
    196 {
    197 // Print Serial Number.
    198 _tprintf(_T("Serial Number: "));
    199 dwData = pCertContext->pCertInfo->SerialNumber.cbData;
    200 for (DWORD n = 0; n < dwData; n++)
    201 {
    202 _tprintf(_T("%02x "),
    203 pCertContext->pCertInfo->SerialNumber.pbData[dwData - (n + 1)]);
    204 }
    205 _tprintf(_T("\n"));
    206 // Get Issuer name size.
    207 if (!(dwData = CertGetNameString(pCertContext,
    208 CERT_NAME_SIMPLE_DISPLAY_TYPE,
    209 CERT_NAME_ISSUER_FLAG,
    210 NULL,
    211 NULL,
    212 0)))
    213 {
    214 _tprintf(_T("CertGetNameString failed.\n"));
    215 __leave;
    216 }
    217 // Allocate memory for Issuer name.
    218 szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
    219 if (!szName)
    220 {
    221 _tprintf(_T("Unable to allocate memory for issuer name.\n"));
    222 __leave;
    223 }
    224 // Get Issuer name.
    225 if (!(CertGetNameString(pCertContext,
    226 CERT_NAME_SIMPLE_DISPLAY_TYPE,
    227 CERT_NAME_ISSUER_FLAG,
    228 NULL,
    229 szName,
    230 dwData)))
    231 {
    232 _tprintf(_T("CertGetNameString failed.\n"));
    233 __leave;
    234 }
    235 // print Issuer name.
    236 _tprintf(_T("Issuer Name: %s\n"), szName);
    237 LocalFree(szName);
    238 szName = NULL;
    239 // Get Subject name size.
    240 if (!(dwData = CertGetNameString(pCertContext,
    241 CERT_NAME_SIMPLE_DISPLAY_TYPE,
    242 0,
    243 NULL,
    244 NULL,
    245 0)))
    246 {
    247 _tprintf(_T("CertGetNameString failed.\n"));
    248 __leave;
    249 }
    250 // Allocate memory for subject name.
    251 szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
    252 if (!szName)
    253 {
    254 _tprintf(_T("Unable to allocate memory for subject name.\n"));
    255 __leave;
    256 }
    257 // Get subject name.
    258 if (!(CertGetNameString(pCertContext,
    259 CERT_NAME_SIMPLE_DISPLAY_TYPE,
    260 0,
    261 NULL,
    262 szName,
    263 dwData)))
    264 {
    265 _tprintf(_T("CertGetNameString failed.\n"));
    266 __leave;
    267 }
    268 // Print Subject Name.
    269 _tprintf(_T("Subject Name: %s\n"), szName);
    270 fReturn = TRUE;
    271 }
    272 __finally
    273 {
    274 if (szName != NULL) LocalFree(szName);
    275 }
    276 return fReturn;
    277 }
    278 LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
    279 {
    280 LPWSTR outputString = NULL;
    281 outputString = (LPWSTR)LocalAlloc(LPTR,
    282 (wcslen(inputString) + 1) * sizeof(WCHAR));
    283 if (outputString != NULL)
    284 {
    285 lstrcpyW(outputString, inputString);
    286 }
    287 return outputString;
    288 }
    289 BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
    290 PSPROG_PUBLISHERINFO Info)
    291 {
    292 BOOL fReturn = FALSE;
    293 PSPC_SP_OPUS_INFO OpusInfo = NULL;
    294 DWORD dwData;
    295 BOOL fResult;
    296 __try
    297 {
    298 // Loop through authenticated attributes and find
    299 // SPC_SP_OPUS_INFO_OBJID OID.
    300 for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
    301 {
    302 if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID,
    303 pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
    304 {
    305 // Get Size of SPC_SP_OPUS_INFO structure.
    306 fResult = CryptDecodeObject(ENCODING,
    307 SPC_SP_OPUS_INFO_OBJID,
    308 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
    309 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
    310 0,
    311 NULL,
    312 &dwData);
    313 if (!fResult)
    314 {
    315 _tprintf(_T("CryptDecodeObject failed with %x\n"),
    316 GetLastError());
    317 __leave;
    318 }
    319 // Allocate memory for SPC_SP_OPUS_INFO structure.
    320 OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData);
    321 if (!OpusInfo)
    322 {
    323 _tprintf(_T("Unable to allocate memory for Publisher Info.\n"));
    324 __leave;
    325 }
    326 // Decode and get SPC_SP_OPUS_INFO structure.
    327 fResult = CryptDecodeObject(ENCODING,
    328 SPC_SP_OPUS_INFO_OBJID,
    329 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
    330 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
    331 0,
    332 OpusInfo,
    333 &dwData);
    334 if (!fResult)
    335 {
    336 _tprintf(_T("CryptDecodeObject failed with %x\n"),
    337 GetLastError());
    338 __leave;
    339 }
    340 // Fill in Program Name if present.
    341 if (OpusInfo->pwszProgramName)
    342 {
    343 Info->lpszProgramName =
    344 AllocateAndCopyWideString(OpusInfo->pwszProgramName);
    345 }
    346 else
    347 Info->lpszProgramName = NULL;
    348 // Fill in Publisher Information if present.
    349 if (OpusInfo->pPublisherInfo)
    350 {
    351 switch (OpusInfo->pPublisherInfo->dwLinkChoice)
    352 {
    353 case SPC_URL_LINK_CHOICE:
    354 Info->lpszPublisherLink =
    355 AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);
    356 break;
    357 case SPC_FILE_LINK_CHOICE:
    358 Info->lpszPublisherLink =
    359 AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);
    360 break;
    361 default:
    362 Info->lpszPublisherLink = NULL;
    363 break;
    364 }
    365 }
    366 else
    367 {
    368 Info->lpszPublisherLink = NULL;
    369 }
    370 // Fill in More Info if present.
    371 if (OpusInfo->pMoreInfo)
    372 {
    373 switch (OpusInfo->pMoreInfo->dwLinkChoice)
    374 {
    375 case SPC_URL_LINK_CHOICE:
    376 Info->lpszMoreInfoLink =
    377 AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);
    378 break;
    379 case SPC_FILE_LINK_CHOICE:
    380 Info->lpszMoreInfoLink =
    381 AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);
    382 break;
    383 default:
    384 Info->lpszMoreInfoLink = NULL;
    385 break;
    386 }
    387 }
    388 else
    389 {
    390 Info->lpszMoreInfoLink = NULL;
    391 }
    392 fReturn = TRUE;
    393 break; // Break from for loop.
    394 } // lstrcmp SPC_SP_OPUS_INFO_OBJID
    395 } // for
    396 }
    397 __finally
    398 {
    399 if (OpusInfo != NULL) LocalFree(OpusInfo);
    400 }
    401 return fReturn;
    402 }
    403 BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st)
    404 {
    405 BOOL fResult;
    406 FILETIME lft, ft;
    407 DWORD dwData;
    408 BOOL fReturn = FALSE;
    409 // Loop through authenticated attributes and find
    410 // szOID_RSA_signingTime OID.
    411 for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
    412 {
    413 if (lstrcmpA(szOID_RSA_signingTime,
    414 pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
    415 {
    416 // Decode and get FILETIME structure.
    417 dwData = sizeof(ft);
    418 fResult = CryptDecodeObject(ENCODING,
    419 szOID_RSA_signingTime,
    420 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
    421 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
    422 0,
    423 (PVOID)&ft,
    424 &dwData);
    425 if (!fResult)
    426 {
    427 _tprintf(_T("CryptDecodeObject failed with %x\n"),
    428 GetLastError());
    429 break;
    430 }
    431 // Convert to local time.
    432 FileTimeToLocalFileTime(&ft, &lft);
    433 FileTimeToSystemTime(&lft, st);
    434 fReturn = TRUE;
    435 break; // Break from for loop.
    436 } //lstrcmp szOID_RSA_signingTime
    437 } // for
    438 return fReturn;
    439 }
    440 BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo)
    441 {
    442 PCCERT_CONTEXT pCertContext = NULL;
    443 BOOL fReturn = FALSE;
    444 BOOL fResult;
    445 DWORD dwSize;
    446 __try
    447 {
    448 *pCounterSignerInfo = NULL;
    449 // Loop through unathenticated attributes for
    450 // szOID_RSA_counterSign OID.
    451 for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++)
    452 {
    453 if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId,
    454 szOID_RSA_counterSign) == 0)
    455 {
    456 // Get size of CMSG_SIGNER_INFO structure.
    457 fResult = CryptDecodeObject(ENCODING,
    458 PKCS7_SIGNER_INFO,
    459 pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,
    460 pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,
    461 0,
    462 NULL,
    463 &dwSize);
    464 if (!fResult)
    465 {
    466 _tprintf(_T("CryptDecodeObject failed with %x\n"),
    467 GetLastError());
    468 __leave;
    469 }
    470 // Allocate memory for CMSG_SIGNER_INFO.
    471 *pCounterSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);
    472 if (!*pCounterSignerInfo)
    473 {
    474 _tprintf(_T("Unable to allocate memory for timestamp info.\n"));
    475 __leave;
    476 }
    477 // Decode and get CMSG_SIGNER_INFO structure
    478 // for timestamp certificate.
    479 fResult = CryptDecodeObject(ENCODING,
    480 PKCS7_SIGNER_INFO,
    481 pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,
    482 pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,
    483 0,
    484 (PVOID)*pCounterSignerInfo,
    485 &dwSize);
    486 if (!fResult)
    487 {
    488 _tprintf(_T("CryptDecodeObject failed with %x\n"),
    489 GetLastError());
    490 __leave;
    491 }
    492 fReturn = TRUE;
    493 break; // Break from for loop.
    494 }
    495 }
    496 }
    497 __finally
    498 {
    499 // Clean up.
    500 if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
    501 }
    502 return fReturn;
    503 }
  • 相关阅读:
    P1121 环状最大两段子段和
    无题
    cdoj 1485 柱爷搞子串 sam treap
    自然数幂和
    Gym 100341C AVL Trees NTT
    线性筛分解质因子
    codeforces 366 Ant Man dp
    UVALive 6914 Maze Mayhem 轮廓线dp
    hdu 5790 Prefix 字典树 主席树
    莫比乌斯反演个人小结
  • 原文地址:https://www.cnblogs.com/Quincy/p/1775217.html
Copyright © 2011-2022 走看看