.Net 程序集加载

.Net 程序在执行的时候要预先加载CLR ,Windows 如何知道并加载CLR?

新建控制台应用程序,编译好

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }

用dumpbin 导出PE格式文件(包括PE 镜像文件)

这里写图片描述

分析导出的文件

OPTIONAL HEADER VALUES
           ......
            27FE entry point (004027FE)
           ......

可以看到entry point的地址为0x004027FE,查看.text段,可以从RAM DATA 段发现一些信息

  004027E0: 00 00 5F 43 6F 72 45 78 65 4D 61 69 6E 00 6D 73  .._CorExeMain.ms
  004027F0: 63 6F 72 65 65 2E 64 6C 6C 00 00 00 00 00 FF 25  coree.dll.....?%
  00402800: 00 20 40 00                                      . @.

最后一行实际上表示地址:0x40200 指向PE镜像文件的如下部分,可以看到它指向的是mscoree.dll (Micorsoft 对象运行时执行引擎,Micorsoft Object Runtime Execution Engine),此dll主要作用就是启动CLR。

  Section contains the following imports:

    mscoree.dll
                402000 Import Address Table
                403038 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                    0 _CorExeMain

可以看出_CorExeMain (.NET 库对应的是_CorDllMain)是加载程序集时候第一个调用的函数。接着根据PE中元数据,找到正确版本CLR加载并初始化。CLR初始化好后,在PE镜像文件的头中就可以找到应用程序的入口点(Main),然后JIT 开始编译并执行入口点。

终结

  1. PE文件的头部包含了一个域叫做AddressOfEntryPoint,表示PE文件的入口点位置。在.Net 程序中这个点指向.text段的一小段存根代码。当编译器生产.Net程序的时候还会在PE文件中增加一个数据目录项(data directory)包含了CLR头的位置和大小。
  2. Windows 加载器查看Entry Point 地址,找到.text 段
  3. 根据地址上的指令 跳转到mscoree.dll 中的导入函数
  4. 执行mscoree.dll中的_CorExeMain,启动CLR,并将执行控制转移到程序入口。

应用程序域

为了节省构造和管理进程的开销,.Net 使用应用程序域这一概念。
可以用命令查看

0:004> .loadby sos clr
0:004> !dumpdomain

系统应用程序域

System Domain:      5ff6f308
LowFrequencyHeap:   5ff6f62c
HighFrequencyHeap:  5ff6f678
StubHeap:           5ff6f6c4
Stage:              OPEN
Name:               None

作用:
1. 创建共享应用程序域和默认应用程序域
2. 将mscorlib.dll加载到应用程序域中
3. 记录其他应该用程序域(如加载/卸载)
4. 记录字符串常量池
5. 初始化特定类型异常(如:内存耗尽异常,栈溢出异常以及执行引擎异常)

共享应用程序域

Shared Domain:      5ff6efb8
LowFrequencyHeap:   5ff6f62c
HighFrequencyHeap:  5ff6f678
StubHeap:           5ff6f6c4
Stage:              OPEN
Name:               None
Assembly:           012378d0 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        012239f8
  Module Name
5bb01000    C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

作用

  1. 加载mscorlib.dll
  2. 加载基本类型(String , enum , Value , Array)
  3. 非用户代码加载到共享应用程序域

默认应用程序域

Domain 1:           0120bfe8
LowFrequencyHeap:   0120c454
HighFrequencyHeap:  0120c4a0
StubHeap:           0120c4ec
Stage:              OPEN
SecurityDescriptor: 0120d278
Name:               CRLLoad.exe
Assembly:           012378d0 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        012239f8
SecurityDescriptor: 01235bc0
  Module Name
5bb01000    C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           0123d238 [D:\My\CRLLoad\CRLLoad\bin\Debug\CRLLoad.exe]
ClassLoader:        012237f0
SecurityDescriptor: 0123d1b0
  Module Name
00f13fbc    D:\My\CRLLoad\CRLLoad\bin\Debug\CRLLoad.exe

作用

  1. 隔离自己的应用程序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值