首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何确定DLL是托管程序集还是本机程序集(防止加载本机dll)?

如何确定DLL是托管程序集还是本机程序集(防止加载本机dll)?
EN

Stack Overflow用户
提问于 2008-12-15 08:22:25
回答 7查看 14.5K关注 0票数 31

原始标题:如何防止从.NET应用程序加载本机dll?

背景:

我的C#应用程序包括一个插件框架和通用插件加载程序。

插件加载程序枚举应用程序目录,以便识别plugin (实际上此时它搜索*.dll )。

在同一个应用程序目录中有一个本机(Windows,non-.net) dll,它间接地依赖于一个插件dll。

插件加载程序盲目地假定native.dll是一个.NET程序集dll,仅仅因为它只检查文件扩展名。当尝试加载本机dll时,会引发异常:

“无法加载文件或程序集'native.dll‘或其依赖项之一。预计该模块将包含程序集清单。”

如果插件加载失败,我基本上会创建一个诊断报告,因此我试图避免让这个日志中充满关于无法加载本机dll (我甚至不想尝试)的消息。

问题:

是否有一些.NET API调用,可以用来确定二进制文件是否恰好是.NET程序集,以便我根本不尝试加载本机.NET程序集?

也许从长远来看,我会将插件移到子目录中,但现在,我只想做一项不涉及在插件加载程序中硬编码"native.dll“名称的工作。

我想我在寻找某种静态的Assembly.IsManaged() API调用,我忽略了.大概不存在这样的API吧?

EN

Stack Overflow用户

发布于 2008-12-15 08:50:30

如何确定文件是否为.NET程序集?

代码语言:javascript
运行
复制
public static bool IsManagedAssembly(string fileName)
{
    uint peHeader;
    uint peHeaderSignature;
    ushort machine;
    ushort sections;
    uint timestamp;
    uint pSymbolTable;
    uint noOfSymbol;
    ushort optionalHeaderSize;
    ushort characteristics;
    ushort dataDictionaryStart;
    uint[] dataDictionaryRVA = new uint[16];
    uint[] dataDictionarySize = new uint[16];

    Stream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    BinaryReader reader = new BinaryReader(fs);

    //PE Header starts @ 0x3C (60). Its a 4 byte header.
    fs.Position = 0x3C;
    peHeader = reader.ReadUInt32();

    //Moving to PE Header start location...
    fs.Position = peHeader;
    peHeaderSignature = reader.ReadUInt32();

    //We can also show all these value, but we will be       
    //limiting to the CLI header test.
    machine = reader.ReadUInt16();
    sections = reader.ReadUInt16();
    timestamp = reader.ReadUInt32();
    pSymbolTable = reader.ReadUInt32();
    noOfSymbol = reader.ReadUInt32();
    optionalHeaderSize = reader.ReadUInt16();
    characteristics = reader.ReadUInt16();

    // Now we are at the end of the PE Header and from here, the PE Optional Headers starts... To go directly to the datadictionary, we'll increase the stream’s current position to with 96 (0x60). 96 because, 28 for Standard fields 68 for NT-specific fields From here DataDictionary starts...and its of total 128 bytes. DataDictionay has 16 directories in total, doing simple maths 128/16 = 8. So each directory is of 8 bytes. In this 8 bytes, 4 bytes is of RVA and 4 bytes of Size. btw, the 15th directory consist of CLR header! if its 0, its not a CLR file :)
    dataDictionaryStart = Convert.ToUInt16(Convert.ToUInt16(fs.Position) + 0x60);
    fs.Position = dataDictionaryStart;
    for (int i = 0; i < 15; i++)
    {
        dataDictionaryRVA[i] = reader.ReadUInt32();
        dataDictionarySize[i] = reader.ReadUInt32();
    }
    fs.Close();

    if (dataDictionaryRVA[14] == 0) return false;
    else return true;
}
票数 18
EN
查看全部 7 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/367761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档