求判断一个dll是.NET assembly还是Win32的快捷方法

lextm 2007-11-03 06:32:18
两种dll的文件格式肯定有差别,怎么通过分析文件来作出判断?第几个byte可以看出来呢?
...全文
202 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lextm 2008-03-18
  • 打赏
  • 举报
回复
还有一种办法比楼上的反射要稍微好一点(反射加载的dll不能unload,比较占内存)

public static bool IsDotNetAssembly3(string fileName)
{
bool result = true;
Mono.Cecil.AssemblyDefinition myLibrary = null;
try
{
myLibrary = Mono.Cecil.AssemblyFactory.GetAssembly (fileName);
}
catch (Mono.Cecil.Binary.ImageFormatException)
{
// for win32 dll
result = false;
}
catch (ArgumentOutOfRangeException)
{
// for win32 exe
result = false;
}
return result && myLibrary != null;
}


需要使用Mono项目的Cecil。http://www.mono-project.com/Cecil

这个方法还需要更多的测试。
lextm 2008-03-01
  • 打赏
  • 举报
回复
上面的代码还是有点问题。换回了最初的代码,

/// <summary>
/// Verifies whether it is a .NET file.
/// </summary>
/// <param name="fileName">File name</param>
/// <returns>true if it is .NET, false if else.</returns>
public static bool IsDotNetAssembly(string fileName) {
bool result = true;
try {
System.Reflection.Assembly.LoadFrom(fileName);
} catch (BadImageFormatException ex) {
int errorCode = System.Runtime.InteropServices.Marshal.GetHRForException(ex);
if (errorCode == COR_E_ASSEMBLYEXPECTED)
{
result = false;
}
}
return result;
}

private const int COR_E_ASSEMBLYEXPECTED = -2146234344;
lextm 2007-11-04
  • 打赏
  • 举报
回复
刚刚从Google上面找到一个函数
/// <summary>
/// Verifies whether it is a .NET file.
/// </summary>
/// <param name="fileName">File name</param>
/// <returns>true if it is .NET, false if else.</returns>
public static bool IsDotNetAssembly(string fileName)
{
bool result = false;
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();
}
result = dataDictionaryRVA[14] != 0;
fs.Close();
return result;
}

还是读取PE的元数据来做的判断。
windily 2007-11-03
  • 打赏
  • 举报
回复
关注..........
蒋晟 2007-11-03
  • 打赏
  • 举报
回复
Microsoft Portable Executable and Common Object File Format Specification http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
An In-Depth Look into the Win32 Portable Executable File Format, Part 2
http://msdn.microsoft.com/msdnmag/issues/02/03/Pe2/

17,741

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧