How to Determine if a file is a .Net assembly (in Delphi and C#)
来源:互联网 发布:程序员入门必看书籍 编辑:程序博客网 时间:2024/05/29 00:29
How would you go about it?
1. A couple of words about the PE file format
.Net assemblies are valid PE files. A PE file consists of:
* MS-DOS header
* Stub Program
* PE file signature
* PE file header (This is where we position our stream)
* PE optional header
* Section headers (This is where the RVA15 is)
* Section bodies
The PE file header is where we position our file stream at byte offset 60. The 32 bits at this position are the magical number whose value determine if this is a 32 bit (value = 0x010B) or 64 bit (value=0x020B) PE image. This is important since there is a different offset to the data dictionary for these different types of images. 32 bit images have 0x60 offset to dictionary while 64bit images have a 32 bit offset to the data dictionary. The RVA dictionary is a sequence of 16 pairs of 32 bit. Each RVA entry is 8 bytes. Skipping to RVA15 means skipping 14*8 = 112 = 0x70
A PE file is considered a .Net assembly when RVA15 contains a non zero value. RVA 15 points to the CLI header.
For Further details about the CLI header:
http://dotnet.di.unipi.it/EcmaSpec/PartitionII/cont24.html
Microsoft PE file format:
http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
2. IsDotNetAssembly - Delphi version
function IsDotNetAssembly(FileName: string):boolean;
var
fs: TFileStream;
peHeader: LongWord;
peMagicNumber: Word; //contains if it is 32bit or 64bit image
RVA15Value: LongWord;
DictionaryOffset: LongWord;
begin
result := false;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
fs.Position := $3C; //PE Header start offset.
fs.ReadBuffer(peHeader,sizeOf(peHeadeR));
fs.Position := peHeader + $18;
fs.ReadBuffer(peMagicNumber, sizeOf(peMagicNumber));
case peMagicNumber of
$010B: DictionaryOffset := $60; //32 bit Image
$020B: DictionaryOffset := $70; //64 bit Image
else
raise Exception.Create('Invalid Image Format');
end;
//Position to RVA 15 of the DataDictionary.
fs.Position := peHeader + $18 + DictionaryOffset + $70;
//Read the value.
fs.ReadBuffer(RVA15Value,sizeOf(RVA15Value));
//If this value is non zero this is a clr assembly
result := RVA15Value <> 0;
finally
fs.free;
end;
end;
3. IsDotNetAssembly C# Implementation
Just for the fun of it, here is the C# version.private bool IsDotNetAssembly(string fileName)
{
using (FileStream fs =
new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
try
{
using (BinaryReader binReader = new BinaryReader(fs))
{
try
{
fs.Position = 0x3C; //PE Header start offset
uint headerOffset = binReader.ReadUInt32();
fs.Position = headerOffset + 0x18;
UInt16 magicNumber = binReader.ReadUInt16();
switch (magicNumber)
{
case 0x010B: dictionaryOffset = 0x60; break;
case 0x020B: dictionaryOffset = 0x70; break;
default:
throw new Exception("Invalid Image Format");
}
//position to RVA 15
fs.Position = headerOffset + 0x18 +
dictionaryOffset + 0x70;
//Read the value
uint rva15value = binReader.ReadUInt32();
return rva15value != 0;
finally
{
binReader.Close();
}
}
}
finally
{
fs.Close();
}
}
}
- How to Determine if a file is a .Net assembly (in Delphi and C#)
- How to determine if a machine is localhost?
- How to determine if a driver should have been registered in kernel and lspci vs pci_device_id
- How to justify if a file is locked
- How to: Determine if a Package that is About to be Compiled is Being Used Currently (文档 ID 1054939.6
- How To Determine When a Page Is Done Loading in WebBrowser Control
- How to Open a Text File in VB .NET
- How to determine the size of a class/struct in the C++?
- How To Determine Table/View Name in a Form
- CSC231 How to play a wav file in Ciscussion C
- How To: Check if a user is part of a SharePoint group in InfoPath
- How to determine who is logged on to a database by using Microsoft Jet UserRoster in Access 2000
- How to Output a List of Files to a File and Sort Them in Linux
- Given two strings s and t, write a function to determine if t is an anagram of s.
- Given two strings s and t, write a function to determine if t is an anagram of s.
- How to define a template class in a .h file and implement it in a .cpp file
- How to embed a manifest in an assembly
- Given an integer, write a function to determine if it is a power of two.
- 小袋鼠你往哪儿跳——遗传算法基础及其本质
- 两个手机生产治具
- 一种正规的性能调优方法:基于等待的调优
- 架构和框架的区别
- 揭示常见的重构误区
- How to Determine if a file is a .Net assembly (in Delphi and C#)
- 探求真正的SOA
- WML教程
- 读重构 (Refactoring:Improving the Design of Existing Code)
- 【算法】实现对中文字符串数组按照音序排列
- OpenSocial规范、实现现状与展望
- 【算法】截取字符串(判断汉字)
- 虚拟技术与安全
- 【数据加密】易懂易用的MD5加密(可直接运行)(2)