<script type="text/javascript">
</script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
注意:本系列 文章在水木清华BBS(smth.org)之. Net版首发,
转载请保留以上信息,发表请与作者联系
概述
本系列 文章,将从系统层角度,通过对 MS. Net CLR架构对 PE映像结构的 扩展的分析
,
解析 MS. Net CLR架构的底层部分运行机制,帮助读者从更深层次理解 CLR中某些重要概念
本文读者应具备基本的Win32编程经验,了解. Net中常见概念意义,并对Win32之 PE映像
结构有一定了解,具体结构请参看Matt Pietrek于1994.3发表在 MSJ的经典 文章
《 PEering Inside the PE: A Tour of the Win32 Portable Executable
File Format》,与之重复的部分我一概跳过。
本系列 文章,将分为几个大部分,首先是最重要的MetaData,其次是IL代码结构,
然后……我还没想好,呵呵。此外会根据需要穿插一下 CLR核心概念、思想、技术的介绍
。
至于 CLR几个核心部件之间的关系与交互等问题,我热切期待TBSoft的大作,
我这里就不去抢他的话题了,呵呵。
前言
对一个优秀Win32程序员来说,对 PE结构的了解是对Win32架构了解的必经之路,
而从Chicago(Win95的开发代号,Win95正式发布以前的文档对Win95的称呼)以来,
PE结构就相对稳定,直到 MS. Net的出现,才发生了一些不大不小的变化。
之所以说是不大不小,是因为 CLR基本上没有对 PE结构进行改变,只是利用现有 PE
结构的优良可 扩展性,将其所需的信息 扩展到 PE映像中。具体一点说,就是利用了 PE结
构
中的IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
来保存服务于 CLR的IMAGE_COR20_HEADER结构。此外的 PE结构一律不变。
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR此节,原本是设计用于COM,但不知为何
一直没有被使用,现在用于保存. Net信息的最高级信息结构。
我们的分析也将集中在此结构以及相关信息的分析上。
IMAGE_COR20_HEADER结构的定义,可以在FrameworkSDK/include/CorHdr.h
文件中找到,如下:
// CLR 2.0 header structure.
ty PEdef 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;
而详细的说明,则可以在FrameworkSDK/Tool Develo PErs Guide/docs
目录中找到。因为要将 CLR变为标准, MS这次一反常态,公开大量有价值的文档,
避免我等浪费时间去逆向过程,呵呵
此结构虽然字段较多,但实际上其核心在于MetaData,其他信息都是围绕着
MetaData服务。之间的关系,等会再慢慢道来。
cb是结构大小,MajorRuntimeVersion.MinorRuntimeVersion是版本号
指执行此程序所需的最低 CLR版本号,目前一般设置为1.1。而现在发布的. Net
Framework的 CLR版本一般为2.0。
Flags是Runtime Image描述标志,描述此映像的执行属性。如设置位
COMIMAGE_FLAGS_32BITREQUIRED=0x02,则此映像只能在32位系统上执行
对以后的64位 CLR无效( MS. Net很大的一个功能就是为以后平滑过渡到64位
平台做准备,想想以前16位平台到32位平台过渡时的混乱,以及现在比以前翻了
n倍的代码量就恐怖, MS真是未雨绸缪啊,呵呵)。如果设置
COMIMAGE_FLAGS_STRONGNAMESIGNED=0x04,则此映像有strong name
signature(这个东东不知道怎么翻译好)。这个strong name signature
在 CLR架构里起到了非常重要的作用。为什么这么说呢?因为这个strong name
signature起到Assembly的身份证的作用,它关系到 CLR中一大堆概念的实现,
以后我会专门用一章篇幅来介绍他,这里暂且放下。
EntryPointToken则是指向IL程序的入口,类似于以前的
IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint的作用,只是以前的
AddressOfEntryPoint是一个RVA直接指向程序入口代码所在地址,
(不要告诉我你不知道RVA是什么啊,呵呵,赶快去看 PEering Inside the PE)
而现在EntryPointToken指向一个Token。注意,是Token,因为IL代码是
JIT编译的,存在于映像中的都是IL形式的P-code(pseudo code),在需要时
才由 CLR动态读取,在内存中编译展开为本机代码(Native Code),进而执行。
因此这里的程序入口执行的只是一个MethodDef或File表的入口,一个Token而已。
这里的MethodDef是一个MetaData表,每行定义一个方法;而File表则是
每行有一个File定义的表,每行包含一个外部文件的信息。也就是说,在执行程序时
可以直接编译执行此映像中的一个方法的IL代码,也可能是重定向到另一个文件,
这就是Assembly作为一个逻辑代码单元,与传统DLL之类相比一个很大的不同。
Assembly的概念也非常重要,我不想这里一下说完,以后专门拿一章出来讲好了。
剩下几个字段都是IMAGE_DATA_DIRECTORY类型,这个类型是一个数据块
定义结构,在Winnt.h中有定义
ty PEdef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
呵呵,知道RVA的意思了吧 RVA = Relative Virtual Address
Resources定义CLI资源;StrongNameSignature定义刚刚提到的
strong name signature;此外CodeManagerTable,
ExportAddressTableJumps,MangedNativeHeader都没用到。
VTableFixups暂且略过,以后用上时再详细解释。
这样一来,就剩下一个MetaData字段没有介绍了,不过这个重中之重的东东,
这次只言片语是无法介绍了,因为下面会有专门的一整篇——MetaData篇,
用n章的篇幅来详细剖析,呵呵
btw:因为自己以前不是搞Win32底层开发的,实在不知这种 文章怎么写,
希望读者多多提意见,有没有解释清楚或者错误的地方尽管提出来。
分析. Net的 CLR PE映像其实并不是什么困难的事情,有现成的
代码(mono)现成的文档(Tool Develo PErs Guide)可以看,
只是代码比较难看(不习惯unix代码风格),文档比较长
(一共20几M,poor)而已。我是实在耐不住好奇心才动手分析的,
希望能够把自己分析的一些收获和体会写出来,节省其他朋友的时间。
希望能够有充足的时间、精力和耐心完成这个系列
seover="window.status='正文--
MS.
Net
CLR
扩展
PE
结构分析(转,
很不错的
文章)';return true">
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
Flier Lu <flier_lu@sina.com.cn>
注意:本系列 文章在水木清华BBS(smth.org)之. Net版首发,
转载请保留以上信息,发表请与作者联系
概述
本系列 文章,将从系统层角度,通过对 MS. Net CLR架构对 PE映像结构的 扩展的分析
,
解析 MS. Net CLR架构的底层部分运行机制,帮助读者从更深层次理解 CLR中某些重要概念
本文读者应具备基本的Win32编程经验,了解. Net中常见概念意义,并对Win32之 PE映像
结构有一定了解,具体结构请参看Matt Pietrek于1994.3发表在 MSJ的经典 文章
《 PEering Inside the PE: A Tour of the Win32 Portable Executable
File Format》,与之重复的部分我一概跳过。
本系列 文章,将分为几个大部分,首先是最重要的MetaData,其次是IL代码结构,
然后……我还没想好,呵呵。此外会根据需要穿插一下 CLR核心概念、思想、技术的介绍
。
至于 CLR几个核心部件之间的关系与交互等问题,我热切期待TBSoft的大作,
我这里就不去抢他的话题了,呵呵。
前言
对一个优秀Win32程序员来说,对 PE结构的了解是对Win32架构了解的必经之路,
而从Chicago(Win95的开发代号,Win95正式发布以前的文档对Win95的称呼)以来,
PE结构就相对稳定,直到 MS. Net的出现,才发生了一些不大不小的变化。
之所以说是不大不小,是因为 CLR基本上没有对 PE结构进行改变,只是利用现有 PE
结构的优良可 扩展性,将其所需的信息 扩展到 PE映像中。具体一点说,就是利用了 PE结
构
中的IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
来保存服务于 CLR的IMAGE_COR20_HEADER结构。此外的 PE结构一律不变。
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR此节,原本是设计用于COM,但不知为何
一直没有被使用,现在用于保存. Net信息的最高级信息结构。
我们的分析也将集中在此结构以及相关信息的分析上。
IMAGE_COR20_HEADER结构的定义,可以在FrameworkSDK/include/CorHdr.h
文件中找到,如下:
// CLR 2.0 header structure.
ty PEdef 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;
而详细的说明,则可以在FrameworkSDK/Tool Develo PErs Guide/docs
目录中找到。因为要将 CLR变为标准, MS这次一反常态,公开大量有价值的文档,
避免我等浪费时间去逆向过程,呵呵
此结构虽然字段较多,但实际上其核心在于MetaData,其他信息都是围绕着
MetaData服务。之间的关系,等会再慢慢道来。
cb是结构大小,MajorRuntimeVersion.MinorRuntimeVersion是版本号
指执行此程序所需的最低 CLR版本号,目前一般设置为1.1。而现在发布的. Net
Framework的 CLR版本一般为2.0。
Flags是Runtime Image描述标志,描述此映像的执行属性。如设置位
COMIMAGE_FLAGS_32BITREQUIRED=0x02,则此映像只能在32位系统上执行
对以后的64位 CLR无效( MS. Net很大的一个功能就是为以后平滑过渡到64位
平台做准备,想想以前16位平台到32位平台过渡时的混乱,以及现在比以前翻了
n倍的代码量就恐怖, MS真是未雨绸缪啊,呵呵)。如果设置
COMIMAGE_FLAGS_STRONGNAMESIGNED=0x04,则此映像有strong name
signature(这个东东不知道怎么翻译好)。这个strong name signature
在 CLR架构里起到了非常重要的作用。为什么这么说呢?因为这个strong name
signature起到Assembly的身份证的作用,它关系到 CLR中一大堆概念的实现,
以后我会专门用一章篇幅来介绍他,这里暂且放下。
EntryPointToken则是指向IL程序的入口,类似于以前的
IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint的作用,只是以前的
AddressOfEntryPoint是一个RVA直接指向程序入口代码所在地址,
(不要告诉我你不知道RVA是什么啊,呵呵,赶快去看 PEering Inside the PE)
而现在EntryPointToken指向一个Token。注意,是Token,因为IL代码是
JIT编译的,存在于映像中的都是IL形式的P-code(pseudo code),在需要时
才由 CLR动态读取,在内存中编译展开为本机代码(Native Code),进而执行。
因此这里的程序入口执行的只是一个MethodDef或File表的入口,一个Token而已。
这里的MethodDef是一个MetaData表,每行定义一个方法;而File表则是
每行有一个File定义的表,每行包含一个外部文件的信息。也就是说,在执行程序时
可以直接编译执行此映像中的一个方法的IL代码,也可能是重定向到另一个文件,
这就是Assembly作为一个逻辑代码单元,与传统DLL之类相比一个很大的不同。
Assembly的概念也非常重要,我不想这里一下说完,以后专门拿一章出来讲好了。
剩下几个字段都是IMAGE_DATA_DIRECTORY类型,这个类型是一个数据块
定义结构,在Winnt.h中有定义
ty PEdef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
呵呵,知道RVA的意思了吧 RVA = Relative Virtual Address
Resources定义CLI资源;StrongNameSignature定义刚刚提到的
strong name signature;此外CodeManagerTable,
ExportAddressTableJumps,MangedNativeHeader都没用到。
VTableFixups暂且略过,以后用上时再详细解释。
这样一来,就剩下一个MetaData字段没有介绍了,不过这个重中之重的东东,
这次只言片语是无法介绍了,因为下面会有专门的一整篇——MetaData篇,
用n章的篇幅来详细剖析,呵呵
btw:因为自己以前不是搞Win32底层开发的,实在不知这种 文章怎么写,
希望读者多多提意见,有没有解释清楚或者错误的地方尽管提出来。
分析. Net的 CLR PE映像其实并不是什么困难的事情,有现成的
代码(mono)现成的文档(Tool Develo PErs Guide)可以看,
只是代码比较难看(不习惯unix代码风格),文档比较长
(一共20几M,poor)而已。我是实在耐不住好奇心才动手分析的,
希望能够把自己分析的一些收获和体会写出来,节省其他朋友的时间。
希望能够有充足的时间、精力和耐心完成这个系列
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>