`
javatoyou
  • 浏览: 1013083 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

.net中PE文件的结构

 
阅读更多
一.摘要
在我们使用了任何支持CLR的语言来创建了源代码文件之 后,无论使用什么编译器,编译出的文件都是一个托管模块(managed module),这个托管模块可以在CLR上运行。所以,我们把这种文件称为托管可执行文件(Managed Executable File)。关于通用PE文件的格式已经在笔记三中间记录了,这里只记录一些托管文件自身比较有特色的部分。

二.托管执行文件的重要组成部分
1.CLR Header
我们知道,在PE头中,包含一个数据目录表(Data Directory Table),这个表的第15项就是一个包含了CLR头的RVA和大小,可以通过它找到CLR Header。简单记录一下CLR Header中的几个主要的字段:
(1)Flags
这是一个二进制的标记,其可选值包括:
A.COMIMAGE_FLAGS_ILONLY (0x00000001) 文件中只包含纯的IL代码,未嵌入任何Native Code(除了Dos Stub,这个stub会被所有能够识别CLR的系统忽略掉)。
B.COMIMAGE_FLAGS_32BITREQUIRED (0x00000002) 文件只能被加载到32位的进程空间中。
C.COMIMAGE_FLAGS_STRONGNAMESIGNED (0x00000008) 文件受到强名称签名的保护
(2)
EntryPointToken
这是一个指明了此PE文件入口点的元数据标志符(MeteData Identifier),它 指向一个方法定义或者文件引用,而指向文件引用的唯一可能是:一个多模块程序集的入口点不在其主模块中,那么主模块里的入口点标记指向包含入口点的模块文 件。入口点只能出现在可执行文件里,如果你的代码里不包含入口点,IL汇编器会拒绝为你编译EXE文件。但对于非可执行文件,却分为两种情况:如果程序是 一个纯的托管程序,则不需要入口点;如果程序中即包含IL代码又包含机器码(由MC++编译器和链接器生成),则必须把DLLMain()作为入口点函 数,它要对程序集里的非托管代码进行一些必要的初始化操作。
(3)
VTableFixups
要理解这个字段,首先要理解v-table的概念。这是我摘了一个老外的描述,应该很精确,“
Certain languages, which choose not to follow the common type system runtime model, may have virtual functions which need to be represented in a v-table. These v-tables are laid out by the compiler, not by the runtime. Finding the correct v-table slot and calling indirectly through the value held in that slot is also done by the compiler”。v-table是为虚方法调用服务的,而VTableFixups包含了一组v-table的地址和大小。
根据笔者当前的认识,v-table只有在此托管文件
需要和非托管环境交互的时候才有用(比如这个托管代码要被一个非托管环境调用),在纯的托管环境下可能是没用的。当然,大家都知道C#作为典型的OO语言,也有虚函数的概念,但它的虚函数实现机制和C++中的v-table的实现方式有什么不同,我暂时还不清楚。

2.文本段(.Text section)
整个CLR Header是放置在一个文本段中的。这是一个只读的段,包含了元数据表、IL代码、引入表等,整个结构如下图所示:

这个段里的各个部分并非同时生成的,上图用带序号的方框来提示这一点,序号低的先生成。

3.资源
在托管文件中可以嵌入两种不同类型的资源:非托管的平台相关的资源,或者托管资源。这两种资源存储在PE文件的不同section里(其中托管资源已经在上面的文本段内出现过了,不是吗?),其中非托管资源被放在一个单独的.rsrc段里,而托管资源放在文本段里。
需要注意的是,IL汇编器在每个托管可执行文件中只能嵌入一个资源文件(.RES)。IL反汇编器会定位到这个section,然后把section中的所有内容作为一个.RES文件释放出来。

三.元数据的结构

使用过.net的Reflection功能的人对元数据可能多少都有点概念,它是对整个托管模块的逻辑结构的完整描述,包含了所有在模块中声明和引用的元 素。从结构上来说,所有元数据类似于一个关系数据库,里面的数据体现为一组交叉引用的表(而不是树或者什么其他数据结构),并且任何数据都只有一份(其他 用到这个数据的位置都将包含一个指向此数据的引用)。从用途上来说,这些表分为三类:定义表(definition table)、引用表(reference table)和清单表(manifest table)。
整个元数据是一个二进制的数据块,你只能通过工具来查看已生成程序集的元数据信息,如ildasm.exe(你可以在“视图”菜单里找到关于元数据信息显示的命令)。
(1)元数据结构概览
下面贴出来的显示信息,是我用ildasm.exe统计了自己写的一个很小的Demo程序中的元数据信息,先放在这里,可以和后面提到的内容相互参考:

CLRmeta-datasize:1260
---------这些是元数据中的tablestream-----------------
Module-
1(10bytes)
TypeDef-
3(42bytes)0interfaces,0explicitlayout
TypeRef-
8(48bytes)
MethodDef-
8(112bytes)0abstract,0native,4bodies
FieldDef-
1(6bytes)0constant
MemberRef-
5(30bytes)
ParamDef-
9(54bytes)
CustomAttribute-
4(24bytes)
StandAloneSig-
1(2bytes)
Assembly-
1(22bytes)
AssemblyRef-
1(20bytes)
-----------tablestreamend--------------------------

-----------这些是元数据中的Heapstream-------------------
Strings-
385bytes
Blobs-
108bytes//
UserStrings-
200bytes
Guids-
16bytes
-----------heapstreamend---------------------------

Uncategorized-
181bytes

可以看到,在元数据中除了上面我们提到的那些表以外,还有一些用于记录UserString,Guid的堆数据,后面会提到。

(2)元数据中的父子关系
元数据中包含很多“父子关系”,如“类--方法”、“方法--参数”等等。如果你想找到和某个父数据对应的所有子数据,遍历这个子数据所在的表可是个糟糕 的选择。事实上,对于这种一对多关系,汇编器在构造元数据表的时候,并不仅仅使用数据间的引用关系,而且使用了数据的排列顺序来帮助定位。每个父数据都只 含有一个指向其第一个子数据的引用,其子数据的结尾靠下一个父数据的起始引用来定位。这就要求子数据要依照他们的父数据来排序(符合这种条件的元数据被称 为“优化的”、“压缩的”元数据,而IL汇编器一般都是生成这种元数据)。下图是书中给出的class-method父子关系的元数据表示意图:

(3)元数据结构
前面曾经提到过,元数据其实就是一个二进制的数据块,所以元数据的内部,就是一个个的named stream。这些stream又分为两种类型,除了前面提到过的Table,还有一类是以Heap的形式体现(见上文代码段中的注释)。下图是书中给出 的一个完整的元数据结构图:

上面以#开头的就是元数据中可能出现的6个命名流,他们的用途分别是
#Strings:用来存储元数据项的名字,如类名、方法名等 //Heap Stream
#Blob: 用来存储一些内部的对象实例,如默认值什么的 //Heap Stream
#US: 用户定义的字符串常量 //Heap Stream
#GUID: 包含各种全局统一标志符 //Heap Stream
#~: “优化的”、“压缩的”元数据,里面的元数据表以优化方式存储(我们在父子关系中刚刚提到过的) //Table Stream
#-: 非优化的元数据(和#~不能共存) //Table Stream
其中(#~或#-)、#GUID、#Strings是必不可少的。
另外,元数据既然被存储在很多表里,那么CLR是如何定位一个元数据项的呢(怎么样定位到某个表的某一行)?这里,它使用了一种叫做Token的机制, 每个token占4个字节,其中高位字节表示表序号,剩余三个字节表示表内的行序号。具体这些序号被称为RID(record index),其中行序号从1开始,表序号从0开始。

分享到:
评论

相关推荐

    PEDump Delphi版的PE文件结构分析工具

    PEDump Delphi版的PE文件结构分析工具! 值得下载看看!资源免费,大家分享!! 更多免费资源 http://ynsky.download.csdn.net/

    PE文件解析类(轻松制作自己的PE文件解析器)

    该类对想学PE文件结构的朋友可算一份可贵的资料,代码均很易懂,考虑较全面,具有一定的通用性。 同时该类也可以让想创建自己的PE文件解析软件的朋可以轻松在此基础上实现。 最后,错误在所难免,如果大家发现有错误...

    .net C# 学习过程中收藏的一些比较有用的和感兴趣的链接

    http://www.360doc.com/userhome.aspx?userid=19107491&cid=3 jQuery基本选择器及用法 前端模块化...再探.NET的PE文件结构(安全篇) http://www.cnblogs.com/dwlsxj/p/4052871.html 浅析MSIL中间语言——PE文件结构篇

    asp.net中资源文件的使用

    .Net是一个丰富的平台,在它的结构中,程序集Assembly是自我描述的安装单元,它可以只包括一个PE(可移植可执行)格式的Dll或exe文件,也可以由多个文件组成,例如资源、Dll和exe等

    .net 反编译软件

    DisSharp 3.1.1 ,能够反编译.net软件 ...DIS#有它自己的元数据结构,扩大与所有反编译的信息,如局部变量的名称,必要的PE元数据结构。您可以保存在项目文件(扩展名.DIS)DIS#元数据和保存所有更改

    AsmResolver:用于编辑具有完全.NET元数据支持的PE文件的库

    AsmResolver是一个PE检查库,允许.NET程序员读取,修改和写入可执行文件。 这包括.NET以及本机本地映像。 该库公开了PE的高级表示,同时仍允许用户访问低级结构。 AsmResolver是根据MIT许可发布的。 二进制文件 从...

    CFFExplore 8.0

    CFFExplore 8.0 一款优秀的PE工具,其增减区块功能非常强大。查看.net的PE结构也很方便。 已经完全汉化了 Explorer Suite 的所有文件,包括主文件(pe)、自述文件、脚本、扩展以及SDK,应该说是完全池底的汉化

    MFCLibrary1Dll.dll

    PE总结(3)---PE文件结构DOS文件头 文章使用到的dll文件 http://blog.csdn.net/obuyiseng/article/details/50014429

    Windows 资源查看器 MiTeC EXE Explorer 2.7.1.0 + x64 绿色中文.zip

    它与 PE32(便携式可执行文件),PE32 +(64位),NE(Windows 3.x 新建可执行文件)和 VxD(Windows 9x 虚拟设备驱动程序)文件类型兼容。 .NET 可执行文件也受支持。 Windows 资源查看器 MiTeC EXE Explorer ...

    Windows环境下32位汇编语言程序设计.rar

    在最后的几章中,本书将从应用的角度再补充介绍一些常用的网络编程,注册表和PE文件操作方面的内容,这就是应用篇: 14.1 异常处理的用途 14.2 使用筛选器处理异常(1) 14.2 使用筛选器处理异常(2) 14.3 使用SEH...

    C#微软培训资料

    17.1 .Net 框架结构提供的 I/O 方式 .215 17.2 文件存储管理 .217 17.3 读 写 文 件 .222 17.4 异步文件操作 .227 17.5 小 结 .234 第十八章 高 级 话 题 .235 18.1 注册表编程 .235 18.2 在 C #代码...

    c#学习笔记.txt

    在结构中初始化实例字段是错误的。在类中,必须初始化实例对象. 使用 new 运算符创建结构对象时,将创建该结构对象,并且调用适当的构造函数。与类不同的是,结构的实例化可以不使用 new 运算符。如果不使用 new,...

    Windows环境下32位汇编语言程序设计(chm 罗云彬)

    17.1 PE文件的结构(3) 17.1 PE文件的结构(4) 17.1 PE文件的结构(5) 17.1 PE文件的结构(6) 17.1 PE文件的结构(7) 17.1 PE文件的结构(8) 17.2 导 入 表(1) 17.2 导 入 表(2) 17.2 导 入 表(3) 17.3 导 出 表...

    PEDump.zip_ JIURL PEDUMP_ dump_R-Tree_coff_pedump

    PEDUMP是一个命令行程序,不带任何选项对我刚刚描述的文件类型去运行,将会有一个包括许多有用数据结构的缺省导出。几个可以有额外输出的选项列在如下: ============================...

    Sojobo:二进制分析框架

    它是完全在.NET中开发的,因此您无需安装或编译任何其他外部库(该项目是自包含的)。 使用Sojobo,您可以: 模拟(32位)PE二进制文件 检查模拟过程的内存 读取过程状态 显示已执行代码的反汇编 以托管语言(C#...

    WINRAR5.0正式注册版

    RAR 5.0 压缩文件可以使用 256位的 BLAKE2sp 哈希( https://blake2.net ) 代替 32 位的 CRC32 作为文件校验和。可以在压缩对话框的“选项”页中启用“使用 BLAKE2 文 件校验和”或在命令行中指定 -htb 开关来使用...

    部分经典C程序源代码

    PE文件格式分析程序VC++ Pi3web-DoS pjam2 PortReady1.6-Code proDETECT 0.1 BETA qqport shareall10 SMB Auditing Tool v1.0.4 THCsql THCunREAL T-Mouse v1.0 基于远程线程结构程序vc++ T-Mouse v2.0 基于三线程...

    Windows编程循序渐进(清晰完整版)1

    因为本人帐户只能上传15M的文件,电子书文件有130M左右大小,只能分割8个分卷分别...第18章,可执行文件格式:介绍PE文件格式及其基本应用。 第19章,模块注入与函数挂接技术:介绍模块注入及函数挂接技术及其防御。

Global site tag (gtag.js) - Google Analytics