Microsoft如何从DLL的元数据中隐藏C#内部类?

亚历克斯:

当我想分析有关CVE-2017-8759的代码时,一切就开始了。我知道CVE的修复程序是System.Runtime.Remoting.dll中名为WsdlParser.cs的类,该类是.Net Framework的一部分。您可能在类似于以下位置的计算机上拥有此dll:

C:\ Program Files(x86)\参考程序集\ Microsoft \ Framework.NETFramework \ v4.7 \ System.Runtime.Remoting.dll

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

在此处输入图片说明

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

在此处输入图片说明

但是,我知道有一个此类:

  • It's in Microsoft's documentation: https://referencesource.microsoft.com/System.Runtime.Remoting/metadata/wsdlparser.cs.html
  • When using reflection and LoadAssembly() I was able to find the class:

        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");
        }
    

I noticed that this behavior is consistent to all internal classes in this dll, but I don't understand how it makes sense. My guess is there might be a post-build procedure to remove data of internal types, but if so, how was I able to find the class by loading the assembly? I thought that the CIL loads types using the TypeDef metadata, but is there an additional space where this data is stored?

In order to understand it better, I created a C# test project with an internal class, and inspected the metadata using CFF Explorer. The internal class was there, as it should be, in debug and in release builds.

So what is this voodoo?

Thanks guys.

Damien_The_Unbeliever :

What you've found is a Reference Assembly. There's a big clue to that in the path you found it in.

Reference assemblies are a special type of assembly that contain only the minimum amount of metadata required to represent the library's public API surface. They include declarations for all members that are significant when referencing an assembly in build tools, but exclude all member implementations and declarations of private members that have no observable impact on their API contract.

(My emphasis)

And:

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

没什么大不了的,只是公开记录的不需要完整文件时分发较小文件的方法。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章