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

如何通过PowerShell获取文件正确的SignerInfos信息?

问题:读取文件签名者信息时仅获取到反签名者,无法获取目标签名者

我正在编写PowerShell脚本读取文件的所有证书和SignerInfos。当前代码能获取所有证书,但只返回第一个签名者(这个是反签名者,不是我需要的)。目标文件CbDisk.sys在Windows资源管理器中显示有2个签名者,且每个签名者都带有CounterSignature,我需要获取签名者“Carbon Black Inc.”的信息,但脚本只显示“Microsoft Windows Third Party Component CA 2012”作为唯一签名者。我尝试用CryptMsgGetParam()结合CMSG_SIGNER_COUNT_PARAM参数读取签名者数量,结果还是显示只有1个签名者。

以下是当前代码:

# reference links:
# embedded C# code template: https://www.sysadmins.lv/blog-en/reading-multiple-signatures-from-signed-file-with-powershell.aspx
# MS sample: https://learn.microsoft.com/en-gb/previous-versions/troubleshoot/windows/win32/get-information-authenticode-signed-executables
# wincrypt header definitions: https://github.com/dwimperl/perl-5.14.2.1-32bit-windows/blob/master/c/i686-w64-mingw32/include/wincrypt.h

cls
Remove-Variable * -ea 0
$errorActionPreference = 'stop'

$FilePath = "C:\WINDOWS\system32\DRIVERS\CbDisk.sys"

Add-Type -TypeDefinition @"
using System;
using System.Security.Cryptography.Pkcs;
using System.Runtime.InteropServices;

public static class Crypt32 {
    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptQueryObject(
        int dwObjectType,
        [MarshalAs(UnmanagedType.LPWStr)]
        string pvObject,
        int dwExpectedContentTypeFlags,
        int dwExpectedFormatTypeFlags,
        int dwFlags,
        ref int pdwMsgAndCertEncodingType,
        ref int pdwContentType,
        ref int pdwFormatType,
        ref IntPtr phCertStore,
        ref IntPtr phMsg,
        ref IntPtr ppvContext
    );

    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptMsgGetParam(
        IntPtr hCryptMsg,
        int dwParamType,
        int dwIndex,
        byte[] pvData,
        ref int pcbData
    );

    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptMsgClose(IntPtr hCryptMsg);

    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CertCloseStore(IntPtr hCertStore, int dwFlags);

    public static SignedCms GetSignedCmsFromFile(string filePath) {
        int pdwMsgAndCertEncodingType = 0;
        int pdwContentType = 0;
        int pdwFormatType = 0;
        IntPtr phCertStore = IntPtr.Zero;
        IntPtr phMsg = IntPtr.Zero;
        IntPtr ppvContext = IntPtr.Zero;
    
        if (!CryptQueryObject(
            1, filePath, 0x400, 2, 0,
            ref pdwMsgAndCertEncodingType,
            ref pdwContentType,
            ref pdwFormatType,
            ref phCertStore,
            ref phMsg,
            ref ppvContext
        )) {return new SignedCms();}
    
        int pcbData = 0;
        CryptMsgGetParam(phMsg, 29, 0, null, ref pcbData);
        byte[] pvData = new byte[pcbData];
        CryptMsgGetParam(phMsg, 29, 0, pvData, ref pcbData);
        CryptMsgClose(phMsg);

        SignedCms signedCms = new SignedCms();
        signedCms.Decode(pvData);
        return signedCms;
    }
}
"@ -ReferencedAssemblies System.Security

# this gets all certs:
$cms = [Crypt32]::GetSignedCmsFromFile($FilePath)
$certs  = $cms.Certificates
$certs | ft -AutoSize

# this gives me only 1 signer, but not all of them.
# also the CounterSignerInfos are always empty here:
$signers = $cms.SignerInfos

资源管理器中该文件的签名显示:
文件签名截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:38:09