Vae*_*tus 6 c# dll 64-bit parsing portable-executable
我正在努力将32位Web应用程序迁移到64位,并且我的插件加载器代码存在一些问题.
在32位版本中,我们扫描所有.net dll的webapps bin目录,然后加载它们Assembly.Load以检查我们的插件属性是否存在.
我们使用公共域代码以相当漂亮的方式完成了这项工作:
/// <summary>
/// Returns true if the file specified is a real CLR type,
/// otherwise false is returned.
/// False is also returned in the case of an exception being caught
/// </summary>
/// <param name="file">A string representing the file to check for
/// CLR validity</param>
/// <returns>True if the file specified is a real CLR type,
/// otherwise false is returned.
/// False is also returned in the case of an exception being
/// caught</returns>
public static bool IsDotNetAssembly(String file)
{
Stream fs = new FileStream(@file, FileMode.Open, FileAccess.Read);
try
{
BinaryReader reader = new BinaryReader(fs);
//PE Header starts @ 0x3C (60). Its a 4 byte header.
fs.Position = 0x3C;
uint peHeader = reader.ReadUInt32();
//Moving to PE Header start location...
fs.Position = peHeader;
uint peHeaderSignature = reader.ReadUInt32();
ushort machine = reader.ReadUInt16();
ushort sections = reader.ReadUInt16();
uint timestamp = reader.ReadUInt32();
uint pSymbolTable = reader.ReadUInt32();
uint noOfSymbol = reader.ReadUInt32();
ushort optionalHeaderSize = reader.ReadUInt16();
ushort characteristics = reader.ReadUInt16();
// PE Optional Headers
// To go directly to the datadictionary, we'll increase the stream's current position to with 96 (0x60).
// 28 bytes for Standard fields
// 68 bytes for NT-specific fields
// 128 bytes DataDictionary
// DataDictionay has 16 directories
// 8 bytes per directory (4 bytes RVA and 4 bytes of Size.)
// 15th directory consist of CLR header! (if its 0, it is not a CLR file )
uint[] dataDictionaryRVA = new uint[16];
uint[] dataDictionarySize = new uint[16];
ushort 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();
}
if (dataDictionaryRVA[14] == 0)
{
fs.Close();
return false;
}
else
{
fs.Close();
return true;
}
}
catch (Exception)
{
return false;
}
finally
{
fs.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
现在问题是我们现在必须处理64位或平台独立的dll,并且偏移量似乎已经改变,并且此代码失败.有没有人知道对上述代码的正确修改,对于有效的64位唯一OR平台无关的dll返回true?
您的代码不适用于x64-Bit DLL的原因是因为x64-Bit DLL和x86-Bit DLL的映像可选标头大小不同.您必须考虑不同的图像可选标头大小,以确定给定的DLL是否是.Net DLL.
的PE文件格式规范描述在3.4节(可选报头)的不同的偏移量,跳转到数据目录:
0x60(就像在您的代码中一样)和0x70.为了确定给定的DLL是否是x64位DLL,您必须读取可选标头的魔术字节:
0x20bPE32 +,0x10bPE32.我扩展了你的例子:
Stream fs = new FileStream(@file, FileMode.Open, FileAccess.Read);
try
{
BinaryReader reader = new BinaryReader(fs);
//PE Header starts @ 0x3C (60). Its a 4 byte header.
fs.Position = 0x3C;
uint peHeader = reader.ReadUInt32();
//Moving to PE Header start location...
fs.Position = peHeader;
uint peHeaderSignature = reader.ReadUInt32();
ushort machine = reader.ReadUInt16();
ushort sections = reader.ReadUInt16();
uint timestamp = reader.ReadUInt32();
uint pSymbolTable = reader.ReadUInt32();
uint noOfSymbol = reader.ReadUInt32();
ushort optionalHeaderSize = reader.ReadUInt16();
ushort characteristics = reader.ReadUInt16();
long posEndOfHeader = fs.Position;
ushort magic = reader.ReadUInt16();
int off = 0x60; // Offset to data directories for 32Bit PE images
// See section 3.4 of the PE format specification.
if (magic == 0x20b) //0x20b == PE32+ (64Bit), 0x10b == PE32 (32Bit)
{
off = 0x70; // Offset to data directories for 64Bit PE images
}
fs.Position = posEndOfHeader;
uint[] dataDictionaryRVA = new uint[16];
uint[] dataDictionarySize = new uint[16];
ushort dataDictionaryStart = Convert.ToUInt16(Convert.ToUInt16(fs.Position) + off);
fs.Position = dataDictionaryStart;
for (int i = 0; i < 15; i++)
{
dataDictionaryRVA[i] = reader.ReadUInt32();
dataDictionarySize[i] = reader.ReadUInt32();
}
if (dataDictionaryRVA[14] == 0)
{
fs.Close();
return false;
}
else
{
fs.Close();
return true;
}
}
catch (Exception)
{
return false;
}
finally
{
fs.Close();
}
Run Code Online (Sandbox Code Playgroud)
在Windows SDK中,还有为PE32/PE32 +可选标头定义的结构.这些结构的描述可以在MSDN中找到.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
1761 次 |
| 最近记录: |