原始标题:如何防止从.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吧?
发布于 2008-12-15 08:50:30
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;
}
https://stackoverflow.com/questions/367761
复制相似问题