现在的位置: 首页 > 综合 > 正文

.NET对PE结构的扩展

2013年01月19日 ⁄ 综合 ⁄ 共 3049字 ⁄ 字号 评论关闭
 

可执行文件的格式是反映一个系统程序运行机制的重要方面,Win32下可执行文件是读者已经非常熟悉的PE格式,
在.NET系统中,运行机制的改变带来了可执行文件格式的扩展。一方面,.NET建立在Win32/64的基础上,兼容性的要求决定了.NET的可执行文
件必须是在PE的基础上进行扩展;另一方面,Win32中PE文件存储的是汇编代码,而.NET中存储的是MSIL与元数据,后者无论是在逻辑结构还是物
理结构上,都与传统PE格式有很大区别。本章将详细讨论元数据的意义及其在可执行文件中的存储,读者需要对传统PE格式有所了解,因为本章会跳过这些基础
内容而直接进入.NET的扩展部分。

如果用普通的PE文件结构工具查看.NET可执行文件,不会发现它有什么特别之处,因为所有的头结构、节名称都和Win32下的相同。但细心的读者会发
现,.NET
PE文件的第15项数据目录COM大多数情况下的RVA为0x2008,大小为0x48,而该地址正指向了.text节。没错,.NET对PE的扩展主要
体现在了.text节的构造上:在Win32下,.text节保存的是汇编;而.NET中保存的是MSIL、元数据、以及各种特殊的.NET结构。本节首
先带领读者认识大变样后的.text节,随后介绍.NET PE中最重要的结构:CLR头。

图3.1为一般情况下.NET PE文件的.text节结构,通常包含八部分内容,比较重要的有以下几项:Common Language
Runtime头(CLR头),这是整个.NET可执行文件综合信息的存放处,其作用类似于Win32下的PE头;MSIL代码和可选的异常处理表,这是
加密软件重点关注的数据,也是解密时最希望得到的数据;强名称及其hash数据,当一个文件被签署了强名称后,相应的强名称数据保存于此;最后则是元数
据。

图3.1  .NET PE文件中的.text节结构

前面叙述了.text节中存储了哪些内容,接着将介绍它们具体的结构及含义。先介绍最重要的结构CLR头,它的定义在SDK安装目录里include目录下的CorHdr.h文件中,结构名叫IMAGE_COR20_HEADER,精简后的C++代码如下:
// COM+ 2.0 header structure.
typedef struct IMAGE_COR20_HEADER
{
DWORD                   cb;             
WORD                    MajorRuntimeVersion;
WORD                    MinorRuntimeVersion;
IMAGE_DATA_DIRECTORY    MetaData;       
DWORD                   Flags;          
union {
DWORD               EntryPointToken;
DWORD               EntryPointRVA;
};
IMAGE_DATA_DIRECTORY    Resources;
IMAGE_DATA_DIRECTORY    StrongNameSignature;
IMAGE_DATA_DIRECTORY    CodeManagerTable;
IMAGE_DATA_DIRECTORY    VTableFixups;
IMAGE_DATA_DIRECTORY    ExportAddressTableJumps;
IMAGE_DATA_DIRECTORY    ManagedNativeHeader;   
} IMAGE_COR20_HEADER, *PIMAGE_COR20_HEADER;

表3-1详细解释了该结构中各项的意义。整个结构的大小为0x48,正是倒数第2项数据目录中指出的大小。

表3-1  CLR头的结构与说明

偏移

大小

名    称

说    明

0

4

Cb

CLR头的大小,以byte为单位

4

2

MajorRuntimeVersion

能运行该程序的最小.NET版本的主版本号

6

2

MinorRuntimeVersion

能运行该程序的.NET版本的副版本号

8

8

MetaData

元数据的RVA和Size

16

4

Flags

属性字段,可以在IL中以.corflags进行显式设置,也可以在编译时用/FLAGS选项进行设置,其中命令行设置的优先级较高

20

4

EntryPointToken
/EntryPointRVA

入口方法的元数据ID(也就是token),在EXE文件必须有,而DLL文件中此项可以为0(.NET 2.0中,此项还可以是本地入口代码的RVA值)

24

8

Resources

托管资源的RVA和Size

32

8

StrongNameSignature

强名称数据的RVA和Size(强名称的意义在后面介绍)

40

8

CodeManagerTable

CodeManagerTable的RVA与Size,此项暂未使用,为0

48

8

VTableFixups

v-table项的RVA和Size,主要供使用v-table的C++语言进行重定位

56

8

ExportAddressTableJumps

用于C++的输出跳转地址表的RVA和Size,大多数情况为0

64

8

ManagedNativeHeader

仅在由ngen生成本地模块中该项不为0,其余情况均为0

其中Flags项定义了该exe文件的最基本性质,包含以下设置:
COMIMAGE_FLAGS_ILONLY           =0x00000001,//此程序由纯IL代码组成
COMIMAGE_FLAGS_32BITREQUIRED    =0x00000002,//此程序仅在32位系统上运行
COMIMAGE_FLAGS_IL_LIBRARY       =0x00000004,//此程序仅作为IL代码库(很少用)
COMIMAGE_FLAGS_STRONGNAMESIGNED =0x00000008,//此程序有强名称(重要)
COMIMAGE_FLAGS_NATIVE_ENTRYPOINT    =0x00000008,//此程序入口方法为非托管
COMIMAGE_FLAGS_TRACKDEBUGDATA   =0x00010000,//loader和JIT需要追踪调试信息

如果读者是初次接触上述内容,建议使用UltraEdit等编辑工具打开某个.NET
PE文件,在十六进制编码的基础上对照表中各项进行学习。通常在进行软件分析时,该头结构中的大多数信息是不变的,若有特殊需要,可利用专门的文件结构查
看工具进行浏览,如传统的Win32文件结构查看工具如PEiD、PEInfo、LordPE等,以及专为.NET编写的查看工具,如
Researcher .NET、Spices.NET的元数据结构浏览组件、CFF
Explorer等,有兴趣的读者还可以自己编写类似工具。图3.2便是用LordPE载入mscorlib.dll后显示的CLR头的数
据,mscorlib.dll是.NET平台的基础文件之一,位于(系统盘)/WINDOWS/Microsoft.NET/
Framework/v2.0.50727目录下。


图3.2  LordPE显示mscorlib.dll的CLR头结构

CLR头中最重要的项是MetaData,它是IMAGE_DATA_DIRECTORY格式,指出了该文件中元数据存放的位置和大小。而这,就是3.2节将详细阐述的内容。

抱歉!评论已关闭.