分享
 
 
 

浅析.NETFramework对PE文件格式的扩展

王朝c#·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

Microsoft .NET Framework出来小阵子了,我也自从其Beta 1以来,第一次接触。本文将从.NET生成的一个小PE文件着手,旨在理解.NET Framework对PE文件格式的扩展。这种扩展目的是让Windows系统识别Common Language Runtime(CLR)。

PE文件是Windows系列操作系统的可执行文件格式。本文假设您对这一文件格式有相当的理解,文中未涉及PE在之前的win16及之后的win64上的讨论。在CLR出现之前,PE文件格式仅简单的由PE Header与Native Image(相对于以下介绍的CLR Header与CLR Data部分)组成。Native Image由各个section组成,如.text,.data,.rdate等等,需要指出的是PE文件的这些section名命名规则并不要求一定要以句点开头,事实上这只是Microsoft的对于代码段或数据段的默认说法,像Borland等其他编译器则相应分别命名为CODE,DATA等等。Native Image含有已编译的相应处理器的机器代码。

在CLR出现后PE文件扩展出了另外一部分,即CLR Header与CLR Data组成的供.NET

Framework运行的支撑部分。CLR Header由.NET Framework SDK的CorHdr.h中的IMAGE_COR20_HEADER结构定义。从CorHdr.h或是IMAGE_COR20_HEADER的命名中Cor的全称Com+ Runtime即可隐隐约约的看到.NET Framework的发展过程,其与COM+的渊源关系了。事实上IMAGE_COR20_HEADER在平台SDK的winnt.h中也有定义,我查阅的了随Windows XP DDK Build 2505发行的winnt.h中Microsoft在给出这个定义时的注释为COM+ 2.0 header structure,而在.NET Framework SDK中即修改为CLR 2.0 header structure了。CLR Data则包含.NET metadata, IL method bodies等等。metadata及IL method是.NET中很关键的术语。IL即Microsoft Intermediate Language的缩写。她是为了.NET跨平台、跨语言的特性而引入的,有其自身的指令集。.NET SDK中的opcode.def列出的其支持的指令集。粗粗看来这些指令集与Intel的X86指令集十分的相像,也是由Prefix指定的的双字节进行编码。

下面的我将通过底下列出的这一段C# Console代码来简述C#编译器生成的PE文件的执行流程及PE文件的on disk结构。代只是简单的输出Hi,如下所示:

public class App {

static public void Main(System.String[] args) {

System.Console.WriteLine("Hi");

}

}

我们简单的使用csc /out:app.exe app.cs对其编译。生成的PE文件,与.NET出现前传统的编译器生成的PE文件一致,也含有IMAGE_DOS_HEADER,我们知道这部分的作用即是早期的DOS在遇到PE文件格式时,能判定这个可执行文件不能执行于DOS下而存在的。IMAGE_DOS_HEADER与将要谈及的一些结构在winnt.h中均有详细定义。Windows OS Loader根据IMAGE_DOS_HEADER中的e_lfanew成员定位紧挨着的IMAGE_NT_HEADERS。其定义如下:

typedef struct _IMAGE_NT_HEADERS {

DWORD Signature;

IMAGE_FILE_HEADER FileHeader;

IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

我们知道IMAGE_OPTIONAL_HEADER32的成员AddressOfEntryPoint 是PE可执行文件的入口,在.NET中其仍为执行入口,这应该是很好理解的。对于一个COMIMAGE_FLAGS_ILONLY(由IMAGE_COR20_HEADER 的成员Flags 指定)的Image,如我们生成的App.exe,这个入口也即间接定位至App.exe的Import表的_CorExeMain函数。_CorExeMain对应EXE文件,由mscoree.dll导出。mscoree.dll位于%WINNT%\system32下,是Microsoft .NET Runtime Execution Engine,应该指出的她是一个Native Image,负责调用IMAGE_COR20_HEADER中的 EntryPointToken 指定的.NET Token。这才是真正IL语言的入口。

Native Image部分的各个Section的定位,已经有很多文档介绍,而且winnt.h中都有详细的定义。我只简单的阐述一下:

.text、.data等section定位是由IMAGE_OPTIONAL_HEADER32中的DataDirectory成员指定。DataDirectory是一个IMAGE_DATA_DIRECTORY数组,个数为MAGE_NUMBEROF_DIRECTORY_ENTRIES(当前为16)个。各个DataDirectory功能分别由IMAGE_DIRECTORY_ENTRY_***指定,如EXPORT、IMPORT等等。因为IMAGE_DATA_DIRECTORY由VirtualAddress(RVA)与Size组成,所以我们即可以很容易的找到这些Section的位置。与这些Section一样,CLR Header的定位也是DataDirectory指定,其为IMAGE_DIRECTORY_ENTRY_COMHEADER(值为14,.NET Framework SDK V1 CorHdr.h中称谓,在DDK 2505的winnt.h中为IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)。我们生成的App.exe有如下的格式:

.

.

.

AddressOfEntryPoint: 0x000022CE (+0x10)

.

.

.

DataDirectory[0] - IMAGE_DIRECTORY_ENTRY_EXPORT

VirtualAddress: 0x00000000 (+0x60)

Size: 0x00000000 (+0x64)

DataDirectory[1] - IMAGE_DIRECTORY_ENTRY_IMPORT

VirtualAddress: 0x0000227C (+0x68)

Size: 0x0000004F (+0x6C)

.

.

.

DataDirectory[14] - IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR

VirtualAddress: 0x00002008 (+0xD0)

Size: 0x00000048 (+0xD4)

.

.

.

OK,从DataDirectory[14]我们即可以很容易的定位CLR Header。CLR Header可以被合并到其它任何为只读属性的Section中。前面已经提及到CLR Header由IMAGE_COR20_HEADER结构定义。

// CLR 2.0 header structure.

typedef struct IMAGE_COR20_HEADER

{

// Header versioning

ULONG cb;

USHORT MajorRuntimeVersion;

USHORT MinorRuntimeVersion;

// Symbol table and startup information

IMAGE_DATA_DIRECTORY MetaData;

ULONG Flags;

ULONG EntryPointToken;

// Binding information

IMAGE_DATA_DIRECTORY Resources;

IMAGE_DATA_DIRECTORY StrongNameSignature;

// Regular fixup and binding information

IMAGE_DATA_DIRECTORY CodeManagerTable;

IMAGE_DATA_DIRECTORY VTableFixups;

IMAGE_DATA_DIRECTORY ExportAddressTableJumps;

// Precompiled image info (internal use only - set to zero)

IMAGE_DATA_DIRECTORY ManagedNativeHeader;

} IMAGE_COR20_HEADER;

这个结构的Flags与EntryPointToken上面已经提及。从这么多的IMAGE_DATA_DIRECTORY上看,这个定义很像IMAGE_OPTIONAL_HEADER32,后者可以理解成PE文件头的精华,其用于定位.text等Section,由Windows OS Loader执行。而前者用于定位.NET CLR Data,如MetaData、Resources、StrongNameSignature等等。不同的是IMAGE_COR20_HEADER是由mscoree.dll中的_CorExeMain(对应于EXE文件)负责调用(MSIL语言需经过JIT编译成机器码才可执行)。

虽然EnrtyPointToken与上面的AddressOfEntryPoint均是执行入口,但却有非常大的区别。AddressOfEntryPoint是一RVA,直接指向执行地址(相对于Image Base),其只能指向一本地机器代码用于装载NET Runtime(如mscoree.dll中的_CorExeMain,对于DLL文件其可以置为0)。而EntryPointToken只是一个.NET TOKEN。TOKEN是.NET Type的唯一识别,是一个DWORD值。其最高的8bit指明何种TOKEN。其由CorHdr.h中的CorTokenType enum定义。如mdtMethodDef为0x06000000,mdtEvent为0x14000000等等,而余下的24bit则为此类TOKEN的唯一识别。EnrtyPointToken只能是一METHOD,而不能是EVENT等等。如App.Exe的EnrtyPointTokeno为0x06000001,其对应于Main Method。您可以使用ildasm.exe(随.NET Framework SDK提供)进行验证。

App.exe的CLR Header如下(只列出了部分非空字段):

Size: 0x00000048

MajorRuntimeVersion: 0x0002

MinorRuntimeVersion: 0x0000

MetaData

VirtualAddress: 0x0000207C

Size: 0x00000200

Flags: 0x00000001

COMIMAGE_FLAGS_ILONLY

EntryPointToken: 0x06000001

.NET MetaData由MetaData成员指定。Microsoft在CorHdr.h中给出了ILMETHOD的on disk组织结构(IMAGE_COR_ILMETHOD)。随.NET Framework SDK也提供了一个例子metainfo用于分析Metadata。随QuickStart例子的Class Browser的ASP.NET范例也是.NET Framework很好的学习材料。Metainfo使用常规的COM方法,而Class Browser使用.NET Framework的System.Reflection Namespace。关于.NET的SOAP,Web Services,Web Forms,XML等等QuickStart真不愧为QuickStart,.NET看来是下阵子学习的方向啊。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有