c# - 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 的元数据中确实缺少这种类型:
但是,我知道这个类是存在的:
- 它在微软的文档中:https ://referencesource.microsoft.com/System.Runtime.Remoting/metadata/wsdlparser.cs.html
使用反射和 LoadAssembly() 时,我能够找到该类:
Assembly assembly = Assembly.LoadFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7\System.Runtime.Remoting.dll"); foreach (var type in assembly.GetTypes()) { if (!type.FullName.EndsWith("WsdlParser")) { continue; } Console.WriteLine("Great Success"); }
我注意到此行为与此 dll 中的所有内部类一致,但我不明白它的意义。我的猜测是可能有一个构建后过程来删除内部类型的数据,但如果是这样,我如何能够通过加载程序集来找到该类?我认为 CIL 使用 TypeDef 元数据加载类型,但是是否有额外的空间来存储这些数据?
为了更好地理解它,我创建了一个带有内部类的 C# 测试项目,并使用 CFF Explorer 检查了元数据。内部类在调试和发布版本中应该存在。
那么这个巫毒是什么?
多谢你们。
解决方案
您发现的是一个Reference Assembly。在你找到它的路径中有一个很大的线索。
参考程序集是一种特殊类型的程序集,仅包含表示库的公共 API 表面所需的最少量元数据。它们包括在构建工具中引用程序集时重要的所有成员的声明,但不包括对其 API 合同没有明显影响的私有成员的所有成员实现和声明。
(我的重点)
和:
当您的库使用者需要针对许多不同版本的库构建他们的程序时,为您的库生成参考程序集会很有用。为所有这些版本分发实现程序集可能是不切实际的,因为它们的尺寸很大。参考程序集的大小更小,将它们作为库 SDK 的一部分分发可以减少下载大小并节省磁盘空间。
没有魔法,只是一种在不需要完整文件时分发较小文件的公开记录方法。
这些程序集在编译时使用,但不在运行时使用。为此,您需要一个实现程序集,该程序集将通过其他方式提供,例如已放置在 GAC 中。
推荐阅读
- python - 如何从图像中提取信息
- r - 如何创建具有分组的多个最小和最大点的多面图
- java - 无法使用 jdbc 模板将 Spring Boot 与 Secured Kerberos 连接
- jquery - 模态不显示按钮
- c++ - 重载运算符 == 和多态性的好习惯?
- python - Numba 和二维 numpy 数组列表
- java - 将 Solrj 与基本身份验证一起使用时,出现错误“原因:java.net.SocketException:连接重置”
- html - Django Html页面渲染项目循环
- c# - EventAggregator 如何注册事件和订阅者并通知所有订阅者事件触发?
- apache-spark - ¿ MultilayerPerceptronClassifier - Spark - mllib 中的 maxIter 参数是什么?