托管模块结构及运行机制

托管文件模块组成

PE表头: 文件类型:(GUI,CUI,DLL),时间标记(文件创建时间)

.text部分:包含JMP _CorExeMain指令

.idata部分,保护MSCorEE.dll引用

CLR表头: 包含托管模块信息:CLR版本号,Main方法的MethodDef元数据标记,托管模块的元数据,资源,强命名,标记信息的位置和尺寸

元数据: 包括元数据表,有两种,一种描述源代码中定义的类型和成员,一种描述源代码中应用的类型和成员

中间语言:编译器编译代码时产生的指令。

清单(manifest)


元数据构成:

元数据是一块二进制数据,包含一些表

定义表:

 1. ModuleDef: 包括托管模块的条目,条目主要包括模块的文件名,扩展名等

 2. TypeDef:托管代码定义的每一个类型都在TypeDef中一个对应条目,包括类型的名称,基类型,类似public访问标记,以及一些指针(指针指向MethodDef表中该类型的方法,FieldDef中该类型的字段以及PropertyDef和EventDef表中属于该类型的成员)

 3. MethodDef:托管模块中定义的每个方法在MethodDef中都对应一个条目,包括方法名,访问标记,方法签名,已经该方法的IL代码在模块中的偏移量,还包括一个指向ParamDef的指针

 4. FieldDef:

 5. ParamDef:

 6. PropertyDef:

 7. EventDef:

引用表:

 1. AssemblyRef:托管模块中每一个引用在AssemblyRef中都有一个对应条目,记录程序集名称,版本,语言文化以及一个公有密钥标记

 2. ModuleRef:用来记录实现在同一程序集中的其它不同模块的一些类型

 3. TypeRef:

 4. MemberRef:

清单表:

 1. AssemblyDef:

 2. FileDef:

 3. ManifestResourceDef:

 4. ExportedTypesDef:

程序集执行:

编译期:

1. 编译器编译程序时,再PE文件的.text部分嵌入指令 JMP _CorExeMain

2. _CorExeMain函数存在MSCorEE.dll中,所以MSCorEE.dll将在PE文件的.idata部分被引用

执行期:

1. Windows加载该PE文集

2. 发现其.idata部分存在MSCorEE.dll引用,于是加载MSCorEE.dll,获取_CorExeMain函数地址,用此地址修正JMP指令。

3. 进程开始执行修正后的JMP指令, 该指令跳转倒MSCorEE.dll中的_CorExeMain函数,此函数初始化CLR, 然后此函数查看CLR表头的Main函数位置。

4. 找到Main函数后,PE文件的IL被JIT编译成CPU指令。

5. CLR跳转到编译后的指令,程序开始运行。


托管方法的调用:

1. 方法执行之前,CLR会检查方法中引用到的所有类型。

2. CLR为方法分配一个内部数据结构,用于管理所有引用类型。该方法引用到的所有类都会被分配,该类中的每个方法都有一个对应的条目,每个条目都将被初始化为一个没有记录的函数(JITCompiler函数)

3. 当调用到该条目的时候,JITCompiler被调用,其搜索元数据,找到IL位置其将验证IL并编译为CPU指令(即所谓的及时编译JIT)

4. JITCompiler用CPU指令的位置替换该调用方法的地址

5. JITCompiler跳转到该内存代码上开始执行

6.如果第二次调用将直接使用该方法的地址 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值