首页 > 解决方案 > Microsoft 如何从 DLL 的元数据中隐藏 C# 内部类?

问题描述

这一切都始于我想分析 CVE-2017-8759 周围的代码。我知道 CVE 的修复程序位于 System.Runtime.Remoting.dll 中名为 WsdlParser.cs 的类中,该类是 .Net 框架的一部分。您的计算机上可能有此 dll,位置类似于:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7\System.Runtime.Remoting.dll

我使用 ilspycmd 将代码重新组装回 C#,并注意到输出目录中缺少 WsdlParser.cs:

在此处输入图像描述

后来我使用了 CFF Explorer,发现 TypeDefs 的元数据中确实缺少这种类型:

在此处输入图像描述

但是,我知道这个类是存在的:

我注意到此行为与此 dll 中的所有内部类一致,但我不明白它的意义。我的猜测是可能有一个构建后过程来删除内部类型的数据,但如果是这样,我如何能够通过加载程序集来找到该类?我认为 CIL 使用 TypeDef 元数据加载类型,但是是否有额外的空间来存储这些数据?

为了更好地理解它,我创建了一个带有内部类的 C# 测试项目,并使用 CFF Explorer 检查了元数据。内部类在调试和发布版本中应该存在。

那么这个巫毒是什么?

多谢你们。

标签: c#reflectionreverse-engineeringcililspy

解决方案


您发现的是一个Reference Assembly。在你找到它的路径中有一个很大的线索。

参考程序集是一种特殊类型的程序集,仅包含表示库的公共 API 表面所需的最少量元数据。它们包括在构建工具中引用程序集时重要的所有成员的声明,但不包括对其 API 合同没有明显影响的私有成员的所有成员实现和声明。

(我的重点

和:

当您的库使用者需要针对许多不同版本的库构建他们的程序时,为您的库生成参考程序集会很有用。为所有这些版本分发实现程序集可能是不切实际的,因为它们的尺寸很大。参考程序集的大小更小,将它们作为库 SDK 的一部分分发可以减少下载大小并节省磁盘空间。

没有魔法,只是一种在不需要完整文件时分发较小文件的公开记录方法。

这些程序集在编译时使用,但不在运行时使用。为此,您需要一个实现程序集,该程序集将通过其他方式提供,例如已放置在 GAC 中。


推荐阅读