问题描述
我正在编写一个需要加载其他文件的程序。有没有办法检查这些文件是否被签名,没有右键点击它们并检查?我使用300-400个文件,每隔几天更改
我需要检查DLL / EXE / CAB / OCX / MSI(也可能是vbs / js)
有没有办法检查?
假设你想检查一个文件是否是Authenticode签名,证书是相信您可以固定在 Wintrust.dll
。
下面是一个包装器或多或少复制了),可以调用如下:
AuthenticodeTools.IsTrusted(@path\to\some\signed\file.exe)
其中 AuthenticodeTools
定义如下:
内部静态类AuthenticodeTools
{
[DllImport(Wintrust.dll,PreserveSi g = true,SetLastError = false)]
private static extern uint WinVerifyTrust(IntPtr hWnd,IntPtr pgActionID,IntPtr pWinTrustData);
private static uint WinVerifyTrust(string fileName)
{
Guid wintrust_action_generic_verify_v2 = new Guid({00AAC56B-CD44-11d0-8CC2-00C04FC295EE});
uint result = 0;
using(WINTRUST_FILE_INFO fileInfo = new WINTRUST_FILE_INFO(fileName,
Guid.Empty))
using(UnmanagedPointer guidPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)))
using(UnmanagedPointer wvtDataPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_DATA))),
AllocMethod.HGlobal))
{
WINTRUST_DATA data = new WINTRUST_DATA(fileInfo);
IntPtr pGuid = guidPtr;
IntPtr pData = wvtDataPtr;
Marshal.StructureToPtr(wintrust_action_generic_verify_v2,
pGuid,
true);
Marshal.StructureToPtr(data,
pData,
true);
result = WinVerifyTrust(IntPtr.Zero,
pGuid,
pData);
}
返回结果;
}
public static bool IsTrusted(string fileName)
{
返回WinVerifyTrust(fileName)== 0;
}
内部结构WINTRUST_FILE_INFO:IDisposable
{
public WINTRUST_FILE_INFO(string fileName,引用主题)
{
cbStruct =(uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO));
pcwszFilePath = fileName;
如果(subject!= Guid.Empty)
{
pgKnownSubject = Marshal.AllocHGlobal(Marshal.SizeOf(typeof GUID)));
Marshal.StructureToPtr(subject,pgKnownSubject,true);
}
else
{
pgKnownSubject = IntPtr.Zero;
}
hFile = IntPtr.Zero;
}
public uint cbStruct;
[MarshalAs(UnmanagedType.LPTStr)]
public string pcwszFilePath;
public IntPtr hFile;
public IntPtr pgKnownSubject;
#region IDisposable会员
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool处置)
{
if(pgKnownSubject!= IntPtr.Zero)
{
Marshal.DestroyStructure(this.pgKnownSubject,typeof(Guid));
Marshal.FreeHGlobal(this.pgKnownSubject);
}
}
#endregion
}
枚举AllocMethod
{
HGlobal,
CoTaskMem
};
enum UnionChoice
{
文件= 1,
目录,
Blob,
签名者,
证书
};
枚举UiChoice
{
全部= 1,
NoUI,
NoBad,
NoGood
};
枚举RevocationCheckFlags
{
无= 0,
WholeChain
};
enum StateAction
{
Ignore = 0,
验证,
关闭,
自动缓存,
AutoCacheFlush
};
枚举TrustProviderFlags
{
UseIE4Trust = 1,
NoIE4Chain = 2,
NoPolicyUsage = 4,
RevocationCheckNone = 16,
RevocationCheckEndCert = 32 ,
RevocationCheckChain = 64,
RecovationCheckChainExcludeRoot = 128,
Safer = 256,
HashOnly = 512,
UseDefaultOSVerCheck = 1024,
LifetimeSigning = 2048
};
枚举UIContext
{
执行= 0,
安装
};
[StructLayout(LayoutKind.Sequential)]
内部结构WINTRUST_DATA:IDisposable
{
public WINTRUST_DATA(WINTRUST_FILE_INFO fileInfo)
{
this.cbStruct =(uint)Marshal.SizeOf(typeof(WINTRUST_DATA));
pInfoStruct = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)));
Marshal.StructureToPtr(fileInfo,pInfoStruct,false);
this.dwUnionChoice = UnionChoice.File;
pPolicyCallbackData = IntPtr.Zero;
pSIPCallbackData = IntPtr.Zero;
dwUIChoice = UiChoice.NoUI;
fdwRevocationChecks = RevocationCheckFlags.None;
dwStateAction = StateAction.Ignore;
hWVTStateData = IntPtr.Zero;
pwszURLReference = IntPtr.Zero;
dwProvFlags = TrustProviderFlags.Safer;
dwUIContext = UIContext.Execute;
}
public uint cbStruct;
public IntPtr pPolicyCallbackData;
public IntPtr pSIPCallbackData;
public UiChoice dwUIChoice;
public RevocationCheckFlags fdwRevocationChecks;
public UnionChoice dwUnionChoice;
public IntPtr pInfoStruct;
public StateAction dwStateAction;
public IntPtr hWVTStateData;
private IntPtr pwszURLReference;
public TrustProviderFlags dwProvFlags;
public UIContext dwUIContext;
#region IDisposable会员
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposal)
{
if(dwUnionChoice == UnionChoice.File)
{
WINTRUST_FILE_INFO info = new WINTRUST_FILE_INFO();
Marshal.PtrToStructure(pInfoStruct,info);
info.Dispose();
Marshal.DestroyStructure(pInfoStruct,typeof(WINTRUST_FILE_INFO));
}
Marshal.FreeHGlobal(pInfoStruct);
}
#endregion
}
内部密封类UnmanagedPointer:IDisposable
{
private IntPtr m_ptr;
private AllocMethod m_meth;
内部UnmanagedPointer(IntPtr ptr,AllocMethod方法)
{
m_meth = method;
m_ptr = ptr;
}
〜UnmanagedPointer()
{
Dispose(false);
}
#region IDisposable会员
private void Dispose(bool disposal)
{
if(m_ptr!= IntPtr.Zero)
{
if(m_meth == AllocMethod.HGlobal)
{
Marshal.FreeHGlobal(m_ptr);
}
else if(m_meth == AllocMethod.CoTaskMem)
{
Marshal.FreeCoTaskMem(m_ptr);
}
m_ptr = IntPtr.Zero;
}
如果(处置)
{
GC.SuppressFinalize(this);
}
}
public void Dispose()
{
Dispose(true);
}
#endregion
public static implicit operator IntPtr(UnmanagedPointer ptr)
{
return ptr.m_ptr;
}
}
I'm writing a program that need to load a few other files.is there a way to check if those files are signed or not, without right clicking them and check? I use 300-400 files that change every few daysI need to check DLL/EXE/CAB/OCX/MSI (and maybe also vbs/js)
is there a way to check it?
Assuming you want to check if a file is Authenticode signed and that the certificate is trusted you can pinvoke to WinVerifyTrust
in Wintrust.dll
.
Below is a wrapper (more or less reproduced from here) that can be called as follows:
AuthenticodeTools.IsTrusted(@"path\to\some\signed\file.exe")
Where AuthenticodeTools
is defined as follows:
internal static class AuthenticodeTools
{
[DllImport("Wintrust.dll", PreserveSig = true, SetLastError = false)]
private static extern uint WinVerifyTrust(IntPtr hWnd, IntPtr pgActionID, IntPtr pWinTrustData);
private static uint WinVerifyTrust(string fileName)
{
Guid wintrust_action_generic_verify_v2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");
uint result=0;
using (WINTRUST_FILE_INFO fileInfo = new WINTRUST_FILE_INFO(fileName,
Guid.Empty))
using (UnmanagedPointer guidPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof (Guid))),
AllocMethod.HGlobal))
using (UnmanagedPointer wvtDataPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof (WINTRUST_DATA))),
AllocMethod.HGlobal))
{
WINTRUST_DATA data = new WINTRUST_DATA(fileInfo);
IntPtr pGuid = guidPtr;
IntPtr pData = wvtDataPtr;
Marshal.StructureToPtr(wintrust_action_generic_verify_v2,
pGuid,
true);
Marshal.StructureToPtr(data,
pData,
true);
result = WinVerifyTrust(IntPtr.Zero,
pGuid,
pData);
}
return result;
}
public static bool IsTrusted(string fileName)
{
return WinVerifyTrust(fileName) == 0;
}
}
internal struct WINTRUST_FILE_INFO : IDisposable
{
public WINTRUST_FILE_INFO(string fileName, Guid subject)
{
cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO));
pcwszFilePath = fileName;
if (subject != Guid.Empty)
{
pgKnownSubject = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
Marshal.StructureToPtr(subject, pgKnownSubject, true);
}
else
{
pgKnownSubject = IntPtr.Zero;
}
hFile = IntPtr.Zero;
}
public uint cbStruct;
[MarshalAs(UnmanagedType.LPTStr)]
public string pcwszFilePath;
public IntPtr hFile;
public IntPtr pgKnownSubject;
#region IDisposable Members
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (pgKnownSubject != IntPtr.Zero)
{
Marshal.DestroyStructure(this.pgKnownSubject, typeof(Guid));
Marshal.FreeHGlobal(this.pgKnownSubject);
}
}
#endregion
}
enum AllocMethod
{
HGlobal,
CoTaskMem
};
enum UnionChoice
{
File = 1,
Catalog,
Blob,
Signer,
Cert
};
enum UiChoice
{
All = 1,
NoUI,
NoBad,
NoGood
};
enum RevocationCheckFlags
{
None = 0,
WholeChain
};
enum StateAction
{
Ignore = 0,
Verify,
Close,
AutoCache,
AutoCacheFlush
};
enum TrustProviderFlags
{
UseIE4Trust = 1,
NoIE4Chain = 2,
NoPolicyUsage = 4,
RevocationCheckNone = 16,
RevocationCheckEndCert = 32,
RevocationCheckChain = 64,
RecovationCheckChainExcludeRoot = 128,
Safer = 256,
HashOnly = 512,
UseDefaultOSVerCheck = 1024,
LifetimeSigning = 2048
};
enum UIContext
{
Execute = 0,
Install
};
[StructLayout(LayoutKind.Sequential)]
internal struct WINTRUST_DATA : IDisposable
{
public WINTRUST_DATA(WINTRUST_FILE_INFO fileInfo)
{
this.cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_DATA));
pInfoStruct = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)));
Marshal.StructureToPtr(fileInfo, pInfoStruct, false);
this.dwUnionChoice = UnionChoice.File;
pPolicyCallbackData = IntPtr.Zero;
pSIPCallbackData = IntPtr.Zero;
dwUIChoice = UiChoice.NoUI;
fdwRevocationChecks = RevocationCheckFlags.None;
dwStateAction = StateAction.Ignore;
hWVTStateData = IntPtr.Zero;
pwszURLReference = IntPtr.Zero;
dwProvFlags = TrustProviderFlags.Safer;
dwUIContext = UIContext.Execute;
}
public uint cbStruct;
public IntPtr pPolicyCallbackData;
public IntPtr pSIPCallbackData;
public UiChoice dwUIChoice;
public RevocationCheckFlags fdwRevocationChecks;
public UnionChoice dwUnionChoice;
public IntPtr pInfoStruct;
public StateAction dwStateAction;
public IntPtr hWVTStateData;
private IntPtr pwszURLReference;
public TrustProviderFlags dwProvFlags;
public UIContext dwUIContext;
#region IDisposable Members
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (dwUnionChoice == UnionChoice.File)
{
WINTRUST_FILE_INFO info = new WINTRUST_FILE_INFO();
Marshal.PtrToStructure(pInfoStruct, info);
info.Dispose();
Marshal.DestroyStructure(pInfoStruct, typeof(WINTRUST_FILE_INFO));
}
Marshal.FreeHGlobal(pInfoStruct);
}
#endregion
}
internal sealed class UnmanagedPointer : IDisposable
{
private IntPtr m_ptr;
private AllocMethod m_meth;
internal UnmanagedPointer(IntPtr ptr, AllocMethod method)
{
m_meth = method;
m_ptr = ptr;
}
~UnmanagedPointer()
{
Dispose(false);
}
#region IDisposable Members
private void Dispose(bool disposing)
{
if (m_ptr != IntPtr.Zero)
{
if (m_meth == AllocMethod.HGlobal)
{
Marshal.FreeHGlobal(m_ptr);
}
else if (m_meth == AllocMethod.CoTaskMem)
{
Marshal.FreeCoTaskMem(m_ptr);
}
m_ptr = IntPtr.Zero;
}
if (disposing)
{
GC.SuppressFinalize(this);
}
}
public void Dispose()
{
Dispose(true);
}
#endregion
public static implicit operator IntPtr(UnmanagedPointer ptr)
{
return ptr.m_ptr;
}
}
这篇关于如何检查文件是否在C#中签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!