You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取WPF进程中已加载的所有DLL?模块检测异常排查

问题:检测WPF项目中已加载的自定义DLL并验证签名

项目信息

  • 项目文件夹路径:F:\workspace\VantageAddin\aiscreenshotaddin\src\AIScreenshotAddin\bin\x64\Release\AIScreenshot
  • 文件夹内文件:
    • app.exe
    • 1.dll
    • 2.dll
    • 3.dll

问题描述

在WPF项目文件夹中,存在app.exe和多个自定义DLL文件(如1.dll、2.dll、3.dll),app.exe会加载其中部分DLL到进程空间。所有EXE和DLL均已添加Windows数字签名,需要检测已加载的DLL并验证其签名,只有所有已加载DLL签名有效时才继续执行主函数(目的是防止DLL被替换或注入未签名文件,因此仅检测已加载的DLL,而非文件夹内所有文件)。

使用以下代码获取已加载模块:

Process myProcess = Process.GetCurrentProcess();
foreach (ProcessModule module in myProcess.Modules)
{
    Logger.Debug(ClassName, $", dll module, FileName: {module.FileName}, BaseAddress: {module.BaseAddress}, ModuleName: {module.ModuleName}");
    File.AppendAllText("D:\\111.txt", $"dll module, FileName: {module.FileName}, BaseAddress: {module.BaseAddress}, ModuleName: {module.ModuleName}");
    File.AppendAllText("D:\\111.txt", Environment.NewLine);
}

但输出结果中仅显示app.exe来自项目文件夹,自定义的1.dll、2.dll等已加载的DLL未被检测到。

输出结果示例

dll module, FileName: F:\workspace\VantageAddin\aiscreenshotaddin\src\AIScreenshotAddin\bin\x64\Release\AIScreenshot\app.exe, BaseAddress: 1790275420160, ModuleName: app.exe
dll module, FileName: C:\windows\SYSTEM32\ntdll.dll, BaseAddress: 140723926794240, ModuleName: ntdll.dll
dll module, FileName: C:\windows\SYSTEM32\MSCOREE.DLL, BaseAddress: 140723452182528, ModuleName: MSCOREE.DLL
...(其余系统模块省略)

补充说明

需要验证的是Windows文件属性中的数字签名(包含签名者、时间戳等信息,非.NET强名称签名)。


原因分析

  1. 模块类型差异:Process.Modules仅返回由Windows原生加载器加载的模块(如系统DLL、EXE),而WPF项目中的自定义DLL是.NET托管程序集,由CLR(公共语言运行时)负责加载,这类模块不会出现在Process.Modules的结果中。
  2. 加载时机过早:如果检测代码执行时,自定义DLL还未被实际触发加载(比如延迟加载的程序集尚未被调用),也会导致无法检测到。

解决方案

1. 获取已加载的托管程序集

使用AppDomain.CurrentDomain.GetAssemblies()获取当前应用域中所有已加载的.NET托管程序集,示例代码:

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
    try
    {
        string filePath = assembly.Location;
        if (!string.IsNullOrEmpty(filePath) && filePath.StartsWith(@"F:\workspace\VantageAddin\aiscreenshotaddin\src\AIScreenshotAddin\bin\x64\Release\AIScreenshot"))
        {
            Console.WriteLine($"已加载自定义程序集:{filePath}");
            // 调用签名验证方法
            if (!IsFileSigned(filePath))
            {
                // 签名无效,终止程序或处理异常
                Environment.Exit(1);
            }
        }
    }
    catch (NotSupportedException)
    {
        // 跳过动态生成的无文件路径的程序集
        continue;
    }
}

2. 验证Windows数字签名

使用X509Certificate2相关API验证文件的数字签名有效性,示例方法:

using System.Security.Cryptography.X509Certificates;

public static bool IsFileSigned(string filePath)
{
    try
    {
        // 从签名文件创建证书
        using (X509Certificate2 cert = X509Certificate2.CreateFromSignedFile(filePath))
        {
            // 构建证书链并验证有效性
            using (X509Chain chain = new X509Chain())
            {
                // 根据需求调整吊销检查策略,这里暂时关闭吊销检查
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                // 验证证书链是否有效
                return chain.Build(cert);
            }
        }
    }
    catch
    {
        // 文件无签名或签名无效时抛出异常,返回false
        return false;
    }
}

3. 确保程序集已加载

如果部分程序集是延迟加载的,需要在执行检测前触发相关代码逻辑,确保目标DLL被CLR加载。也可以通过Assembly.Load显式加载必要的程序集后再进行检测。


内容的提问来源于stack exchange,提问作者Tom Xue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:40:32