.NET对PE结构的扩展

.NET对PE结构的扩展

    可执行文件的格式是反映一个系统程序运行机制的重要方面,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节将详细阐述的内容。
 
本文节选自电子工业出版社2008年11月出版的 《微软.NET程序的加密与解密》。
到当当网购买
到卓越网购买
到china-pub购买
 
浏览更多精彩文章>>
订阅软件安全电子期刊>>
 
 
 

你可能感兴趣的:(.net,加密,解密,休闲,pe)