private Object ResolveAssemblyReference(AssemblyReferenceHandle handle) { AssemblyReference assemblyReference = _metadataReader.GetAssemblyReference(handle); AssemblyName an = new AssemblyName(); an.Name = _metadataReader.GetString(assemblyReference.Name); an.Version = assemblyReference.Version; var publicKeyOrToken = _metadataReader.GetBlobBytes(assemblyReference.PublicKeyOrToken); if ((an.Flags & AssemblyNameFlags.PublicKey) != 0) { an.SetPublicKey(publicKeyOrToken); } else { an.SetPublicKeyToken(publicKeyOrToken); } an.CultureName = _metadataReader.GetString(assemblyReference.Culture); an.ContentType = GetContentTypeFromAssemblyFlags(assemblyReference.Flags); return(Context.ResolveAssembly(an)); }
private IReadOnlyList <SourceLinkMap> GetSourceLinkInformation() { var sl = (from cdi in _reader.CustomDebugInformation let cd = _reader.GetCustomDebugInformation(cdi) let kind = _reader.GetGuid(cd.Kind) where kind == SourceLinkGuid let bl = _reader.GetBlobBytes(cd.Value) select Encoding.UTF8.GetString(bl)) .FirstOrDefault(); if (sl != null) { try { /* Some tools, like GitLink generate incorrectly escaped JSON: * * { * "documents": { * "C:\projects\cefsharp\*": "https://raw.github.com/CefSharp/CefSharp/4f88ad11416e93dde4b52216800efd42ba3b9c8a/*" * } * } * * Catch the exception and try to fix the key */ JObject?jobj = null; try { jobj = JObject.Parse(sl); } catch (JsonReaderException e) when(e.Path == "documents") { sl = sl.Replace(@"\", @"\\"); jobj = JObject.Parse(sl); } var docs = (JObject)jobj["documents"]; var slis = (from prop in docs.Properties() select new SourceLinkMap { Base = prop.Name.Replace(@"\", @"/"), // use forward slashes for the url, Location = prop.Value.Value <string>() }) .ToList(); return(slis); } catch (JsonReaderException jse) { throw new InvalidDataException("SourceLink data could not be parsed", jse); } } return(Array.Empty <SourceLinkMap>()); }
/// <summary> /// Unpacks all files stored in a PortablePDB meta-data. The key in the dictionary is the location of a source file /// on the build machine. The value is the content of the source file itself. /// The function will throw an exception if PortablePDB file is not found or anything else went wrong. /// </summary> /// <param name="pdbFilePath">Path to PortablePDB file to load source files from.</param> public static Dictionary <string, CompressedSourceFile> GetEmbeddedFiles(string pdbFilePath) { Dictionary <string, CompressedSourceFile> embeddedFiles = new Dictionary <string, CompressedSourceFile>(); using (FileStream stream = File.OpenRead(pdbFilePath)) using (MetadataReaderProvider metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(stream)) { MetadataReader metadataReader = metadataReaderProvider.GetMetadataReader(); CustomDebugInformationHandleCollection customDebugInformationHandles = metadataReader.CustomDebugInformation; foreach (var customDebugInformationHandle in customDebugInformationHandles) { CustomDebugInformation customDebugInformation = metadataReader.GetCustomDebugInformation(customDebugInformationHandle); if (metadataReader.GetGuid(customDebugInformation.Kind) == EmbeddedSource) { byte[] embeddedSource = metadataReader.GetBlobBytes(customDebugInformation.Value); Int32 uncompressedSourceFileSize = BitConverter.ToInt32(embeddedSource, 0); if (uncompressedSourceFileSize != 0) { Document document = metadataReader.GetDocument((DocumentHandle)customDebugInformation.Parent); string sourceFileName = System.IO.Path.GetFullPath(metadataReader.GetString(document.Name)); embeddedFiles.Add(sourceFileName, new CompressedSourceFile(embeddedSource)); } } } } return(embeddedFiles); }
public static AssemblyIdentity TryGetAssemblyIdentity(string filePath) { try { using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) using (PEReader peReader = new PEReader(stream)) { MetadataReader metadataReader = peReader.GetMetadataReader(); AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition(); string name = metadataReader.GetString(assemblyDefinition.Name); Version version = assemblyDefinition.Version; StringHandle cultureHandle = assemblyDefinition.Culture; string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null; AssemblyFlags flags = assemblyDefinition.Flags; bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0; BlobHandle publicKeyHandle = assemblyDefinition.PublicKey; ImmutableArray <byte> publicKeyOrToken = !publicKeyHandle.IsNil ? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull() : default(ImmutableArray <byte>); return(new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey)); } } catch { } return(null); }
private Object ResolveAssemblyReference(AssemblyReferenceHandle handle) { AssemblyReference assemblyReference = _metadataReader.GetAssemblyReference(handle); AssemblyName an = new AssemblyName(); an.Name = _metadataReader.GetString(assemblyReference.Name); an.Version = assemblyReference.Version; var publicKeyOrToken = _metadataReader.GetBlobBytes(assemblyReference.PublicKeyOrToken); if ((assemblyReference.Flags & AssemblyFlags.PublicKey) != 0) { an.SetPublicKey(publicKeyOrToken); } else { an.SetPublicKeyToken(publicKeyOrToken); } an.CultureName = _metadataReader.GetString(assemblyReference.Culture); an.ContentType = GetContentTypeFromAssemblyFlags(assemblyReference.Flags); var assembly = _moduleResolver.ResolveAssembly(an, throwIfNotFound: false); if (assembly == null) { return(ResolutionFailure.GetAssemblyResolutionFailure(an.Name)); } else { return(assembly); } }
private static void WriteAssemblyToXml(MetadataReader metaReader, XmlTextWriter xmlWriter) { if (!metaReader.IsAssembly) { return; } var assembly = metaReader.GetAssemblyDefinition(); xmlWriter.WriteStartElement("File"); xmlWriter.WriteAttributeString("AssemblyName", metaReader.GetString(assembly.Name)); xmlWriter.WriteAttributeString("Version", assembly.Version.ToString(4)); var culture = metaReader.GetString(assembly.Culture); xmlWriter.WriteAttributeString("Culture", string.IsNullOrEmpty(culture) ? "neutral" : culture); var publicKey = metaReader.GetBlobBytes(assembly.PublicKey); var publicKeyToken = PublicKeyTokenCalculator.CalculatePublicKeyToken(publicKey); var publicKeyTokenStr = BitConverter.ToString(publicKeyToken).Replace("-", string.Empty).ToLowerInvariant(); xmlWriter.WriteAttributeString("PublicKeyToken", publicKeyTokenStr); xmlWriter.WriteAttributeString("InGac", "false"); xmlWriter.WriteAttributeString("ProcessorArchitecture", "MSIL"); xmlWriter.WriteEndElement(); }
public unsafe int GetSigFromToken( int tkSignature, // Signature token. out byte *ppvSig, // return pointer to signature blob out int pcbSig ) // return size of signature { if (_metadataReaderOpt == null) { throw new NotSupportedException("Metadata not available"); } var sig = _metadataReaderOpt.GetStandaloneSignature( (StandaloneSignatureHandle)MetadataTokens.Handle(tkSignature) ); var signature = _metadataReaderOpt.GetBlobBytes(sig.Signature); GCHandle pinnedBuffer = GCHandle.Alloc(signature, GCHandleType.Pinned); ppvSig = (byte *)pinnedBuffer.AddrOfPinnedObject(); pcbSig = signature.Length; #pragma warning disable RS0042 // Do not copy value _pinnedBuffers.Add(pinnedBuffer); #pragma warning restore RS0042 // Do not copy value return(0); }
public static string GetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader) { string publicKey = "null"; if (!reference.PublicKeyOrToken.IsNil) { if ((reference.Flags & AssemblyFlags.PublicKey) != 0) { publicKey = CalculatePublicKeyToken(reference.PublicKeyOrToken, reader); } else { publicKey = reader.GetBlobBytes(reference.PublicKeyOrToken).ToHexString(8); } } string properties = ""; if ((reference.Flags & AssemblyFlags.Retargetable) != 0) { properties = ", Retargetable=true"; } return($"{reader.GetString(reference.Name)}, " + $"Version={reference.Version}, " + $"Culture={(reference.Culture.IsNil ? "neutral" : reader.GetString(reference.Culture))}, " + $"PublicKeyToken={publicKey}{properties}"); }
//<SnippetReadPdb> static string ReadDocumentPath(MetadataReader reader, Document doc) { BlobReader blob = reader.GetBlobReader(doc.Name); // Read path separator character var separator = (char)blob.ReadByte(); var sb = new StringBuilder(blob.Length * 2); // Read path segments while (true) { BlobHandle bh = blob.ReadBlobHandle(); if (!bh.IsNil) { byte[] nameBytes = reader.GetBlobBytes(bh); sb.Append(Encoding.UTF8.GetString(nameBytes)); } if (blob.Offset >= blob.Length) { break; } sb.Append(separator); } return(sb.ToString()); }
private void ReadAssemblyDefinition() { var definition = reader.GetAssemblyDefinition(); assemblyName = reader.GetString(definition.Name); publicKey = definition.PublicKey.IsNil ? null : reader.GetBlobBytes(definition.PublicKey); }
// https://github.com/Microsoft/msbuild/issues/4002 // https://github.com/dotnet/corefx/issues/34008 // // We do not use AssemblyReference.GetAssemblyName() here because its behavior // is different from other code paths with respect to neutral culture. We will // get unspecified culture instead of explicitly neutral culture. This in turn // leads string comparisons of assembly-name-modulo-version in RAR to false // negatives that break its conflict resolution and binding redirect generation. private static AssemblyName GetAssemblyName(MetadataReader metadataReader, AssemblyReferenceHandle handle) { var entry = metadataReader.GetAssemblyReference(handle); var assemblyName = new AssemblyName { Name = metadataReader.GetString(entry.Name), Version = entry.Version, CultureName = metadataReader.GetString(entry.Culture) }; var publicKeyOrToken = metadataReader.GetBlobBytes(entry.PublicKeyOrToken); if (publicKeyOrToken != null) { if (publicKeyOrToken.Length <= 8) { assemblyName.SetPublicKeyToken(publicKeyOrToken); } else { assemblyName.SetPublicKey(publicKeyOrToken); } } assemblyName.Flags = (AssemblyNameFlags)(int)entry.Flags; return(assemblyName); }
public static PublicKeyToken GetPublicKeyToken(this MetadataReader metadataReader, BlobHandle handle) { if (handle.IsNil) { return(PublicKeyToken.Empty); } var bytes = metadataReader.GetBlobBytes(handle); // Strong named assembly if (bytes != null && bytes.Length > 8) { // Get the public key token, which is the last 8 bytes of the SHA-1 hash of the public key using (var sha1 = SHA1.Create()) { var hash = sha1.ComputeHash(bytes); var token = new byte[8]; int count = 0; for (int i = hash.Length - 1; i >= hash.Length - 8; i--) { token[count] = hash[i]; count++; } return(new PublicKeyToken(ImmutableArray.Create(token))); } } return(new PublicKeyToken(ImmutableArray.Create(bytes))); }
private static string FormatPublicKeyToken(this MetadataReader metadataReader, BlobHandle handle) { byte[] bytes = metadataReader.GetBlobBytes(handle); if (bytes == null || bytes.Length <= 0) { return("null"); } if (bytes.Length > 8) // Strong named assembly { // Get the public key token, which is the last 8 bytes of the SHA-1 hash of the public key using (var sha1 = SHA1.Create()) { var token = sha1.ComputeHash(bytes); bytes = new byte[8]; int count = 0; for (int i = token.Length - 1; i >= token.Length - 8; i--) { bytes[count] = token[i]; count++; } } } // Convert bytes to string, but we don't want the '-' characters and need it to be lower case return(BitConverter.ToString(bytes) .Replace("-", "") .ToLowerInvariant()); }
private void ParseAssemblyDefinition(MetadataReader reader) { var assembly = reader.GetAssemblyDefinition(); Name = reader.GetString(assembly.Name); Version = assembly.Version; PublicKey = reader.GetBlobBytes(assembly.PublicKey).ToList(); }
private static bool TryMapPortablePdb(Module module, out MetadataReaderProvider metadataReaderProvider) { metadataReaderProvider = null; MetadataReader rd = null; try { metadataReaderProvider = GetMetadataReaderProvider(module); rd = metadataReaderProvider?.GetMetadataReader(); } catch (BadImageFormatException ex) when(ex.Message == "Invalid COR20 header signature.") { TraceSourceLink("no portable PDB found: " + module.FullyQualifiedName); // todo figure out a better way to detect if PDB is portable or classic // https://github.com/dotnet/corefx/blob/06b1365d9881ed26a921490d7edd2d4e4de35565/src/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs#L185 } if (rd == null) { metadataReaderProvider?.Dispose(); metadataReaderProvider = null; return(false); } TraceSourceLink("found portable PDB for: " + module.FullyQualifiedName); // https://github.com/dotnet/symreader-portable/blob/d27c08d6015c4716ced790e34233c0219773ab10/src/Microsoft.DiaSymReader.PortablePdb/Utilities/MetadataUtilities.cs var sourceLinkHandles = rd .GetCustomDebugInformation(EntityHandle.ModuleDefinition) .Where(r => !r.IsNil) .Select(rd.GetCustomDebugInformation) .Where(cdi => !cdi.Value.IsNil && rd.GetGuid(cdi.Kind) == SourceLinkId) .ToList(); if (sourceLinkHandles.Count == 0) { metadataReaderProvider?.Dispose(); metadataReaderProvider = null; return(false); } var sourceLinkHandle = sourceLinkHandles.First(); var sourceLink = SourceLink.Deserialize(rd.GetBlobBytes(sourceLinkHandle.Value)); var hinstance = (long)Marshal.GetHINSTANCE(module); foreach (var dh in rd.Documents) { if (dh.IsNil) { continue; } var doc = rd.GetDocument(dh); var file = rd.GetString(doc.Name); SourceMappedPaths[Tuple.Create(hinstance, file)] = sourceLink.GetUrl(file); } return(true); }
public static MetadataAssemblyReference GetAssemblyName(this AssemblyReference reference, MetadataReader reader) { return(new ReaderMetadataAssemblyReference( reader.GetString(reference.Name), reference.Version, reference.Culture.IsNil ? null : reader.GetString(reference.Culture), reference.PublicKeyOrToken.IsNil ? null : reader.GetBlobBytes(reference.PublicKeyOrToken), reference.Flags)); }
static string CalculatePublicKeyToken(BlobHandle blob, MetadataReader reader) { // Calculate public key token: // 1. hash the public key using the appropriate algorithm. byte[] publicKeyTokenBytes = reader.GetHashAlgorithm().ComputeHash(reader.GetBlobBytes(blob)); // 2. take the last 8 bytes // 3. according to Cecil we need to reverse them, other sources did not mention this. return(publicKeyTokenBytes.TakeLast(8).Reverse().ToHexString(8)); }
static AssemblyName CreateAssemblyName(MetadataReader mdReader, AssemblyReference ar) { var an = CreateAssemblyName(mdReader, ar.Name, ar.Version, ar.Culture); if (!ar.PublicKeyOrToken.IsNil) { an.SetPublicKeyToken(mdReader.GetBlobBytes(ar.PublicKeyOrToken)); } return(an); }
static AssemblyName CreateAssemblyName(MetadataReader mdReader, AssemblyDefinition ad) { var an = CreateAssemblyName(mdReader, ad.Name, ad.Version, ad.Culture); if (!ad.PublicKey.IsNil) { an.SetPublicKey(mdReader.GetBlobBytes(ad.PublicKey)); } return(an); }
public AssemblyName ToAssemblyName(AssemblyReference ar) { AssemblyName result = new AssemblyName(); result.CultureInfo = string.IsNullOrEmpty(_metaReader.GetString(ar.Culture)) ? null : new System.Globalization.CultureInfo(_metaReader.GetString(ar.Culture)); result.Name = _metaReader.GetString(ar.Name); result.Version = ar.Version; result.SetPublicKeyToken(_metaReader.GetBlobBytes(ar.PublicKeyOrToken)); return(result); }
public unsafe int GetSigFromToken(int tkSignature, out byte *ppvSig, out int pcbSig) { var signatureHandle = (StandaloneSignatureHandle)MetadataTokens.Handle(tkSignature); var bytes = MetadataReader.GetBlobBytes(MetadataReader.GetStandaloneSignature(signatureHandle).Signature); var pinned = GCHandle.Alloc(bytes, GCHandleType.Pinned); ppvSig = (byte *)pinned.AddrOfPinnedObject(); pcbSig = bytes.Length; return(HResult.S_OK); }
public ScannedAssembly(AssemblyReferenceHandle handle, MetadataReader reader) { var reference = reader.GetAssemblyReference(handle); Name = reader.GetString(reference.Name); Culture = reader.GetString(reference.Culture); PublicKey = reader.GetBlobBytes(reference.PublicKeyOrToken).ToList(); Token = reader.GetToken(handle); Version = reference.Version; Flags = reference.Flags; ResolutionStatus = ResolutionStatus.UnResolved; }
private byte[]? GetSourceLinkBytes() { if (_reader == null) { return(null); } var blobh = default(BlobHandle); foreach (var cdih in _reader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)) { var cdi = _reader.GetCustomDebugInformation(cdih); if (_reader.GetGuid(cdi.Kind) == SourceLinkId) { blobh = cdi.Value; } } if (blobh.IsNil) { return(Array.Empty <byte>()); } return(_reader.GetBlobBytes(blobh)); }
internal static AssemblyName GetAssemblyName(MetadataReader metadata, AssemblyReference assembly) { var name = new AssemblyName(metadata.GetString(assembly.Name)); bool hasPublicKey = (assembly.Flags & AssemblyFlags.PublicKey) != 0; if (hasPublicKey) { name.Flags = AssemblyNameFlags.PublicKey; name.SetPublicKey(metadata.GetBlobBytes(assembly.PublicKeyOrToken)); } else { name.SetPublicKeyToken(metadata.GetBlobBytes(assembly.PublicKeyOrToken)); } name.CultureName = assembly.Culture.IsNil ? string.Empty : metadata.GetString(assembly.Culture); name.Version = assembly.Version; return(name); }
private static AssemblyName GetAssemblyName(MetadataReader metadataReader) { AssemblyName name = new AssemblyName(); AssemblyDefinition definition = metadataReader.GetAssemblyDefinition(); name.Name = metadataReader.GetString(definition.Name); name.Version = definition.Version; name.CultureInfo = CultureInfo.GetCultureInfo(metadataReader.GetString(definition.Culture)); name.SetPublicKey(metadataReader.GetBlobBytes(definition.PublicKey)); return(name); }
//TODO: should replace the AssembyName.GetAssemblyVersion with something based on SMR. public static AssemblyName GetAssemblyName(MetadataReader metaReader, AssemblyDefinition assemblyDef) { AssemblyName result = new AssemblyName(); result.CultureInfo = string.IsNullOrEmpty(metaReader.GetString(assemblyDef.Culture)) ? null : new System.Globalization.CultureInfo(metaReader.GetString(assemblyDef.Culture)); result.Name = metaReader.GetString(assemblyDef.Name); result.Version = assemblyDef.Version; result.SetPublicKey(metaReader.GetBlobBytes(assemblyDef.PublicKey)); return(result); }
private IReadOnlyList <SourceLinkMap> GetSourceLinkInformation() { var sl = (from cdi in _reader.CustomDebugInformation let cd = _reader.GetCustomDebugInformation(cdi) let kind = _reader.GetGuid(cd.Kind) where kind == SourceLinkGuid let bl = _reader.GetBlobBytes(cd.Value) select Encoding.UTF8.GetString(bl)) .FirstOrDefault(); if (sl != null) { try { var jobj = JObject.Parse(sl); var docs = (JObject)jobj["documents"]; var slis = (from prop in docs.Properties() select new SourceLinkMap { Base = prop.Name, Location = prop.Value.Value <string>() }) .ToList(); return(slis); } catch (JsonReaderException jse) { throw new InvalidDataException("SourceLink data could not be parsed", jse); } } return(Array.Empty <SourceLinkMap>()); }
Object ResolveAssemblyReference(AssemblyReferenceHandle handle) { AssemblyReference assemblyReference = _metadataReader.GetAssemblyReference(handle); AssemblyName an = new AssemblyName(); an.Name = _metadataReader.GetString(assemblyReference.Name); an.Version = assemblyReference.Version; var publicKeyOrToken = _metadataReader.GetBlobBytes(assemblyReference.PublicKeyOrToken); if ((an.Flags & AssemblyNameFlags.PublicKey) != 0) { an.SetPublicKey(publicKeyOrToken); } else { an.SetPublicKeyToken(publicKeyOrToken); } // TODO: ContentType, Culture - depends on newer version of the System.Reflection contract return(Context.ResolveAssembly(an)); }
private IReadOnlyList <SourceLinkMap> GetSourceLinkInformation() { var sl = (from cdi in _reader.CustomDebugInformation let cd = _reader.GetCustomDebugInformation(cdi) let kind = _reader.GetGuid(cd.Kind) where kind == SourceLinkGuid let bl = _reader.GetBlobBytes(cd.Value) select Encoding.UTF8.GetString(bl)) .FirstOrDefault(); var jobj = JObject.Parse(sl); var docs = (JObject)jobj["documents"]; var slis = (from prop in docs.Properties() select new SourceLinkMap { Base = prop.Name, Location = prop.Value.Value <string>() }) .ToList(); return(slis); }
private byte[]? TryGetEmbeddedTextBytes(DocumentHandle handle) { var handles = _pdbReader.GetCustomDebugInformation(handle); foreach (var cdiHandle in handles) { var cdi = _pdbReader.GetCustomDebugInformation(cdiHandle); var guid = _pdbReader.GetGuid(cdi.Kind); if (guid == PortableCustomDebugInfoKinds.EmbeddedSource) { return(_pdbReader.GetBlobBytes(cdi.Value)); } } return(null); }
/// <summary> /// PropertyMap Table Columns: /// Parent (RID to TypeDef) /// PropertyList (RID to EventTable) /// =========================================== /// Property Table Columns: /// Name (offset to #String) /// PropFlags (2 byte unsigned) /// Type (offset to #blob - Signature) /// </summary> private void ValidateProperty(MetadataReader reader, uint rowId, uint startIndex, uint count, bool isVBMod = false) { if (0 == count) { return; } // ModuleCS01 var expNames = new string[] { "AppProp", "P01", "Item", "P01", "Item", "CS1IGoo<System.Linq.Expressions.Expression,System.Object>.P01", "CS1IGoo<System.Linq.Expressions.Expression,System.Object>.Item", }; var expSigs = new byte[][] { new byte[] { 0x28, 00, 0x15, 0x12, 0x21, 0x02, 0x12, 0x19, 0x1c }, new byte[] { 0x28, 00, 0x13, 00 }, new byte[] { 0x28, 01, 0x1c, 0x13, 00 }, new byte[] { 0x28, 0x00, 0x13, 00 }, new byte[] { 0x28, 0x01, 0x1c, 0x13, 00 }, new byte[] { 0x28, 00, 0x12, 0x19 }, new byte[] { 0x28, 01, 0x1c, 0x12, 0x19 } }; // ModuleVB01 // Prop: 0:0000, 1:string#13c, 2:blob#70 | 0:0000, 1:string#14d, 2:blob#75 var modNames = new string[] { "ModVBDefaultProp", "ModVBProp", }; var modSigs = new byte[][] { new byte[] { 0x28, 01, 0x0e, 0x08 }, new byte[] { 0x28, 00, 0x11, 0x09 }, }; // Validity Rules uint zeroBased = startIndex - 1; uint delta = count; // Last one if (0xF0000000 == count) { delta = (uint)reader.PropertyTable.NumberOfRows - zeroBased; if (0 == delta) { return; } } Assert.InRange((uint)reader.PropertyTable.NumberOfRows, zeroBased + count, uint.MaxValue); for (uint i = zeroBased; i < zeroBased + count; i++) { var handle = PropertyDefinitionHandle.FromRowId((int)i + 1); var row = reader.GetPropertyDefinition(handle); // Name if (isVBMod) { Assert.Equal(modNames[i], reader.GetString(row.Name)); } else { Assert.Equal(expNames[i], reader.GetString(row.Name)); } Assert.Equal(0, (ushort)row.Attributes); var sig = reader.GetBlobBytes(row.Signature); Assert.Equal(40, sig[0]); byte[] exp; if (isVBMod) { exp = modSigs[i]; } else { exp = expSigs[i]; } for (int j = 0; j < exp.Length; j++) { Assert.Equal(exp[j], sig[j]); } } // for }
/// <summary> /// Method Table Columns: /// Name (offset to #String) /// Flags, ImplFlags (2 byte unsigned) /// Signature (offset to #blob) /// ParamList (RID to Param) /// RVA (4-byte unsigned) -> body /// </summary> private void ValidateMethodDef(MetadataReader reader, uint startIndex, uint count, bool isMod = false) { if (0 == count) { return; } var expNames = new string[] { "get_AppProp", ".ctor", "AppMethod", ".cctor", "get_Item", "Use", ".ctor", "set_ContraFooProp", "CoFooMethod", "NormalFoo", "set_ContraFooProp", ".ctor", "CoFooMethod", ".ctor", "NormalFoo", ".ctor", ".ctor", ".ctor", "Main", ".ctor", }; var expFlags = new ushort[] { 0x0883, 0x1886, 0x0084, 0x1891, 0x0881, 0x0086, 0x1886, 0x0dc6, 0x05c6, 0x05c6, 0x09e6, 0x1886, 0x01e6, 0x1886, 0x01e6, 0x1886, 0x1886, 0x1886, 0x0096, 0x1886 }; var expRVAs = new uint[] { 0x2050, 0x2070, 0x20a4, 0x20b7, 0x20c0, 0x20d4, 0x2105, 0, 0, 0, 0x2115, 0x2118, 0x2120, 0x2152, 0x215c, 0x2177, 0x217f, 0x2187, 0x2190, 0x21d5 }; var expSigs = new byte[][] { new byte[] { 0x20, 0x00, 0x15, 0x12, 0x15, 0x02, 0x12, 0x19, 0x1c }, new byte[] { 0x20, 01, 01, 0x10, 0x12, 0x1d }, new byte[] { 0x30, 01, 01, 0x15, 0x12, 0x21, 0x01, 0x1e, 00, 0x1e, 00 }, new byte[] { 0x00, 0x00, 0x01 }, new byte[] { 0x20, 01, 0x11, 0x29, 0x11, 0x29 }, new byte[] { 0x20, 00, 0x15, 0x12, 0x21, 0x01, 0x12, 0x35 }, new byte[] { 0x20, 00, 01 }, new byte[] { 0x20, 01, 01, 0x13, 00 }, new byte[] { 0x20, 00, 0x13, 00 }, new byte[] { 0x20, 01, 0x13, 00, 0x13, 00 }, new byte[] { 0x20, 01, 01, 0x13, 00 }, new byte[] { 0x20, 00, 01 }, new byte[] { 0x20, 00, 0x13, 00 }, new byte[] { 0x20, 00, 01 }, new byte[] { 0x20, 01, 0x13, 00, 0x13, 00 }, new byte[] { 0x20, 00, 01 }, new byte[] { 0x20, 00, 01 }, new byte[] { 0x20, 00, 01 }, new byte[] { 00, 00, 08 }, new byte[] { 0x20, 00, 01 }, }; var modNames = new string[] { ".ctor", "get_ModVBDefaultProp", "set_ModVBDefaultProp", "get_ModVBProp", "BCSub01", "BCFunc02", ".cctor", "add_AnEvent", "remove_AnEvent", "EventHandler1", "BSFunc01", ".ctor", "BeginInvoke", "EndInvoke", "Invoke", }; var modFlags = new ushort[] { 0x1806, 0x0803, 0x0803, 0x0806, 0x0006, 0x0006, 0x1811, 0x0806, 0x0806, 0x0006, 0x0006, 0x1806, 0x0346, 0x0346, 0x0346, }; var modImpls = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, }; var modRVAs = new uint[] { 0x2050, 0x2058, 0x2070, 0x2074, 0x2090, 0x20a8, 0x20bc, 0x20cc, 0x20e8, 0x2104, 0x2108, 0, 0, 0, 0 }; var modSigs = new byte[][] { new byte[] { 0x20, 0x00, 0x01 }, new byte[] { 0x20, 01, 0x0e, 0x08 }, new byte[] { 0x20, 02, 01, 0x08, 0x0e }, new byte[] { 0x20, 00, 0x11, 0x09 }, new byte[] { 0x20, 02, 01, 0x11, 0x0d, 0x12, 0x11 }, new byte[] { 0x20, 01, 0x12, 0x15, 0x10, 0x12, 0x19 }, new byte[] { 0x00, 00, 01 }, new byte[] { 0x20, 01, 01, 0x12, 0x18 }, new byte[] { 0x20, 01, 01, 0x12, 0x18 }, new byte[] { 0x20, 02, 01, 0x1c, 0x12, 0x21 }, new byte[] { 0x20, 01, 0x1c, 0x10, 0x11, 0x14 }, new byte[] { 0x20, 02, 01, 0x1c, 0x18 }, new byte[] { 0x20, 04, 0x12, 0x2d, 0x1c, 0x12, 0x21, 0x12, 0x31, 0x1c }, new byte[] { 0x20, 01, 01, 0x12, 0x2d }, new byte[] { 0x20, 02, 01, 0x1c, 0x12, 0x21 }, }; if (startIndex > reader.MethodDefTable.NumberOfRows) { return; } uint zeroBased = startIndex - 1; uint delta = count; // Last one if (0xF0000000 == count) { delta = (uint)reader.MethodDefTable.NumberOfRows - zeroBased; if (0 == delta) { return; } } Assert.InRange((uint)reader.MethodDefTable.NumberOfRows, zeroBased + delta, uint.MaxValue); // 1 based bool first = true; uint prevParamStart = 0; for (uint i = zeroBased; i < zeroBased + delta; i++) { var handle = MethodDefinitionHandle.FromRowId((int)i + 1); var flags = reader.MethodDefTable.GetFlags(handle); var implFlags = reader.MethodDefTable.GetImplFlags(handle); var rva = reader.MethodDefTable.GetRva(handle); var name = reader.MethodDefTable.GetName(handle); var signature = reader.MethodDefTable.GetSignature(handle); var paramStart = (uint)reader.MethodDefTable.GetParamStart((int)i + 1); if (isMod) { // Console.WriteLine("M: {0}", reader.GetString(row.Name)); Assert.Equal(modNames[i], reader.GetString(name)); Assert.Equal(modFlags[i], (ushort)flags); Assert.Equal(modImpls[i], (ushort)implFlags); Assert.Equal(modRVAs[i], (uint)rva); } else { // Console.WriteLine("M: {0}", reader.GetString(row.Name)); Assert.Equal(expNames[i], reader.GetString(name)); Assert.Equal(expFlags[i], (ushort)flags); Assert.Equal((ushort)0, (ushort)implFlags); Assert.Equal(expRVAs[i], (uint)rva); } var sig = reader.GetBlobBytes(signature); int len = 0; if (isMod) { len = modSigs[i].Length; } else { len = expSigs[i].Length; } for (int j = 0; j < len; j++) { if (isMod) { Assert.Equal(modSigs[i][j], sig[j]); } else { Assert.Equal(expSigs[i][j], sig[j]); } } // validate previous row's param as it needs current row's other to calc how many if (!first) { ValidateParam(reader, prevParamStart, paramStart - prevParamStart, isMod); } // Last if (i + 1 == reader.MethodDefTable.NumberOfRows) { ValidateParam(reader, paramStart, 0xF0000000, isMod); } prevParamStart = paramStart; first = false; } }
/// <summary> /// Field Table Columns: /// Name (offset to #String) /// Flags (2 byte unsigned) /// Signature (offset to #blob) /// </summary> private void ValidateFieldDef(MetadataReader reader, uint startIndex, uint count, bool isMod = false) { if (count == 0) { return; } // APPCS var expNames = new string[] { "AppField01", "AppField02" }; var expFlags = new FieldAttributes[] { /*0x11*/ FieldAttributes.Private | FieldAttributes.Static, /*0x01*/ FieldAttributes.Private, }; var expSigs = new byte[][] { new byte[] { 0x06, 0x12, 0x11 }, new byte[] { 0x06, 0x12, 0x25 }, }; // ===================================================================================================== // VB Module - 8 var modNames = new string[] { "ConstString", "ArrayField", "AnEventEvent", "value__", "None", "Red", "Yellow", "Blue", }; var modFlags = new FieldAttributes[] { /* 0x8053 */ FieldAttributes.HasDefault | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.FamANDAssem | FieldAttributes.Private, /* 0x0016 */ FieldAttributes.Static | FieldAttributes.Family | FieldAttributes.FamANDAssem, /* 0x0001 */ FieldAttributes.Private, /* 0x0606 */ FieldAttributes.RTSpecialName | FieldAttributes.SpecialName | FieldAttributes.Family | FieldAttributes.FamANDAssem, /* 0x8056 */ FieldAttributes.HasDefault | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Family | FieldAttributes.FamANDAssem, /* 0x8056 */ FieldAttributes.HasDefault | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Family | FieldAttributes.FamANDAssem, /* 0x8056 */ FieldAttributes.HasDefault | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Family | FieldAttributes.FamANDAssem, /* 0x8056 */ FieldAttributes.HasDefault | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Family | FieldAttributes.FamANDAssem, }; var modSigs = new byte[][] { new byte[] { 0x06, 0x0e }, new byte[] { 0x06, 0x14, 0x11, 0x14, 02, 00, 02, 00, 00 }, new byte[] { 0x06, 0x12, 0x18 }, new byte[] { 0x06, 0x08 }, new byte[] { 0x06, 0x11, 0x10 }, new byte[] { 0x06, 0x11, 0x10 }, new byte[] { 0x06, 0x11, 0x10 }, new byte[] { 0x06, 0x11, 0x10 }, }; if (startIndex > reader.FieldTable.NumberOfRows) { return; } uint zeroBased = startIndex - 1; uint delta = count; // Last one if (0xF0000000 == count) { delta = (uint)reader.FieldTable.NumberOfRows - zeroBased; if (0 == delta) { return; } } Assert.InRange((uint)reader.FieldTable.NumberOfRows, zeroBased + delta, uint.MaxValue); // 1 based for (uint i = zeroBased; i < zeroBased + delta; i++) { var handle = FieldDefinitionHandle.FromRowId((int)(i + 1)); var row = reader.GetFieldDefinition(handle); if (isMod) { Assert.Equal(modNames[i], reader.GetString(row.Name)); Assert.Equal(modFlags[i], row.Attributes); } else { Assert.Equal(expNames[i], reader.GetString(row.Name)); Assert.Equal(expFlags[i], row.Attributes); } var sig = reader.GetBlobBytes(row.Signature); // calling convention, always 6 for field Assert.Equal(sig[0], 6); int len = 0; if (isMod) { len = modSigs[i].Length; } else { len = expSigs[i].Length; } for (int j = 1; j < len; j++) { if (isMod) { Assert.Equal(modSigs[i][j], sig[j]); } else { Assert.Equal(expSigs[i][j], sig[j]); } } } }