Skip to content

Instantly share code, notes, and snippets.

@omajid
Created June 5, 2024 19:08
Show Gist options
  • Save omajid/c82f19c1850ac3349b3c1641fe214c4b to your computer and use it in GitHub Desktop.
Save omajid/c82f19c1850ac3349b3c1641fe214c4b to your computer and use it in GitHub Desktop.
// https://download.microsoft.com/download/7/3/3/733ad403-90b2-4064-a81e-01035a7fe13c/ms%20partition%20ii.pdf
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
foreach (string arg in args)
{
var file = arg;
Console.WriteLine($"Looking at {file}");
if (file.EndsWith(".dll"))
{
using var pdbStream = File.OpenRead(file);
using var peReader = new PEReader(pdbStream);
var metadataReader = peReader.GetMetadataReader();
Console.WriteLine(metadataReader);
foreach (var attributeHandle in metadataReader.CustomAttributes)
{
var customAttribute = metadataReader.GetCustomAttribute(attributeHandle);
var valueHandle = customAttribute.Value;
if (customAttribute.Constructor.Kind == HandleKind.MethodDefinition)
{
var methodDefinition = metadataReader.GetMethodDefinition((MethodDefinitionHandle)customAttribute.Constructor);
var typeDefinition = metadataReader.GetTypeDefinition(methodDefinition.GetDeclaringType());
Console.WriteLine($"Type: {metadataReader.GetString(typeDefinition.Namespace)}.{metadataReader.GetString(typeDefinition.Name)}");
var typeName = metadataReader.GetString(typeDefinition.Name);
if (typeName == "AssemblyInformationalVersionAttribute")
{
Console.WriteLine(GetSingleStringValue(metadataReader, typeName, valueHandle));
}
}
else if (customAttribute.Constructor.Kind == HandleKind.MemberReference)
{
var ctor = metadataReader.GetMemberReference((MemberReferenceHandle)customAttribute.Constructor);
if (ctor.Parent.Kind == HandleKind.TypeReference)
{
var attrType = metadataReader.GetTypeReference((TypeReferenceHandle)ctor.Parent);
Console.WriteLine($"Type: {metadataReader.GetString(attrType.Namespace)}.{metadataReader.GetString(attrType.Name)}");
var attrName = metadataReader.GetString(attrType.Name);
if (attrName == "AssemblyInformationalVersionAttribute")
{
Console.WriteLine(GetSingleStringValue(metadataReader, attrName, valueHandle));
}
}
else
{
Console.WriteLine(ctor.Parent.Kind);
}
}
}
foreach (var debugEntry in peReader.ReadDebugDirectory())
{
Console.WriteLine($"{debugEntry.Type}: {debugEntry.DataSize}");
switch (debugEntry.Type)
{
case DebugDirectoryEntryType.CodeView:
{
var data = peReader.ReadCodeViewDebugDirectoryData(debugEntry);
Console.WriteLine($"\tage: {data.Age}");
Console.WriteLine($"\tguid: {data.Guid}");
Console.WriteLine($"\tpath: {data.Path}");
break;
}
case DebugDirectoryEntryType.PdbChecksum:
{
var data = peReader.ReadPdbChecksumDebugDirectoryData(debugEntry);
Console.WriteLine($"\talgorithm: {data.AlgorithmName}");
Console.WriteLine($"\tchecksum: {BitConverter.ToString(data.Checksum.ToArray())}");
break;
}
default:
break;
}
}
}
else if (file.EndsWith(".pdb"))
{
using var pdbStream = File.OpenRead(file);
using var metadataProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
var metadataReader = metadataProvider.GetMetadataReader();
var debugHeader = metadataReader.DebugMetadataHeader;
var contentId = new BlobContentId(debugHeader.Id);
Console.WriteLine($"\tguid: {contentId.Guid}");
Console.WriteLine($"\tdefault: {contentId.IsDefault}");
Console.WriteLine($"\tstamp: {contentId.Stamp}");
}
}
string? GetSingleStringValue(MetadataReader mr, string typeName, BlobHandle valueHandle)
{
var data = mr.GetBlobContent(valueHandle);
if (data[0] != 0x01 || data[1] != 0x00)
{
Console.WriteLine($"error reading data for attrbiute {typeName}");
return null;
}
ReadOnlySpan<byte> d = data.AsSpan();
return Encoding.UTF8.GetString(d.Slice(start:2, length: d.Length - 4));
}
#!/bin/bash
set -euo pipefail
set -x
sdk=$(readlink -f $1)
commit=$2
for file in $(find $sdk -iname '*.dll'); do
echo $file
dotnet bin/Debug/net8.0/DebugHelper.dll $file > out
grep --binary-files=without-match -E '^@9.0' out
grep --binary-files=without-match -F '+'"$commit" out
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment