Home > Back-end >  Trying to check processes for digital signatures, having an error
Trying to check processes for digital signatures, having an error

Time:01-03

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.

CodePudding user response:

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.

CodePudding user response:

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

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 recognize 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
        {
            // Check if the process has a main module
            if (!process.HasExited && (process.MainModule != null))
            {
                // Check if the main module has a digital signature
                bool isSigned = CheckIfSigned(process.MainModule.FileName);

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