我正在寻找一个 Powershell 脚本来读取一个文件签名的所有证书。 Powershell 本身只允许通过默认命令读取文件的第一个证书。在答案中查看我对此问题的解决方案。
这是我为此编写的示例代码。享受吧!
cls
Remove-Variable * -ea 0
$errorActionPreference = 'stop'
$path = "C:\WINDOWS\system32\DRIVERS\fbwwanfilter.sys"
$reader = $null
try {
# Open the file as a BinaryReader
$reader = [System.IO.BinaryReader]::new([System.IO.File]::OpenRead($path))
# Read DOS header:
$null = $reader.BaseStream.Seek(0x3C, 0)
$peHeaderOffset = $reader.ReadUInt32()
# Read PE signature:
$null = $reader.BaseStream.Seek($peHeaderOffset, 0)
$signature = $reader.ReadUInt32()
if ($signature -ne 0x4550) { throw "Not a PE file" }
# Read the PE magic:
$null = $reader.BaseStream.Seek(20, 1)
$magic = $reader.ReadUInt16()
$seekOffset = if ($magic -eq 0x10b) { 126 } elseif ($magic -eq 0x20b) { 142 } else { throw "Unknown PE magic" }
$null = $reader.BaseStream.Seek($seekOffset, 1)
# Read Certificate Table entry in Data Directory:
$certStart = $reader.ReadUInt32()
$certSize = $reader.ReadUInt32()
if ($certStart -eq 0 -or $certSize -eq 0) { throw "No Certificate Table entry" }
# Read Certificate Table
$null = $reader.BaseStream.Seek($certStart, 0)
$len = $reader.ReadUInt32()
if ($len -eq 0) { throw "Certificate length is zero" }
$revision = $reader.ReadUInt16()
$certificateType = $reader.ReadUInt16()
$certBytes = $reader.ReadBytes($len - 8)
Add-Type -AssemblyName System.Security
$signedCms = [Security.Cryptography.Pkcs.SignedCms]::new()
$signedCms.Decode($certBytes)
# Output certificate details
$signedCms.Certificates
}
finally {
if ($reader -ne $null) {
$reader.Close()
}
}