.net程序如何启动?

.NET Framework在Windows平台顶部运行,这意味着.NET Framework必须使用 windows可以理解的技术来构建。首先,所有托管模块和程序集文件都必须使用windows PE文件格式,而且要么是一个windows EXE文件,要么是一个DLL文件。

.net程序建立在CLR之上,因此.net程序的运行需要先加载正确的CLR环境。这样我们把问题的关注点转变为:

1、如何正确地加载CLR环境?

2、如何进入.net程序的Main函数?

为了更好地理解这个过程,我使用dumpbin.exe工具来解析PE文件格式并且转储出PE文件的内容。dumpbin.exe在visul studio中的Visul studio Tool的工具命令提示。我使用下面命令转储PE文件内容,

D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC>dumpbin -all assembly>e:\dump.txt

转储部分内容如下:

OPTIONAL HEADER VALUES

10B magic # (PE32)

11.00 linker version

A00 size of code

800 size of initialized data

0 size of uninitialized data

29AE entry point (004029AE)

2000 base of code

4000 base of data

400000 image base (00400000 to 00407FFF)

2000 section alignment

200 file alignment

4.00 operating system version

Entry point域表示PE文件的入口地址 值为Ox004029AE

要找出位置Ox004029AE所对应的代码,需要查看PE映像的.text段,部分内容如下:

00402980: 00 00 00 00 00 00 00 00 90 29 00 00 00 00 00 00  .........)......

00402990: 00 00 5F 43 6F 72 45 78 65 4D 61 69 6E 00 6D 73  .._CorExeMain.ms

004029A0: 63 6F 72 65 65 2E 64 6C 6C 00 00 00 00 00 FF 25  coree.dll.....?%

004029B0: 00 20 40 00

粗体字节对应于Entry Point,这些字节对应的机器指令为JMP 402000。要找到Ox402000指向的内容,我们可以查看PE文件的导入段,可以发现如下内容:

Section contains the following imports:

mscoree.dll

402000 Import Address Table

402988 Import Name Table

0 time date stamp

0 Index of first forwarder reference

0 _CorExeMain

Ox402000指向的是mscoree.dll,这个库包含一个导出函数_CorExeMain。_CorExeMain是mscoree.dll的一部分,这个函数也是加载.net程序集时第一个被调用的函数。mscoree.dll的主要作用是启动CLR。mscoree.dll在启动CLR时将执行一系列工作:

1、通过查看PE文件中的元数据,找出.NET程序集是由哪个版本的CLR构建的。

2、找出操作系统中正确版本CLR的路径

3、加载并初始化CLR

在CLR被初始化之后,在PE映像的CLR头中找到程序集的入口点(Main()),然后JIT开始编译并执行入口点。

.NET程序集加载算法如下:

1、用户执行一个.NET程序集

2、windows加载器查看AddressOfEntryPoint域,并找到PE映像文件的.text段。

3、位于AddressOfEntryPoint位置上的字节只是一个JMP指令,这个指令跳转到mscoree.dll中的一个导入函数。

4、将执行控制转移到mscoree.dll中的函数_CorExeMain中,这个函数将启动CLR并且把执行控制转移到程序集的入口点。

.NET程序如何启动?的更多相关文章

  1. 【原】iOS学习之应用程序的启动原理

    最近看视频了解了一下应用程序的启动原理,这里就做一个博客和大家分享一下,相互讨论,如果有什么补充或不同的意见可以提出来! 1.程序入口 众所周知,一个应用程序的入口一般是一个 main 函数,iOS也 ...

  2. Ubuntu 设置程序开机启动(以指定用户身份)

    一.方法 在/etc/rc.local写程序的启动命令(系统执行内核过程中会启动init进程,该进程把当前runlevel所对应的的所有service 都启动后,才会执行rc.local里的命令),程 ...

  3. 解决Pyqt打包后运行报错:应用程序无法启动 因为程序的并行配置不正确

    做了一个生成二维码的小程序:http://www.cnblogs.com/dcb3688/p/4241048.html 直接运行脚本没问题,用pyinstaller打包后再运行就直接报错了: 应用程序 ...

  4. C#禁止程序重复启动

    采用线程互斥锁Mutex,在winform程序的主入口点中加入如下代码,将程序改为单实例运行. static class Program { /// <summary> /// 应用程序的 ...

  5. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    [Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...

  6. 如何解决"应用程序无法启动,因为应用程序的并行配置不正确"问题

    应用程序事件日志中: "C:\windows\system32\test.exe"的激活上下文生成失败.找不到从属程序集 Microsoft.VC80.MFC,processorA ...

  7. 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

    大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...

  8. iOS的常见文件及程序的启动原理

    一. iOS中常见文件 (一). Xcode6之前 创建项目,默认可以看见一个存放框架的文件夹 info文件以工程文件名开头,如:第一个项目-Info.plist 项目中默认有一个PCH文件 (二). ...

  9. iOS程序的启动过程-UIWindow

    UIApplicationMain main函数中执行了一个UIApplicationMain这个函数 int UIApplicationMain(int argc, char *argv[], NS ...

  10. 提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll

    新版本SQLITE,如果下载Precompiled Binaries版会出现提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll. 下载Prec ...

随机推荐

  1. 周立功CAN-II引脚图

    注意:如果需要两个CAN通道通信,直接用杜邦线将L连L,H连H,地连地就行(3.6引脚已做短接处理),不需要反接

  2. php数组元素去空,测试奇数偶数

    <?php//返回奇数 function test_odd($var) { return($var & 1); } $a1=array("a","b&quo ...

  3. RAID独立冗余磁盘阵列

    独立冗余磁盘阵列(Redundant Array OF Independent Disks,RAID)开始于20世纪80年代美国加州大学伯克利分校的一个研究项目,当时RAID被称为廉价冗余磁盘阵列(R ...

  4. JavaScript字符串转换为变量名

    1.将一个字符串转换为变量名 [javascript] view plain copy print? function string_to_name(string){ let _name = 'var ...

  5. java8 函数接口 Predicate例子

    import java.util.HashSet; import java.util.Collection; import java.util.function.Predicate; public c ...

  6. 自己用java实现飞鸽传书 2 - 实现文件传输

    第二步:实现文件传递. 上一步只是从服务端传递了一个字符串到客户端,这次需要对代码进行调整,实现从服务端获取文件,在客户端将文件存入目标地址. 调整后的代码: 服务端: import java.io. ...

  7. js进阶---12-12、jquery事件委托怎么使用

    js进阶---12-12.jquery事件委托怎么使用 一.总结 一句话总结:通过on方法(事件委托),给要绑定事件的元素的祖先绑定事件,从而达到效果. 1.事件委托是什么? 通过事件冒泡,让子元素绑 ...

  8. [JavaScript]对象创建方法

    1.使用Object或对象字面量创建对象 (1)使用Object创建对象 var cat= new Object(); cat.name = "Tom"; cat.color= & ...

  9. 客户端类中中记录异常的方法: 使用Log4net

    1.首先引用Log4Net 的命名空间 using log4net; 2.在使用的类中生命静态变量 log public class FileService    {        static re ...

  10. 【总结】对异步处理的http接口进行性能测试

    以前对接口做性能测试,接口都是同步处理的,请求之后等待响应结果就知道处理结果了,这样只要看这个接口是否异常,如果无异常无报错记录这个接口的响应时间.TPS等性能指标进行分析就可以了,最近在工作中遇到了 ...