Skip to content

Instantly share code, notes, and snippets.

@MichalStrehovsky
Created January 24, 2018 15:09
Show Gist options
  • Save MichalStrehovsky/e2ddec899d3e0db6eba95bf68694b40e to your computer and use it in GitHub Desktop.
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
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