Created
January 24, 2018 15:09
-
-
Save MichalStrehovsky/e2ddec899d3e0db6eba95bf68694b40e to your computer and use it in GitHub Desktop.
Finds public types in an assembly that are not exposed from a set of facades
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Reflection.Metadata; | |
using System.Reflection.PortableExecutable; | |
namespace PublicScanner | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
MetadataStringDecoder decoder = new MetadataStringDecoder(System.Text.Encoding.UTF8); | |
PEReader reader = new PEReader(File.Open(@"C:\git\rt\bin\Windows_NT.x64.Debug\sdk\System.Private.CoreLib.dll", FileMode.Open)); | |
MetadataReader rdr = reader.GetMetadataReader(MetadataReaderOptions.Default, decoder); | |
List<PEReader> facades = new List<PEReader>(); | |
List<MetadataReader> facadeReaders = new List<MetadataReader>(); | |
foreach (var fileName in Directory.EnumerateFiles(@"C:\git\rt\bin\Windows_NT.x64.Debug\framework\", "*.dll")) | |
{ | |
var peReader = new PEReader(File.OpenRead(fileName)); | |
facades.Add(peReader); | |
facadeReaders.Add(peReader.GetMetadataReader(MetadataReaderOptions.Default, decoder)); | |
} | |
foreach (var definitionHandle in rdr.TypeDefinitions) | |
{ | |
TypeDefinition typeDef = rdr.GetTypeDefinition(definitionHandle); | |
const System.Reflection.TypeAttributes NestedMask = (System.Reflection.TypeAttributes)0x00000006; | |
// TODO: handling of nested types | |
if ((typeDef.Attributes & NestedMask) != 0) | |
continue; | |
if ((typeDef.Attributes & System.Reflection.TypeAttributes.Public) == 0) | |
continue; | |
string name = rdr.GetString(typeDef.Name); | |
string ns = rdr.GetString(typeDef.Namespace); | |
bool foundExport = false; | |
foreach (var frdr in facadeReaders) | |
{ | |
foreach (var exportHandle in frdr.ExportedTypes) | |
{ | |
ExportedType export = frdr.GetExportedType(exportHandle); | |
if (frdr.StringComparer.Equals(export.Name, name) && frdr.StringComparer.Equals(export.Namespace, ns)) | |
{ | |
foundExport = true; | |
} | |
} | |
} | |
if (!foundExport) | |
Console.WriteLine(rdr.GetString(typeDef.Name)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment