可以看到A.EXE只对一个DLL有依赖关系,也就是MSCOREE.DLL。并且A.EXE只用到了MSCOREE.DLL中的一个函数,即_CorExeMain。而MSCOREE.DLL本身却输出了137个函数之多。从这个函数的名字大家可以猜出,这个函数是EXE的一个入口点。为了证实这一点,我们可以用DumpBin看看内容:
Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
![]()
Copyright (C) Microsoft Corporation. All rights reserved.
![]()
![]()
![]()
Dump of file a.exe
![]()
PE signature found
![]()
File Type: EXECUTABLE IMAGE
![]()
FILE HEADER VALUES
14C machine (x86)
3 number of sections
46C83E12 time date stamp Sun Aug 19 20:56:50 2007
![]()
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
10E characteristics
Executable
Line numbers stripped
Symbols stripped
![]()
32 bit word machine
![]()
OPTIONAL HEADER VALUES
10B magic # (PE32)
8.00 linker version
400 size of code
600 size of initialized data
0 size of uninitialized data
23DE entry point (004023DE)
![]()
2000 base of code
4000 base of data
400000 image base (00400000 to 00407FFF)
注意这个EXE的入口点的RVA是23DE。
再使用Windbg加载A.EXE,使用lmm (list module match)命令查看A.EXE加载的首地址:
0:000> lmm a
start end module name
![]()
00de0000 00de8000 a (deferred)
可以看到是0x00de0000,那么再加上23DE这个RVA值,就是程序的入口点。用u命令反汇编看一下:
对于一个托管的DLL而言,情况也非常类似,入口点则是_CorDllMain:

可以看到这就是一个简单的JUMP指令,跳转到0x00de2000所指向的位置,那么这个位置是什么函数呢?我们可以通过dds命令查看:0:000> u de23de
a+0x23de:
00de23de ff250020de00 jmp dword ptr [a+0x2000 (00de2000)]
到此事实就非常清楚了,任何托管的EXE程序中的入口点都是一条JMP指令直接跳转到MSCOREE.DLL的_CorExeMain函数执行。而这个_CorExeMain的地址(也就是00de2000所保存的0x5b034e50)则是由OS Loader填入,因为这个位置正是Import Table的位置。0:000> dds 2000+de0000
00de2000 5b034e50 mscoree!_CorExeMain
对于一个托管的DLL而言,情况也非常类似,入口点则是_CorDllMain:

可以想象的到,假如你的系统中没有安装.NET Framework,那么执行托管程序也会立刻同样的对话框。显然根据这个信息用户本身很难推断出发生了什么问题。一个可行的方案是Windows总是自带一个MSCOREE.DLL,这个MSCOREE.DLL如果发现没有.NET Framework则会给出比较清晰的报错信息。不过由于从Windows 2003之后(包括Vista)的所有Windows版本都会自带.Net Framework,那么这个问题基本上不会出现了。
MSCOREE负责选择.NET Framework版本
MSCOREE.DLL有个非常特殊的地方,也就是它位于C:\Windows\System32目录下,换句话说,不管你的系统上面安装了多少个不同的.NET Framework版本,这个DLL都最多只可能有2份(32位/64位各一份),而在C:\Windows\Microsoft.NET\Framework 或者C:\Windows\Microsoft.NET\Framework64下面,则会有多份不同的.NET Framework同时存在。那么,这个MSCOREE.DLL又是如何对应不同版本的.NET Framework呢?答案很简单:MSCOREE.DLL通过注册表信息确定系统上面安装的.NET Framework版本号码,然后根据应用程序本身的所要求的版本来选择一个合适的.NET Framework版本来执行。真正的工作则是交给实际的某个版本的 .NET的DLL执行,在通常情况下,这个DLL是Work Station版本的CLR,名为MSCORWKS.DLL,而服务器版本的CLR则对应MSCORSVR.DLL