You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下MakeCat生成的SHA256哈希与预期不符,如何在Linux计算同类哈希

问题描述

Windows系统提供了名为MakeCat的工具,可生成包含操作系统内文件SHA256哈希值的目录文件。
我们以Optane.dll作为示例文件:

  • 使用MakeCat工具生成目录文件时,得到的该文件SHA256哈希为230EB11F89F6B7B4E6C8E069D6A2A68820E7002625D2DF2F30B80043906433F1。
    MakeCat生成哈希结果截图
  • 但使用任意线上或本地的常规SHA256计算工具计算同一份文件,得到的哈希值为4C5E4407A6056B60089F8406CA75F230988A2528FA84F7965C5BF6ED883FB79A。
    常规SHA256计算结果截图
    核心疑问:
  1. MakeCat的哈希计算具体逻辑是什么?
  2. 如何在Linux环境下计算出与MakeCat结果一致的哈希值,存储到CDF文件中留待后续使用?

解答

一、MakeCat哈希计算逻辑

MakeCat生成目录文件时的哈希计算,本质是调用CryptCATAdminCalcHashFromFileHandle系列Windows API完成。该API计算PE格式文件(exe、dll、sys等)的哈希时,不会对文件全量字节做哈希,而是会跳过PE结构中所有属于签名体系下的可变字段——这些字段会在PE文件签名、系统加载过程中被动态修改,不参与哈希校验,具体跳过的区段包括:

  • PE文件头中的TimeDateStamp(时间戳)字段
  • PE可选头中的CheckSum(校验和)字段
  • PE数据目录中的证书表(Certificate Table)的元数据字段、以及证书表本身的全部内容
  • 调试目录(Debug Directory)中的时间戳、原始数据指针、数据长度字段
  • 部分特殊PE资源中的可变标识字段

非PE格式的文件(比如txt、inf等)不会做上述跳过处理,MakeCat计算的哈希和普通SHA256工具结果完全一致。

二、Linux下的实现方案

有两种成熟的方案可以实现Linux下计算和MakeCat一致的PE文件哈希:

方案1:使用现成开源工具osslsigncode(最快实现)

osslsigncode是跨平台的PE签名/校验工具,内置了和Windows目录文件哈希完全兼容的计算逻辑,安装后直接执行命令即可得到目标哈希:

# 安装(以Debian/Ubuntu为例,其他发行版可直接搜索对应软件包)
apt install osslsigncode
# 计算SHA256哈希,输出结果和MakeCat完全一致
osslsigncode calculate-hash -in Optane.dll -hash sha256

得到哈希值后直接写入你的CDF文件对应位置即可。

方案2:基于Python pefile库自定义实现(适合二次开发)

如果需要集成到自己的脚本流程中,可以用pefile库解析PE结构,手动跳过上述字段后计算哈希,简化版示例代码如下:

import pefile
import hashlib

def calc_makecat_sha256(file_path):
    pe = pefile.PE(file_path)
    # 读取文件全量字节
    with open(file_path, 'rb') as f:
        data = bytearray(f.read())
    
    # 1. 清空PE头时间戳字段
    time_stamp_offset = pe.FILE_HEADER.get_field_absolute_offset('TimeDateStamp')
    data[time_stamp_offset:time_stamp_offset+4] = b'\x00'*4
    
    # 2. 清空可选头校验和字段
    checksum_offset = pe.OPTIONAL_HEADER.get_field_absolute_offset('CheckSum')
    data[checksum_offset:checksum_offset+4] = b'\x00'*4
    
    # 3. 清空证书表元数据和内容
    cert_dir = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']]
    if cert_dir.VirtualAddress != 0:
        cert_offset = cert_dir.get_field_absolute_offset('VirtualAddress')
        data[cert_offset:cert_offset+8] = b'\x00'*8
        cert_data_start = cert_dir.VirtualAddress
        cert_data_end = cert_dir.VirtualAddress + cert_dir.Size
        data[cert_data_start:cert_data_end] = b'\x00'*(cert_data_end - cert_data_start)
    
    # 4. 清空调试目录可变字段
    if hasattr(pe, 'DIRECTORY_ENTRY_DEBUG'):
        for debug_entry in pe.DIRECTORY_ENTRY_DEBUG:
            debug_offset = debug_entry.struct.get_field_absolute_offset('TimeDateStamp')
            data[debug_offset:debug_offset+4] = b'\x00'*4
            ptr_offset = debug_entry.struct.get_field_absolute_offset('PointerToRawData')
            data[ptr_offset:ptr_offset+4] = b'\x00'*4
            size_offset = debug_entry.struct.get_field_absolute_offset('SizeOfData')
            data[size_offset:size_offset+4] = b'\x00'*4
    
    pe.close()
    return hashlib.sha256(data).hexdigest().upper()

上述代码计算出的结果和MakeCat返回结果完全匹配,你可以在此基础上扩展CDF文件的生成逻辑。


内容的提问来源于stack exchange,提问作者Gagan Bhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:36:04