如何使用 System.Reflection 中的 PEReader 从 DLLImport 属性获取 DLL 名称/路径?

发布于 2025-01-13 21:38:06 字数 1590 浏览 0 评论 0原文

我正在编写一个实用程序,它可以反汇编用 c# 编写的 dll/exe 文件,然后扫描该文件内的所有类型是否存在从非托管 DLL 导入的方法。我需要获取有关每个导入方法的信息,包括导入该方法的 DLL 的名称/路径,即 DllImport 属性的第一个参数的值。假设 dll/exe 文件中有这样一个函数声明:

[DllImport("C:\\TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void HelloWorld();

我是反射新手,正在尝试使用 PEReader 查看所有类型并搜索从 DLL 导入的函数。我从 System.Reflection.Metadata.MethodDefinition 调用 GetImport() 来确定当前 MethodDefinition 是否是导入的方法。通过 GetImport().Attributes 我希望获得所有 DllImport 参数,包括该 DLL 的路径,但这并没有给出所需的结果:

using (var fileStream = new FileStream(pathToBinary, FileMode.Open, FileAccess.Read))
{
    using (var peReader = new PEReader(fileStream))
    {
        var mdReader = peReader.GetMetadataReader();

        foreach (var typeHandler in mdReader.TypeDefinitions)
        {
            var typeDef = mdReader.GetTypeDefinition(typeHandler);

            foreach (var methodHandler in typeDef.GetMethods())
            {
                var methodDef = mdReader.GetMethodDefinition(methodHandler);
                var import = methodDef.GetImport();
                if(import.Module.IsNil)
                {
                    continue;
                }

                //Returns "CallingConventionCdecl" but not ""C:\\TestDll.dll," CallingConventionCdecl":
                var dllImportParameters = import.Attributes.ToString();
            }
        }
    }
}

GetMethod().Attributes< /code> 返回除导入方法的库名称/路径之外的所有 DLLImport 参数。

如何从 DllImport 的第一个参数获取 DLL 路径?

I am writing a utility that disassembles dll/exe files written in c#, and then scans all types inside this file for the presence of methods imported from an unmanaged DLL. I need to get information about each imported method, including the name/path of the DLL from which this method is imported, that is, the value of the first argument of the DllImport attribute. Let's assume that there is such a function declaration in the dll/exe file:

[DllImport("C:\\TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void HelloWorld();

I am new to reflection and am trying to use PEReader to view all types and search for functions imported from DLL. I'm calling GetImport() from the System.Reflection.Metadata.MethodDefinition to determine whether the current MethodDefinition is an imported method. Via GetImport().Attributes I hope to get all the DllImport parameters, including the path of this DLL, but this does not give the desired result:

using (var fileStream = new FileStream(pathToBinary, FileMode.Open, FileAccess.Read))
{
    using (var peReader = new PEReader(fileStream))
    {
        var mdReader = peReader.GetMetadataReader();

        foreach (var typeHandler in mdReader.TypeDefinitions)
        {
            var typeDef = mdReader.GetTypeDefinition(typeHandler);

            foreach (var methodHandler in typeDef.GetMethods())
            {
                var methodDef = mdReader.GetMethodDefinition(methodHandler);
                var import = methodDef.GetImport();
                if(import.Module.IsNil)
                {
                    continue;
                }

                //Returns "CallingConventionCdecl" but not ""C:\\TestDll.dll," CallingConventionCdecl":
                var dllImportParameters = import.Attributes.ToString();
            }
        }
    }
}

That is, GetMethod().Attributes returns all DLLImport parameters except the library name/path from which the method is imported.

How do I get the DLL path from the first argument of DllImport?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

囚我心虐我身 2025-01-20 21:38:06

我找到了解决问题的方法。因此,import 有一个 Module 属性,它返回 System.Reflection.Metadata.ModuleReferenceHandle 的实例。使用MetaDataReader.GetModuleReference(moduleReferenceHandle),可以将其转换为System.Reflection.Metadata.ModuleReference。反过来,ModuleReference 的实例有一个 Name 属性,该属性返回 StringHandle,也可以使用 MetaDataReader.GetString(字符串句柄)。这是 DLL 的名称/路径。

问题的完整解决:

string dllPath = mdReader.GetString(mdReader.GetModuleReference(import.Module).Name);

I found a solution to my problem. So import has a Module property that returns an instance of System.Reflection.Metadata.ModuleReferenceHandle. With MetaDataReader.GetModuleReference(moduleReferenceHandle) it can be converted to System.Reflection.Metadata.ModuleReference. In turn, an instance of ModuleReference has a Name property that returns StringHandle and can also be converted to string using MetaDataReader.GetString(stringHandle). This is the name/path of the DLL.

Full resolution of the issue:

string dllPath = mdReader.GetString(mdReader.GetModuleReference(import.Module).Name);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文