简体   繁体   English

尝试检查数字签名的进程,出现错误

[英]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.您好,我在 C# 中编写了这个方法,它检查所有 windows 进程的数字签名。 Howver, it tells me that File doesn't contain a definiton for GetDigitalSignatures.但是,它告诉我 File 不包含 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.这就是它在专为此而制作的微型 WinForm 应用程序中的样子。

The case when the file doesn't have a digital signature is handled in the Exception .文件没有数字签名的情况在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.为了简单起见,我使用了textbox解决方案和 GUI。

You could call signtool as external tool to validate the process signatures.您可以调用signtool作为外部工具来验证流程签名。

//  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}");
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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