We can directly right-click to check the validity of the digital signature of PE file under windows system, as shown in the following figure:
This reminds us that Microsoft must have its own verification method for the digital signature of PE files. After searching for information, make sure it comes from the WinVerifyTrust function in the dll file shown below.
The calling prototype of this function in C# is as follows:
C#
[DllImport("wintrust.dll ",PreserveSig = true,SetLastError = false)]
private static extern uint WinVerifyTrust(IntPtr hWnd,IntPtr pgActionID,IntPtr pWinTrustData);
About the use of this function, you can see the explanation on MSDN.
(2) Establish the data structure to be used.
According to Microsoft official data, before using this function, we should prepare several data structures:
Use the system;
Use the system. Runtime . InteropServices
Namespace verification digital signature
{
Public enumeration allocm method
{
H global,
CoTaskMem
}
Public enumeration UnionChoice
{
File = 1,
Directory,
Spots,
Signed by:
A sure thing
}
Public enumeration UiChoice
{
All = 1,
Nou,
Nobad,
It doesn't taste good
}
Public enumeration RevocationCheckFlags
{
None = 0,
The whole chain
}
Common enumeration status operation
{
Ignore = 0,
Verification,
Close,
Automatic caching,
Automatic cache refresh
}
Public enumeration TrustProviderFlags
{
UseIE4Trust = 1,
NoIE4Chain = 2,
NoPolicyUsage = 4,
RevocationCheckNone = 16,
RevocationCheckEndCert = 32,
RevocationCheckChain = 64,
RecovationCheckChainExcludeRoot = 128,
Safer = 256,
HashOnly = 5 12,
UseDefaultOSVerCheck = 1024,
Life cycle logo = 2048
}
Public enumeration UIContext
{
Execution = 0,
fix
}
# Area does not manage pointer classes.
Internal sealing class UnmanagedPointer: IDisposable
{
private IntPtr m _ ptr
Private AllocMethod m _ meth
Internal UnmanagedPointer( IntPtr ptr, AllocMethod)
{
M_meth = method;
m _ ptr = ptr
}
~UnmanagedPointer()
{
Dispose (false);
}
# zone IDisposable member
Private invalid disposal (Boolean disposal)
{
if ( m_ptr! = IntPtr。 Zero)
{
if ( m_meth == AllocMethod。 HGlobal)
{
Bailiff. freeh global(m _ ptr);
}
else if ( m_meth == AllocMethod。 CoTaskMem)
{
Bailiff. FreeCoTaskMem(m _ ptr);
}
m_ptr = IntPtr。 Zero;
}
If (processing)
{
GC。 suppress finalize(this);
}
}
Public void Dispose ()
{
Dispose (true);
}
# End area
Public static implicit operator IntPtr( UnmanagedPointer ptr)
{
Returns ptr.m _ ptr
}
}
# End area
Internal structure WINTRUST_FILE_INFO: IDisposable
{
Public WINTRUST_FILE_INFO (string file name, Guid subject)
{
cbStruct = (uint)Marshal。 SizeOf(type of(WINTRUST _ FILE _ INFO));
pcwszFilePath = fileName
If (theme! = Guid。 Empty)
{
pgKnownSubject = Marshal。 AllocHGlobal (marshaled. SizeOf(type of(Guid)));
Bailiff. StructureToPtr( subject,pgKnownSubject,true);
}
other
{
pgKnownSubject = IntPtr。 Zero;
}
hFile = IntPtr。 Zero;
}
Public unit structure;
[MarshalAs( UnmanagedType。 LPTStr )]
Public string pcwszFilePath
Public IntPtr hFile
public IntPtr pgKnownSubject
# Region id Disposable Member
Public void Dispose ()
{
Dispose (true);
}
Private invalid disposal (Boolean disposal)
{
if(pgknownssubject! = IntPtr。 Zero)
{
Bailiff. destroy structure(this . pgknownsubject,type of(Guid));
Bailiff. freeh global(this . pgknownsubject);
}
}
# End area
}
[StructLayout( LayoutKind。 Continuous)]
Internal structure WINTRUST_DATA: IDisposable
{
Public wintrust _ data (wintrust _ file _ infofileinfo)
{
this.cbStruct = (uint)Marshal。 SizeOf(type of(WINTRUST _ DATA));
pInfoStruct = Marshal。 AllocHGlobal (marshaled. SizeOf(type of(WINTRUST _ FILE _ INFO)));
Bailiff. StructureToPtr( fileInfo,pInfoStruct,true);
this.dwUnionChoice = UnionChoice。 Documents;
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。 Execution;
}
Public unit structure;
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 id Disposable Member
Public void Dispose ()
{
Dispose (true);
}
Private invalid disposal (Boolean disposal)
{
if ( dwUnionChoice == UnionChoice。 File)
{
//WINTRUST _ FILE _ INFO INFO = new WINTRUST _ FILE _ INFO();
//sealed. PtrToStructure(pInfoStruct,info);
//info。 dispose();
Bailiff. DestroyStructure( pInfoStruct,type of(WINTRUST _ FILE _ INFO));
}
Bailiff. freeh global(pInfoStruct);
}
# End area
}
}
(3) Build our verification class
shell
Use the system;
Use the system. Assemble. Generics;
Use the system. Runtime . InteropServices
Use Microsoft. Win32
Namespace verification digital signature
{
Public class authentication
{
[DllImport( "wintrust.dll ",PreserveSig = true,SetLastError = false )]
private static extern uint WinVerifyTrust(IntPtr hWnd,IntPtr pgActionID,IntPtr pWinTrustData);
Private static list & ltGuid & gtGetTrustGuid ()
{
//HKEY _ LOCAL _ MACHINE \ SOFTWARE \ Microsoft \ Cryptography \ Providers \ Trust \ initial ization \
List & ltGuid & gttrustGuids = new list & ltGuid & gt ();
RegistryKey hklm = registry. Local machine;
RegistryKey initialization = hklm. open subkey(@ " SOFTWARE \ Microsoft \ Cryptography \ Providers \ Trust \ initial ization));
String[] guidNames = initialization. GetSubKeyNames();
Foreach (string guidName in guidnames)
{
trustGuids。 Add (new guid (guid name));
}
Return to trustGuids
}
Public static uint CSWinVerifyTrust (string file name)
{
Uint result =1516356;
attempt
{
List & lt guid & gt trustguides = gettrustguid ();
Foreach (Guid guid is in trustGuids)
{
guid wintrust _ action _ generic _ verify _ v2 = guid;
Wintrust _ file _ info fileinfo = newwintrust _ file _ info (file name, Guid. Empty);
WINTRUST _ DATA DATA = new WINTRUST _ DATA(fileInfo);
UnmanagedPointer guidPtr = new UnmanagedPointer( Marshal. AllocHGlobal (marshaled. SizeOf( typeof( Guid))、AllocMethod。 h global);
UnmanagedPointer wvtDataPtr = new UnmanagedPointer( Marshal. AllocHGlobal (marshaled. SizeOf( typeof( WINTRUST_DATA))、AllocMethod。 h global);
IntPtr pGuid = guidPtr
IntPtr pData = wvtDataPtr
Bailiff. structure toptr(wintrust _ action _ generic _ verify _ v2,pGuid,true);
Bailiff. StructureToPtr( data,pData,true);
result = WinVerifyTrust( IntPtr。 Zero,pGuid,pData);
If (result == 0)
{
Break;
}
}
}
Catch (exception ex)
{
Throws a new exception ("VerifyDigitalSignature error." ,ex);
}
Return the result;
}
}
}
Note that there are many return values of WinVerifyTrust, where 0 indicates that all indicators of digital signature are normal. We will discuss other codes in the next section.