尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

解析 Authenticode 部分代码。

解析 Authenticode 部分代码。
📅 发布时间:2026/6/19 10:19:40
#include "base/strings/utf_string_conversions.h"
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif#define WINCRYPT_USE_SYMBOL_PREFIX#include <Windows.h>#include <ImageHlp.h>#include "base/command_line.h"
#include "base/containers/heap_array.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"//
#include "third_party/boringssl/src/crypto/x509/internal.h"
#include "third_party/boringssl/src/include/openssl/asn1.h"
#include "third_party/boringssl/src/include/openssl/asn1t.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/x509.h"#include "third_party/boringssl/src/pki/parser.h"namespace switches {
constexpr char kInput[] = "input";
}constexpr uint8_t kOidSpcIndirectDataContent[] = {0x2b, 0x06, 0x01, 0x04, 0x01,0x82, 0x37, 0x02, 0x01, 0x04};  //  1.3.6.1.4.1.311.2.1.4constexpr uint8_t kOidSpcPEImageData[] = {0x2b, 0x06, 0x01, 0x04, 0x01,0x82, 0x37, 0x02, 0x01, 0x0F};  // 1.3.6.1.4.1.311.2.1.15constexpr uint8_t kOidPKCS7SignedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,0x0d, 0x01, 0x07, 0x02};  // 1.2.840.113549.1.7.2// SpcAttributeTypeAndOptionalValue ::= SEQUENCE {
//     type                    ObjectID,
//     value                   [0] EXPLICIT ANY OPTIONAL
// }// SpcPeImageData ::= SEQUENCE {
//    flags                   SpcPeImageFlags DEFAULT { includeResources },
//    file                    SpcLink
// } --#public--// SpcPeImageFlags ::= BIT STRING {
//     includeResources            (0),
//     includeDebugInfo            (1),
//     includeImportAddressTable   (2)
// }// SpcLink ::= CHOICE {
//     url                     [0] IMPLICIT IA5STRING,
//     moniker                 [1] IMPLICIT SpcSerializedObject,
//     file                    [2] EXPLICIT SpcString
// } --#public--// SpcString ::= CHOICE {
//     unicode                 [0] IMPLICIT BMPSTRING,
//     ascii                   [1] IMPLICIT IA5STRING
// }bool Parse_SpcString(CBS* cbs) {if (CBS_peek_asn1_tag(cbs, CBS_ASN1_CONTEXT_SPECIFIC | 0)) {  // unicodeCBS child;if (!CBS_get_asn1(cbs, &child, CBS_ASN1_CONTEXT_SPECIFIC | 0)) {LOG(ERROR) << "Failed to parse unicode SpcString";return false;}if (CBS_len(&child) == 0) {LOG(INFO) << "SpcString (unicode): <empty>";return true;}CBS str;if (!CBS_get_asn1(&child, &str, CBS_ASN1_BMPSTRING)) {LOG(ERROR) << "Failed to parse unicode SpcString";return false;}std::u16string u16_str(reinterpret_cast<const char16_t*>(CBS_data(&str)),CBS_len(&str) / sizeof(char16_t));std::string u8_str = base::UTF16ToUTF8(u16_str);LOG(INFO) << "SpcString (unicode): " << u8_str;} else if (CBS_peek_asn1_tag(cbs, CBS_ASN1_CONTEXT_SPECIFIC | 1)) {  // asciiCBS child;CBS str;if (!CBS_get_asn1(cbs, &child, CBS_ASN1_CONTEXT_SPECIFIC | 1) ||!CBS_get_asn1(&child, &str, CBS_ASN1_IA5STRING)) {LOG(ERROR) << "Failed to parse ascii SpcString";return false;}std::string u8_str(reinterpret_cast<const char*>(CBS_data(&str)),CBS_len(&str));LOG(INFO) << "SpcString (ascii): " << u8_str;} else {LOG(ERROR) << "Failed to parse SpcString choice";return false;}if (CBS_len(cbs) != 0) {LOG(ERROR) << "Trailing data in SpcString";return false;}return true;
}bool Parse_Authenticode_SpcPeImageData(CBS* cbs) {// SpcPeImageData ::= SEQUENCE {//    flags                   SpcPeImageFlags DEFAULT { includeResources },//    file                    SpcLink// } --#public--//// flags SpcPeImageFlags DEFAULT { includeResources },//// SpcPeImageFlags ::= BIT STRING {//     includeResources            (0),//     includeDebugInfo            (1),//     includeImportAddressTable   (2)// }CBS flags;if (!CBS_get_asn1(cbs, &flags, CBS_ASN1_BITSTRING)) {LOG(ERROR) << "Failed to parse flags";return false;}if (CBS_len(&flags) > 1) {const uint8_t* flag_bytes = CBS_data(&flags) + 1;// includeResources is bit 0.if (flag_bytes[0] & 0x80) {LOG(INFO) << "Flag: includeResources";}// includeDebugInfo is bit 1.if (flag_bytes[0] & 0x40) {LOG(INFO) << "Flag: includeDebugInfo";}// includeImportAddressTable is bit 2.if (flag_bytes[0] & 0x20) {LOG(INFO) << "Flag: includeImportAddressTable";}} else {LOG(INFO) << "Flags: default (includeResources)";}// file SpcLink// SpcLink ::= CHOICE {//     url                     [0] IMPLICIT IA5STRING,//     moniker                 [1] IMPLICIT SpcSerializedObject,//     file                    [2] EXPLICIT SpcString// } --#public--CBS spc_link;if (!CBS_get_asn1(cbs, &spc_link,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {LOG(ERROR) << "Failed to parse SpcLink wrapper";return false;}if (CBS_peek_asn1_tag(&spc_link, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {  // urlCBS child;CBS url;if (!CBS_get_asn1(&spc_link, &child,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||!CBS_get_asn1(&child, &url, CBS_ASN1_IA5STRING)) {LOG(ERROR) << "Failed to parse url";return false;} else {LOG(INFO) << "SpcLink (url): "<< std::string(reinterpret_cast<const char*>(CBS_data(&url)),CBS_len(&url));}} else if (CBS_peek_asn1_tag(&spc_link, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {CBS child;CBS moniker;if (!CBS_get_asn1(&spc_link, &child,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1) ||!CBS_get_asn1(&child, &moniker, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse url";return false;} else {LOG(INFO) << "SpcLink (moniker): // TODO: implement";}} else if (CBS_peek_asn1_tag(&spc_link, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2)) {CBS file;if (!CBS_get_asn1(&spc_link, &file,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2)) {LOG(ERROR) << "Failed to parse url";return false;} else {Parse_SpcString(&file);}} else {LOG(ERROR) << "Failed to parse SpcLink choice";return false;}if (CBS_len(cbs) != 0) {LOG(ERROR) << "Trailing data in SpcLink";return false;}return true;
}// DigestInfo ::= SEQUENCE {
//   digestAlgorithm AlgorithmIdentifier,
//   digest OCTET STRING
// }
//
// AlgorithmIdentifier ::= SEQUENCE {
//   algorithm OBJECT IDENTIFIER,
//   parameters ANY DEFINED BY algorithm OPTIONAL
// }
bool Parse_DigestInfo(CBS* cbs) {const EVP_MD* md = EVP_parse_digest_algorithm(cbs);if (md != EVP_sha256() && md != EVP_sha1()) {LOG(ERROR) << "Failed to parse message digest algorithm";return false;}CBS digest;if (!CBS_get_asn1(cbs, &digest, CBS_ASN1_OCTETSTRING)) {LOG(ERROR) << "Failed to parse digest";return false;}if (CBS_len(cbs) != 0) {LOG(ERROR) << "Trailing data in message digest";return false;}return true;
}
// IndirectDataContent ::= SEQUENCE {
//   data ContentInfo,
//   messageDigest DigestInfo
// }
bool Parse_Authenticode_SpcIndirectDataContent(CBS* cbs) {// SpcAttributeTypeAndOptionalValue ::= SEQUENCE {//     type                    ObjectID,//     value                   [0] EXPLICIT ANY OPTIONAL// }CBS data;if (!CBS_get_asn1(cbs, &data, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse data";return false;}CBS data_oid;if (!CBS_get_asn1(&data, &data_oid, CBS_ASN1_OBJECT)) {LOG(ERROR) << "Failed to parse data content type";return false;}if (CBS_mem_equal(&data_oid, kOidSpcPEImageData,sizeof(kOidSpcPEImageData))) {CBS pe_image_data;if (!CBS_get_asn1(&data, &pe_image_data, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse SpcPeImageData wrapper";return false;}if (!Parse_Authenticode_SpcPeImageData(&pe_image_data)) {LOG(ERROR) << "Failed to parse SpcPeImageData";return false;}} else {LOG(ERROR) << "Unknown data content type";return false;}CBS message_digest;if (!CBS_get_asn1(cbs, &message_digest, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse message digest";return false;}if (!Parse_DigestInfo(&message_digest)) {LOG(ERROR) << "Failed to parse message digest";return false;}return true;
}bool Parse_Authenticode_SignedData(CBS* cbs) {CBS in = *cbs;uint64_t version_number;if (!CBS_get_asn1_uint64(&in, &version_number) || version_number != 1) {LOG(ERROR) << "Failed to parse version";return false;}CBS digest_algorithms;if (!CBS_get_asn1(&in, &digest_algorithms, CBS_ASN1_SET)) {LOG(ERROR) << "Failed to parse digest algorithms";return false;}// DigestAlgorithmIdentifiers SET OF DigestAlgorithmIdentifier// DigestAlgorithmIdentifier ::= SEQUENCE {//   algorithm OBJECT IDENTIFIER,//   parameters ANY DEFINED BY algorithm OPTIONAL// }while (CBS_len(&digest_algorithms) > 0) {const EVP_MD* md = EVP_parse_digest_algorithm(&digest_algorithms);if (md != EVP_sha256() && md != EVP_sha1()) {LOG(ERROR) << "Failed to parse digest algorithm";return false;}}//  EncapsulatedContentInfo ::= SEQUENCE {//    eContentType ContentType,//    eContent [0] EXPLICIT OCTET STRING OPTIONAL }CBS content_info;if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse content info";return false;}CBS content_type;if (!CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) {LOG(ERROR) << "Failed to parse content type";return false;}if (!CBS_mem_equal(&content_type, kOidSpcIndirectDataContent,sizeof(kOidSpcIndirectDataContent))) {LOG(ERROR) << "Unknown content type";return false;}CBS wrapped_indirect_data_content, indirect_data_content;if (!CBS_get_asn1(&content_info, &wrapped_indirect_data_content,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||!CBS_get_asn1(&wrapped_indirect_data_content, &indirect_data_content,CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "Failed to parse wrapped content";return false;}Parse_Authenticode_SpcIndirectDataContent(&indirect_data_content);return true;
}bool Parse_Authenticode_ContentInfo(base::span<const uint8_t> data) {CBS cbs;CBS_init(&cbs, data.data(), data.size());CBS content_info;CBS content_type;if (!CBS_get_asn1(&cbs, &content_info, CBS_ASN1_SEQUENCE) ||!CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) {LOG(ERROR) << "Failed to parse PKCS#7 sequence";return false;}if (!CBS_mem_equal(&content_type, kOidPKCS7SignedData,sizeof(kOidPKCS7SignedData))) {LOG(ERROR) << "Not PKCS7SignedData";return false;}CBS wrapped_signed_data, signed_data;// See https://tools.ietf.org/html/rfc2315#section-9.1if (!CBS_get_asn1(&content_info, &wrapped_signed_data,CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||!CBS_get_asn1(&wrapped_signed_data, &signed_data, CBS_ASN1_SEQUENCE)) {LOG(ERROR) << "";return false;}if (!Parse_Authenticode_SignedData(&signed_data)) {LOG(ERROR) << "Failed to parse SignedData";return false;}return true;
}int main(int argc, char** argv) {base::CommandLine::Init(0, nullptr);base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();base::FilePath input = command_line->GetSwitchValuePath(switches::kInput);base::File pe_file(input, base::File::FLAG_OPEN | base::File::FLAG_READ);DWORD cert_count;if (!ImageEnumerateCertificates(pe_file.GetPlatformFile(),CERT_SECTION_TYPE_ANY, &cert_count, nullptr,0)) {PLOG(ERROR) << "ImageEnumerateCertificates";return -1;}std::vector<DWORD> cert_indices(cert_count);if (!ImageEnumerateCertificates(pe_file.GetPlatformFile(),CERT_SECTION_TYPE_ANY, &cert_count,&cert_indices[0], cert_indices.size())) {PLOG(ERROR) << "ImageEnumerateCertificates";}CHECK(cert_indices.size() == cert_count);for (auto idx : cert_indices) {WIN_CERTIFICATE cert = {};if (!ImageGetCertificateHeader(pe_file.GetPlatformFile(), idx, &cert)) {PLOG(ERROR) << "ImageGetCertificateHeader";return -1;}DWORD cert_length = sizeof(WIN_CERTIFICATE) + cert.dwLength;auto cert_data = base::HeapArray<uint8_t>::WithSize(cert_length);if (!ImageGetCertificateData(pe_file.GetPlatformFile(), idx,reinterpret_cast<WIN_CERTIFICATE*>(cert_data.data()),&cert_length)) {PLOG(ERROR) << "ImageGetCertificateData";return -1;}base::WriteFile(input.AddExtensionASCII(base::StringPrintf("%d.der", idx)),cert_data.subspan(offsetof(WIN_CERTIFICATE, bCertificate)));Parse_Authenticode_ContentInfo(cert_data.subspan(offsetof(WIN_CERTIFICATE, bCertificate)));}return 0;
}

相关新闻

  • 实用指南:力扣2132. 用邮票贴满网格图
  • ONCHAINID源码分析(二)
  • 鸿蒙应用开发从入门到实战(十二):ArkUI组件ButtonToggle

最新新闻

  • 2026苏州大额黄金回收测评|对公个人双合规,收的顶资金安全兜底 - 奢侈品回收测评
  • TC818A芯片实战指南:集成运放配置、电阻选型与LCD驱动优化
  • AI Agent正在改变企业:为什么执行型AI成为新的增长引擎
  • QML MediaPlayer实战:从零构建跨平台轻量视频播放器
  • GEO系统源码揭秘:杭州爱搜索如何重新定义AI搜索优化 - 品牌报告
  • 【干货】7套核心数据分析思维框架,搞定90%业务涨跌问题

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号