简体   繁体   中英

Trying to check processes for digital signatures, having an error

Hi i've wrote this method in C# that checks all windows processes for digital signatures. Howver, it tells me that File doesn't contain a definiton for GetDigitalSignatures.


void DriverCheck()
{
Process[] processes = Process.GetProcesses();

            foreach (Process process in processes)
            {
                try
                {
                    // Check if the process has a main module
                    if (process.MainModule != null)
                    {
                        // Check if the main module has a digital signature
                        bool isSigned = File.GetDigitalSignatures(process.MainModule.FileName).Length > 0;
    
                        if (isSigned)
                        {
                            // The main module is signed
                            // You can also get the certificate that was used to sign the file using the following code:
                            
                        }
                        else
                        {
                            // The main module is not signed
                        }
                    }
                }
                catch (System.ComponentModel.Win32Exception)
                {
                    // The process does not have a main module
                }
            }
        }

can someone help me?

I tried finding a namespace that contains those but didn't suceed.

You can try something like this.

using System;
using System.IO;
using System.Windows.Forms; // I have this here, because I wanted to make a WinForm app
using System.Security.Cryptography.X509Certificates;

// rest of the code - form.load, checking the signature
// on button click, displaying the info in a multiline textbox, etc

string curFile = txtPath.Text.Trim(); // I'm reading the path from a textbox
if(File.Exists(curFile))
{
    try
    {
        byte[] fileBytes = File.ReadAllBytes(curFile);
        X509Certificate cert = new X509Certificate(fileBytes);

        byte[] signature = cert.GetRawCertData();
        string extraInfo = "Subject: " + cert.Subject + "\r\n------\r\nIssuer: " + cert.Issuer;

        txtResult.Text = extraInfo;
    } catch (Exception ex)
    {
        txtResult.Text = DateTime.Now.ToString("HH:mm:ss") + "\r\nException: " + ex.Message;
    }
} else
{
    txtResult.Text = "Signature not found";
}

This is how it would look in a tiny WinForm app, made just for this.

The case when the file doesn't have a digital signature is handled in the Exception . You might want to change that for your specific use case, as you would for the way you get the file path (get all the processes, loop through them, check them individually, do something if a signature is not found, etc). For simplicity's sake, I went with a textbox solution and a GUI.

You could call signtool as external tool to validate the process signatures.

//  Compile as x64 executable to be able to access 64-bit processes.
//  Execute tool as Administrator to get access to more processes.

[DllImport("Kernel32.dll")]
static extern uint QueryFullProcessImageName(IntPtr hProcess, uint flags, StringBuilder text, out uint size);

    //  Get the path to a process excutable
    //  https://stackoverflow.com/a/46671939/1911064
    private static string GetPathToApp(Process process)
    {
        string pathToExe = string.Empty;

        if (null != process)
        {
            uint nChars = 256;
            StringBuilder Buff = new StringBuilder((int)nChars);

            uint success = QueryFullProcessImageName(process.Handle, 0, Buff, out nChars);

            if (0 != success)
            {
                pathToExe = Buff.ToString();
            }
            else
            {
                int error = Marshal.GetLastWin32Error();
                pathToExe = ("Error = " + error + " when calling GetProcessImageFileName");
            }
        }

        return pathToExe;
    }

    static bool CheckIfSigned(string fileName)
    {
        bool ret = false;

        if (File.Exists(fileName)) 
        {
            //  https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool
            //  https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
            //  signtool.exe is part of Windows 10 SDK 

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "signtool.exe",
                    Arguments = $"verify /all /pa /v {fileName}",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            process.Start();

            while (!process.StandardOutput.EndOfStream)
            {
                var line = process.StandardOutput.ReadLine();

                // Console.WriteLine(line);

                if (line.StartsWith("Successfully verified:"))
                {
                    Console.WriteLine("success!");
                    return true;
                }
                if (line.StartsWith("SignTool Error:"))
                {
                    Console.WriteLine("error!");
                    return false;
                }
                if (line.StartsWith("Number of errors: 0"))
                {
                    Console.WriteLine("should have announced success!");
                    return false;
                }
                if (line.StartsWith("Number of errors:"))
                {
                    Console.WriteLine("Signtool found errors!");
                    return false;
                }
            }
            Console.WriteLine($"Could not recognized signtool output for {fileName}");
        }
        else
        {
            Console.WriteLine($"File not found: {fileName}");
        }

        return ret;
    }

    static void DriverCheck()
    {
        Process[] processes = Process.GetProcesses();

        foreach (Process process in processes)
        {
            try
            {
                if (!process.HasExited)
                {
                    string processPath = GetPathToApp(process);

                    // Check if the process has a main module
                    if (null != processPath)
                    {
                        // Check if the main module has a digital signature
                        bool isSigned = CheckIfSigned(processPath);

                        if (isSigned)
                        {
                            Console.WriteLine($"signed: {process.MainModule.FileName}");
                        }
                        else
                        {
                            Console.WriteLine($"**NOT** signed: {process.MainModule.FileName}");
                        }
                    }
                }
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                // The process does not have a main module?
                Console.WriteLine($"Win32Exception for ID={process.Id} {process.ProcessName}: {ex.Message}");
            }
            catch(Exception ex)
            {
                Console.WriteLine($"Exception for ID={process.Id} {process.ProcessName}: {ex.Message}");
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM