.NET中的幕后英雄:MSCOREE.DLL

电网加密芯片全解析:分类与功能​ 在电网数字化转型的浪潮中,数据安全和设备的身份认证变得愈发重要。加密芯片作为保障电网信息安全的核心部件,凭借独特的技术特性,在不同应用场景下发挥着关键作用,有力推动着智能电网的安全稳定发展。接下来,我们将对电网中常见的加密芯片展开分类介绍,并探讨其对应的功能。​。 阅读详情

现在做.NET Framework的开发的朋友应该是越来越多了,但是可能并非人人都对MSCOREE.DLL非常了解。而事实上,毫不夸张地说,MSCOREE.DLL是.NET Framework中最为核心的DLL之一,没有这个DLL,托管程序根本无法开始执行起来,但是由于这个DLL藏在System32目录下,根本无人问津,可以说是有点委屈了这位.NET Framework中的幕后英雄。本文主要讨论MSCOREE.DLL的几大作用,以及MSCOREE.DLL的兼容性问题。

MSCOREE是托管程序的入口点
让我们来做一个小实验:

首先写一个最最简单的Hello World程序,用csc编译(当然你用VS我也没意见):

public class Program
{

       public static void Main(string[] args)

       {

              System.Console.WriteLine("Hello World!");

       }
}
 
然后,在命令行中键入:
 

C:/Windows/System32> ren mscoree.dll mscoree_.dll

 
请注意在Vista系统上需提升权限,否则重命名失败。
之后,运行刚才编译出来的EXE程序。Windows直接报错:

然后,再把mscoree.dll名字改回去,再次运行A.EXE,这次正确打印出了Hello World。

那么为什么一旦没有MSCOREE.DLL,就算是最简单的Hello World也无法运行呢?

有在Windows用C/C++编程的朋友们应该熟悉上面那个出错对话框的意思,这个对话框通常在程序找不到所需的DLL的时候出现。我们可以通过运行Visual Studio中自带的Depends.exe来查看A.EXE的对于DLL的依赖关系:

可以看到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命令反汇编看一下:
 
0:000> u de23de
a+0x23de:

00de23de ff250020de00    jmp     dword ptr [a+0x2000 (00de2000)]

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

程序可以通过MSCOREE调用CLR的提供的功能或者定制CLR

MSCOREE.DLL导出了大量的函数,那么这些函数是否公开并且可以调用呢?答案是肯定的。几乎所有这些函数在MSDN中都可以查到对应的文档,并且在.NET Framework SDK的Include目录中有一个对应的mscoree.h,提供了这些函数的Prototype。应用程序通过这些函数,可以访问CLR提供的各项功能,比如:

函数名
用途
GetCORSystemDirectory
获得进程中加载的CLR的安装目录
GetCORVersion
获得进程中加载的CLR的版本西nxi 
GetFileVersion
获得指定文件的CLR版本信息
GetRequestedRuntimeInfo
获得指定版本CLR的相关信息
GetRequestedRuntimeVersion
获得应用程序运行所需要的CLR版本信息
ClrCreateManagedInstance
创建一个.NET对象并返回指定的接口,使用此函数可以访问大量的.NET Framework的已有功能
CorBindToRuntime
加载指定版本CLR
CorBindToRuntimeHost
在Host中加载指定版本CLR,Hosting时候使用
CreateDebuggingInterfaceFromVersion
获得对应版本CLR的ICorDebug接口,用于编写调试器(比如Visual Studio)
CorLaunchApplication
以指定参数启动托管程序

除此之外还有很多,这里只是列了一些比较常用的功能而已。可以看到这些功能都非常有用,特别值得提出的是CorBindToRuntimeHost和CreateDebuggingInterfaceFromVersion。前者提供了对CLR各个方面的定制功能,功能非常强大,有兴趣的朋友可以参考MSDN或者Customizing the Common Language Runtime一书。而后者则提供了对托管程序的调试支持,通过ICorDebug接口。

MSCOREE提供对COM支持

非托管代码可以通过COM直接调用.NET的Assembly中的托管对象。以下面这个对象为例,该对象CLSID为{0029598F-26Fa-46F7-953B-86E2947AB19F},类型为Microsoft.SqlServer.Replication.ComErrorRecord,线程模型为Both,Assembly名称为Microsoft.SqlServer.Replication, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91,所需CLR版本为v2.0.50727 (2.0 RTM)。最值得注意的是,入口点为mscoree.dll。

对于COM来说,COM只知道CLSID=0029598F-26Fa-46F7-953B-86E2947AB19F}的COM对象位于MSCOREE.DLL中。而事实上,这个类型位于Microsoft.SqlServer.Replication.dll之中,但是COM并不知道,COM只需要知道从MSCOREE.DLL中可以获得对应的ClassFactory就可以了,然后COM会通过IClassFactory接口创建这个托管对象的实例,并返回对应的接口。假定一个非托管程序尝试通过COM创建这样一个对象,那么会发生下面这些事情:
1.     程序调用CoCreateInstance通知COM需要创建这样一个对象,CLSID=0029598F-26Fa-46F7-953B-86E2947AB19F,需要返回IDispatch接口
2.     COM调用CoGetClassObject函数查找对应的入口DLL
3.     COM找到对应的注册表,发现对应的DLL为MSCOREE.DLL
4.     COM加载MSCOREE.DLL,调用DllGetClassObject函数,传入CLSID
5.     MSCOREE.DLL中的DllGetClassObject函数读入CLSID,找到对应的注册表,获取对象的类型名称,Assembly名称,CLR版本等信息
6.     DllGetClassObject加载对应版本的CLR
7.     DllGetClassObject返回一个临时Class Factory对象的IClassFactory接口
8.     COM调用这个Class Factory对象的IClassFactory::CreateInstance方法
9.     这个Class Factory加载对应的CLR,并创建对象,返回一个对象的CCW (Com Callable Wrapper),并该CCW的返回指定的IDispatch接口
可以看到,这个情况下起到最关键作用的是MSCOREE.DLL所提供的DllGetClassObject函数。

除了对用户自定义的托管对象提供COM支持之外,MSCOREE.DLL自己也支持少量COM对象,因此MSCOREE.dll支持DllGetClassObject, DllRegisterServer, DllUnregisterServer, DllCanUnloadNow这些COM DLL所需要支持的标准函数。

MSCOREE.DLL的兼容性问题

我们可以考虑一下,假如我们现在有了.NET Framework 1.0,然后安装了.NET Framework 2.0,那么MSCOREE.DLL会发生变化吗。答案是可能会,如果到2.0到1.0发生了改变需要修改MSCOREE.DLL(比如多加了一个函数),那么肯定要更新MSCOREE.DLL,但是这个MSCOREE.DLL必须完全支持所有.NET Framework 1.0中的MSCOREE.DLL中的函数,否则可以想象所有依赖于这些变化的MSCOREE.DLL中的函数程序都会出错。因此MSCOREE.DLL必须要做到完全向前兼容。

再考虑卸载的情况,假如这个时候.NET Framework 2.0被卸载,那么MSCOREE.DLL会被还原成.NET Framework 1.0的吗?这次答案则是不会。因为2.0的MSCOREE.DLL本身支持.NET Framework 1.0,因此无须替换。这样最为简单。

事实上是,CLR Team一般很少改动MSCOREE.DLL,避免出现兼容性问题,因此可以预见,MSCOREE.DLL将会是.NET Framework/CLR中变化最少的DLL。换句话说,这篇文章的内容,在可以预见的未来几个版本基本上不会过时。OK,对于MSCOREE.DLL的讨论到这里就告一段落,有兴趣的朋友可以自己动手写一些小程序,实际体会一下MSCOREE.DLL所提供的各项功能。

 
ABAQUS中CDP模型在钢筋混凝土节点低周反复荷载模拟的关键技术解析 本文深入解析了ABAQUS中CDP模型在钢筋混凝土节点低周反复荷载模拟中的关键技术。通过详细介绍CDP模型的核心价值、建模关键技术、滞回曲线优化方法及典型问题排查指南,帮助工程师精准模拟混凝土的拉伸开裂和压缩压碎行为,提升抗震分析效率。文章还提供了实用的工程应用技巧,如快速建模模板和后处理自动化脚本。 阅读详情

相关推荐

libopus 实现pcm 编码到opus

opus 是一种音频格式,常用于语音通话、视频会议中。最近做了个pcm 到opus 的编码,踩了不少坑,特此记录一下。

sinat_27720649的博客 9464

转 MSCOREE是托管程序的入口点

 学习http://blog.csdn.net/ATField/archive/2007/08/19/1750890.aspx 现在做.NET Framework的开发的朋友应该是越来越多了,但是可能并非人人都对MSCOREE.DLL非常了解。而事实上,毫不夸张地说,MSCOREE.DLL是.NET Framework中最为核心的DLL之一,没有这个DLL,托管程序根本

LiSonTu的专栏 636

基于STM32F103的二维码识别项目——OV7670篇

此系列用于记录做过的项目,这篇文章介绍基于STM32F103的二维码识别项目之OV7670FIFO模块。

beyourself_he的博客 4287

CLR寄宿(上) MSCOREE.DLL

CLR寄宿(上) MSCOREE.DLL   托管代码调用非托管代码,.NET提供了P/Invoke(平台调用)方式,它作为.NET的基础出现在各类书籍和网络资源上,这里不再讨论。那么非托管代码如何去调用托管代码呢?我们知道,一个托管应用程序首先被操作系统启动,然后由操作系统调用CLR来托管该程序。那么.NET框架到底以什么方式让操作系统来认识它并且可以启动它呢?微软实际将其作为COM服务器实...

weixin_34246551的博客 360

CSI Tools 工具的安装 Intel 5300 + Ubuntu14.04

在 ubuntu14 系统上面安装 CSI Tools,2020最新教程,亲测可用,只要保证和我做法一致绝对可以安装好。

WS的小屋 1万+

揭秘Coze图生图隐藏玩法:用Excel批量生成100+电商主图(扣子插件进阶教程)

本文深入解析了如何利用Coze(扣子)的图像生成插件实现电商主图的批量自动化生产。通过将Excel数据源、参数化提示词模板与参考图风格相结合,构建了一套高效的企业级解决方案,能够快速为海量SKU生成风格统一的高质量图片,大幅提升电商运营效率。

theta的博客 433

已安装Framework4.0,仍提示没有安装Framework4.0问题

部分电脑安装Framework4.0成功,但运行4.0程序时仍提示未安装Framework4.0(Win7上再安装4.5后仍不管用)。碰到有该问题的电脑占极少数 原因: 文件 %windir%\system32\mscoree.dll 或(和)%windir%\SysWOW64\mscoree.dll在安装过程中未能应用对应高版本的文件,仍就是V2.0.*版或其他低版本,出现这种情况的原因是安

df398286232的专栏 2万+

TSMC 40nm LP工艺下,新手画版图最容易踩的5个坑(附Cadence避坑指南)

本文详细解析了TSMC 40nm LP工艺下版图设计的5个常见陷阱,包括MOS管尺寸转换、DNW隔离、Guard Ring设计、金属布线和DRC检查。通过Cadence实战技巧和设计规则优化,帮助新手工程师规避典型错误,提升版图设计效率和质量。

weixin_26800111的博客 455

电脑开机或打开程序提示缺少mscoree.dll文件问题

在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包文件不完整造成,原因可能是某些系统防护软件将重要的DLL文件识别为可疑,阻止并放入了隔离单里,还有一些常见的DLL文件缺少是因为系统没有安装齐全的微软运行库,还有部分情况是因为系统更新升级补丁造成的系统内部文件损坏。

2401_89460702的博客 1355

Windows 上安装 OpenCode 完全指南:从零到成功,人人能看懂!

跟着这篇教程,你应该已经成功在 Windows 上安装并运行了 OpenCode。步骤操作要点1安装 Chocolatey必须以管理员身份运行 PowerShell2安装 OpenCode3验证安装关闭并重新打开终端,输入4进入项目目录必须是 Git 仓库(git init5配置模型输入/connect,输入 API Key6开始使用输入问题测试最后的小建议如果没有 API Key,可以从 DeepSeek 或 Kimi 开始,有免费额度初次使用建议先在简单项目上测试。

专注于编程、AI、人工智能等多个领域内容研究和分析 3883

华为海思:大小海思的双轮驱动战略分析

大海思的定位清晰明确,即专注于为华为内部提供高性能、高集成度的芯片解决方案,以支持华为终端、服务器等业务的快速发展。小海思的产品线广泛,涵盖了广域物联、短距物联、手机穿戴、显示交互、智慧视觉、智慧媒体、MCU、模拟以及光模块等多个领域。通过提供多样化的芯片解决方案,小海思旨在满足外部客户的不同需求,拓展华为海思在芯片市场的份额和影响力。大海思的产品布局主要围绕华为的内部需求展开。在智能手机应用处理器方面,大海思的麒麟系列芯片已经成为华为手机的标志性产品,以其出色的性能和能效比赢得了市场的广泛认可。

dream it possible 2922

Win11系统错误powershell找不到mscoree.dll的三种解决方法

近期有用户在更新微软Win11最新补丁KB5013943后,出现了严重 Bug,其中包含了powershell.exe - 系统错误,并提示找不到mscoree.dll,这该怎么解决呢?下面小编就为大家带来三种解决方法介绍,一起来看看吧! 更多重装系统教程尽在小白系统重装官网   由于找不到 mscoree.dll ,无法执行代码。重新安装程序可能会解决此问题。   方法一:   1、首先,按键盘上的 Win + X 组合键,或右键点击任务栏底部的Windows开始图标,在打开的隐藏菜单项中,选

qq_29508575的博客 8327

Windows环境下QGIS完整编译指南(从环境搭建到问题解决)

本文详细介绍了在Windows 11系统下编译QGIS 3.40.12版本的完整流程。主要内容包括:前期准备工作(系统要求、工具清单)、环境搭建(Visual Studio 2026、OSGeo4W、Qt Creator的安装配置)、以及详细的CMake参数设置。特别强调了依赖管理的重要性,并提供了解决常见编译错误的方案。该指南适用于GIS二次开发、QGIS功能定制和源码学习等场景,通过OSGeo4W工具简化了复杂的依赖管理过程,确保编译过程的可重复性。

LuckyHanMo的博客 1332
上一篇: .NET/CLR好书推荐
下一篇: 庆祝微软Silverlight上海开发团队的博客正式开张!
ATField
博客等级 码龄25年 673粉丝 119原创
评论 18
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值