WinVerifyTrust to check for a specific signature?

I believe what you’re looking for is CryptQueryObject.

With it you should be able to pull the involved certificate out of a PE, and do any additional checks you want.


By way of example, this will get you to a HCRYPTMSG. From there you can use CryptMsgGetParam to pull out whatever you want. I’d hoped to make something more ‘robust’, but these APIs are pretty hairy insomuch as they require a lot of branching to handle all their return cases.

So, here’s a p/invoke-rific c# example (I started in C, but that was basically unreadable):

static class Crypt32
{
    //Omitting flag constants; you can look these up in WinCrypt.h

    [DllImport("CRYPT32.DLL", EntryPoint = "CryptQueryObject", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptQueryObject(
        int dwObjectType,
        IntPtr pvObject,
        int dwExpectedContentTypeFlags,
        int dwExpectedFormatTypeFlags,
        int dwFlags,
        out int pdwMsgAndCertEncodingType,
        out int pdwContentType,
        out int pdwFormatType,
        ref IntPtr phCertStore,
        ref IntPtr phMsg,
        ref IntPtr ppvContext);
}

class Program
{
    static void Main(string[] args)
    {
        //Path to executable here
        //  I tested with MS-Office .exe's
        string path = "";

        int contentType;
        int formatType;
        int ignored;
        IntPtr context = IntPtr.Zero;
        IntPtr pIgnored = IntPtr.Zero;

        IntPtr cryptMsg = IntPtr.Zero;

        if (!Crypt32.CryptQueryObject(
            Crypt32.CERT_QUERY_OBJECT_FILE,
            Marshal.StringToHGlobalUni(path),
            Crypt32.CERT_QUERY_CONTENT_FLAG_ALL,
            Crypt32.CERT_QUERY_FORMAT_FLAG_ALL,
            0,
            out ignored,
            out contentType,
            out formatType,
            ref pIgnored,
            ref cryptMsg,
            ref context))
        {
            int error = Marshal.GetLastWin32Error();

            Console.WriteLine((new Win32Exception(error)).Message);

            return;
        }

        //expecting '10'; CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
        Console.WriteLine("Context Type: " + contentType);

        //Which implies this is set
        Console.WriteLine("Crypt Msg: " + cryptMsg.ToInt32());

        return;
    }

Leave a Comment

tech