public static bool IsGeneratedName(this StringHandle handle, MetadataReader metadata) { return(!handle.IsNil && metadata.GetString(handle).StartsWith("<", StringComparison.Ordinal)); }
public VarInfo(LocalVariable v, MetadataReader pdbReader) { this.Name = pdbReader.GetString(v.Name); this.Index = v.Index; }
internal string GetString(StringHandle name) { return(metadata.GetString(name)); }
internal static void CheckTypeParameters(this MetadataReader reader, GenericParameterHandleCollection genericParameters, params string[] expectedNames) { var actualNames = genericParameters.Select(reader.GetGenericParameter).Select(tp => reader.GetString(tp.Name)).ToArray(); Assert.True(expectedNames.SequenceEqual(actualNames)); }
public void SimpleSignatureProviderCoverage() { using (FileStream stream = File.OpenRead(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly.Location)) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>)); Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle)); TypeDefinition type = reader.GetTypeDefinition(typeHandle); Dictionary <string, string> expectedFields = GetExpectedFieldSignatures(); ImmutableArray <string> genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty); foreach (var fieldHandle in type.GetFields()) { FieldDefinition field = reader.GetFieldDefinition(fieldHandle); string fieldName = reader.GetString(field.Name); string expected; Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName); Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext)); } Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures(); foreach (var methodHandle in type.GetMethods()) { MethodDefinition method = reader.GetMethodDefinition(methodHandle); ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters); string methodName = reader.GetString(method.Name); string expected; Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName); MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext); Assert.True(signature.Header.Kind == SignatureKind.Method); if (methodName.StartsWith("Generic")) { Assert.Equal(1, signature.GenericParameterCount); } else { Assert.Equal(0, signature.GenericParameterCount); } Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1)); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures(); foreach (var propertyHandle in type.GetProperties()) { PropertyDefinition property = reader.GetPropertyDefinition(propertyHandle); string propertyName = reader.GetString(property.Name); string expected; Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName); MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext); Assert.True(signature.Header.Kind == SignatureKind.Property); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedEvents = GetExpectedEventSignatures(); foreach (var eventHandle in type.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); string eventName = reader.GetString(@event.Name); string expected; Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName); Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type)); } Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType)); } }
public static string FormatAssemblyInfo(this MetadataReader metadataReader, AssemblyDefinition assemblyDefinition) { var name = metadataReader.GetString(assemblyDefinition.Name); return(metadataReader.FormatAssemblyInfo(name, assemblyDefinition.Culture, assemblyDefinition.PublicKey, assemblyDefinition.Version)); }
/// <summary> /// Try to look up field access info for given canon in metadata blobs for all available modules. /// </summary> /// <param name="metadataReader">Metadata reader for the declaring type</param> /// <param name="declaringTypeHandle">Declaring type for the method</param> /// <param name="fieldHandle">Field handle</param> /// <param name="canonFormKind">Canonical form to use</param> /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param> /// <returns>true when found, false otherwise</returns> private static unsafe bool TryGetFieldAccessMetadataFromFieldAccessMap( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle, CanonicalFormKind canonFormKind, ref FieldAccessMetadata fieldAccessMetadata) { CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind); string fieldName = null; RuntimeTypeHandle declaringTypeHandleDefinition = TypeLoaderEnvironment.GetTypeDefinition(declaringTypeHandle); foreach (NativeFormatModuleInfo mappingTableModule in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle))) { NativeReader fieldMapReader; if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader)) { continue; } NativeParser fieldMapParser = new NativeParser(fieldMapReader, 0); NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule)) { continue; } var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { // Grammar of a hash table entry: // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned(); if ((canonFormKind == CanonicalFormKind.Universal) != ((entryFlags & FieldTableFlags.IsUniversalCanonicalEntry) != 0)) { continue; } RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) && !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle)) { continue; } if ((entryFlags & FieldTableFlags.HasMetadataHandle) != 0) { Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle(); if (!fieldHandle.Equals(entryFieldHandle)) { continue; } } else { if (fieldName == null) { QTypeDefinition qTypeDefinition; bool success = Instance.TryGetMetadataForNamedType( declaringTypeHandleDefinition, out qTypeDefinition); Debug.Assert(success); MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader; fieldName = nativeFormatMetadataReader.GetString(fieldHandle.GetField(nativeFormatMetadataReader).Name); } string entryFieldName = entryParser.GetString(); if (fieldName != entryFieldName) { continue; } } int fieldOffset; IntPtr fieldAddressCookie = IntPtr.Zero; if (canonFormKind == CanonicalFormKind.Universal) { if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, entryParser.GetUnsigned() /* field ordinal */, out fieldOffset)) { Debug.Assert(false); return(false); } } else { if ((entryFlags & FieldTableFlags.FieldOffsetEncodedDirectly) != 0) { fieldOffset = (int)entryParser.GetUnsigned(); } else { fieldOffset = 0; fieldAddressCookie = externalReferences.GetAddressFromIndex(entryParser.GetUnsigned()); FieldTableFlags storageClass = entryFlags & FieldTableFlags.StorageClass; if (storageClass == FieldTableFlags.GCStatic || storageClass == FieldTableFlags.ThreadStatic) { fieldOffset = (int)entryParser.GetUnsigned(); } } } fieldAccessMetadata.MappingTableModule = mappingTableModule.Handle; fieldAccessMetadata.Cookie = fieldAddressCookie; fieldAccessMetadata.Flags = entryFlags; fieldAccessMetadata.Offset = fieldOffset; return(true); } } return(false); }
/// <summary> /// EventMap Table Columns: /// Parent (RID to TypeDef) /// EventList (RID to EventTable) /// =========================================== /// Event Table Columns: /// Name (offset to #String) /// Flags (2 byte unsigned) /// EventType (token to TypeDefOrRef) /// </summary> private void ValidateEvent(MetadataReader reader, uint rowId, uint startIdx, uint count, bool isVBMod = false) { if (0 == count) { return; } var expNames = new string[] { "E01", "E01", "CS1IGoo<System.Linq.Expressions.Expression,System.Object>.E01" }; // ModuleVB01 // Map: 0:TypeDef[2000003], 1:Event[14000001] // Event: 0:0000, 1:string#1c6, 2:TypeDefOrRef[02000006] var modNames = new string[] { "AnEvent" }; var modTokens = new uint[] { 0x02000006 }; uint zeroBased = startIdx - 1; uint delta = count; // Last one if (0xF0000000 == count) { delta = (uint)reader.EventTable.NumberOfRows - zeroBased; if (0 == delta) { return; } } // Validity Rules Assert.InRange((uint)reader.EventTable.NumberOfRows, zeroBased + count, uint.MaxValue); for (uint i = zeroBased; i < zeroBased + count; i++) { var handle = EventDefinitionHandle.FromRowId((int)i + 1); var evnt = reader.GetEventDefinition(handle); // Name if (isVBMod) { Assert.Equal(modNames[i], reader.GetString(evnt.Name)); } else { Assert.Equal(expNames[i], reader.GetString(evnt.Name)); } Assert.Equal(0, (ushort)evnt.Attributes); if (isVBMod) { Assert.Equal(modTokens[i], (uint)evnt.Type.Token); } else { Assert.Equal((int)rowId, evnt.Type.RowId); // could be TypeSpec Id if it's in generic } } }
internal override void DumpSectionContents(ReadyToRunSection section) { switch (section.Type) { case ReadyToRunSectionType.AvailableTypes: if (!_options.Naked) { uint availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser availableTypesParser = new NativeParser(_r2r.Image, availableTypesSectionOffset); NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); _writer.WriteLine(availableTypes.ToString()); } foreach (string name in _r2r.AvailableTypes) { _writer.WriteLine(name); } break; case ReadyToRunSectionType.MethodDefEntryPoints: if (!_options.Naked) { NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); _writer.Write(methodEntryPoints.ToString()); } break; case ReadyToRunSectionType.InstanceMethodEntryPoints: if (!_options.Naked) { uint instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser instanceParser = new NativeParser(_r2r.Image, instanceSectionOffset); NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size)); _writer.Write(instMethodEntryPoints.ToString()); _writer.WriteLine(); } foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods) { _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}"); } break; case ReadyToRunSectionType.RuntimeFunctions: int rtfOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int rtfEndOffset = rtfOffset + section.Size; int rtfIndex = 0; while (rtfOffset < rtfEndOffset) { int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); int endRva = -1; if (_r2r.Machine == Machine.Amd64) { endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); } int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); _writer.WriteLine($"Index: {rtfIndex}"); _writer.WriteLine($" StartRva: 0x{startRva:X8}"); if (endRva != -1) { _writer.WriteLine($" EndRva: 0x{endRva:X8}"); } _writer.WriteLine($" UnwindRva: 0x{unwindRva:X8}"); rtfIndex++; } break; case ReadyToRunSectionType.CompilerIdentifier: _writer.WriteLine(_r2r.CompilerIdentifier); break; case ReadyToRunSectionType.ImportSections: if (_options.Naked) { DumpNakedImportSections(); } else { foreach (ReadyToRunImportSection importSection in _r2r.ImportSections) { importSection.WriteTo(_writer); if (_options.Raw && importSection.Entries.Count != 0) { if (importSection.SectionRVA != 0) { _writer.WriteLine("Section Bytes:"); DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize); } if (importSection.SignatureRVA != 0) { _writer.WriteLine("Signature Bytes:"); DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int)); } if (importSection.AuxiliaryDataRVA != 0 && importSection.AuxiliaryDataSize != 0) { _writer.WriteLine("AuxiliaryData Bytes:"); DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize); } } foreach (ReadyToRunImportSection.ImportSectionEntry entry in importSection.Entries) { entry.WriteTo(_writer, _options); _writer.WriteLine(); } _writer.WriteLine(); } } break; case ReadyToRunSectionType.ManifestMetadata: int assemblyRefCount = 0; if (!_r2r.Composite) { MetadataReader globalReader = _r2r.GetGlobalMetadataReader(); assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef); _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):"); for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++) { AssemblyReference assemblyRef = globalReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex)); string assemblyRefName = globalReader.GetString(assemblyRef.Name); _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}"); } } _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count()} entries):"); int manifestAsmIndex = 0; foreach (string manifestReferenceAssembly in _r2r.ManifestReferenceAssemblies) { _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 2:X2}]: {manifestReferenceAssembly}"); manifestAsmIndex++; } break; case ReadyToRunSectionType.AttributePresence: int attributesStartOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int attributesEndOffset = attributesStartOffset + section.Size; NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset); _writer.WriteLine("Attribute presence filter"); _writer.WriteLine(attributes.ToString()); break; case ReadyToRunSectionType.InliningInfo: int iiOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int iiEndOffset = iiOffset + section.Size; InliningInfoSection inliningInfoSection = new InliningInfoSection(_r2r, iiOffset, iiEndOffset); _writer.WriteLine(inliningInfoSection.ToString()); break; case ReadyToRunSectionType.InliningInfo2: int ii2Offset = _r2r.GetOffset(section.RelativeVirtualAddress); int ii2EndOffset = ii2Offset + section.Size; InliningInfoSection2 inliningInfoSection2 = new InliningInfoSection2(_r2r, ii2Offset, ii2EndOffset); _writer.WriteLine(inliningInfoSection2.ToString()); break; case ReadyToRunSectionType.OwnerCompositeExecutable: int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress); Decoder decoder = Encoding.UTF8.GetDecoder(); int charLength = decoder.GetCharCount(_r2r.Image, oceOffset, section.Size); char[] charArray = new char[charLength]; decoder.GetChars(_r2r.Image, oceOffset, section.Size, charArray, 0, flush: true); string ownerCompositeExecutable = new string(charArray); _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable); break; } }
private object ResolveModuleReference(ModuleReferenceHandle handle) { ModuleReference moduleReference = _metadataReader.GetModuleReference(handle); string fileName = _metadataReader.GetString(moduleReference.Name); return(_moduleResolver.ResolveModule(this.Assembly, fileName)); }
private void LookupMetadataDefinitions( TypeDefinition typeDefinition, OrderPreservingMultiDictionary <string, MetadataDefinition> definitionMap) { // Only bother looking for extension methods in static types. // Note this check means we would ignore extension methods declared in assemblies // compiled from VB code, since a module in VB is compiled into class with // "sealed" attribute but not "abstract". // Although this can be addressed by checking custom attributes, // we believe this is not a common scenario to warrant potential perf impact. if ((typeDefinition.Attributes & TypeAttributes.Abstract) != 0 && (typeDefinition.Attributes & TypeAttributes.Sealed) != 0) { foreach (var child in typeDefinition.GetMethods()) { var method = _metadataReader.GetMethodDefinition(child); if ((method.Attributes & MethodAttributes.SpecialName) != 0 || (method.Attributes & MethodAttributes.RTSpecialName) != 0) { continue; } // SymbolTreeInfo is only searched for types and extension methods. // So we don't want to pull in all methods here. As a simple approximation // we just pull in methods that have attributes on them. if ((method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public && (method.Attributes & MethodAttributes.Static) != 0 && method.GetParameters().Count > 0 && method.GetCustomAttributes().Count > 0) { // Decode method signature to get the receiver type name (i.e. type name for the first parameter) var blob = _metadataReader.GetBlobReader(method.Signature); var decoder = new SignatureDecoder <ParameterTypeInfo, object>(ParameterTypeInfoProvider.Instance, _metadataReader, genericContext: null); var signature = decoder.DecodeMethodSignature(ref blob); // It'd be good if we don't need to go through all parameters and make unnecessary allocations. // However, this is not possible with meatadata reader API right now (although it's possible by copying code from meatadata reader implementaion) if (signature.ParameterTypes.Length > 0) { _containsExtensionsMethod = true; var firstParameterTypeInfo = signature.ParameterTypes[0]; var definition = new MetadataDefinition(MetadataDefinitionKind.Member, _metadataReader.GetString(method.Name), firstParameterTypeInfo); definitionMap.Add(definition.Name, definition); } } } } foreach (var child in typeDefinition.GetNestedTypes()) { var type = _metadataReader.GetTypeDefinition(child); // We don't include internals from metadata assemblies. It's less likely that // a project would have IVT to it and so it helps us save on memory. It also // means we can avoid loading lots and lots of obfuscated code in the case the // dll was obfuscated. if (IsPublic(type.Attributes)) { var definition = MetadataDefinition.Create(_metadataReader, type); definitionMap.Add(definition.Name, definition); _allTypeDefinitions.Add(definition); } } }
public static IEnumerable <string> DumpTypeReferences(this MetadataReader reader) { return(reader.TypeReferences .Select(t => reader.GetTypeReference(t)) .Select(t => $"{reader.GetString(t.Name)}, {reader.GetString(t.Namespace)}, {reader.Dump(t.ResolutionScope)}")); }
public static IEnumerable <string> DumpAssemblyReferences(this MetadataReader reader) { return(reader.AssemblyReferences.Select(r => reader.GetAssemblyReference(r)) .Select(row => $"{reader.GetString(row.Name)} {row.Version.Major}.{row.Version.Minor}")); }
/// <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]); } } } }
private static ImmutableArray <string> GetTypeParameterNames(MetadataReader reader, GenericParameterHandleCollection handles) { return(ImmutableArray.CreateRange(handles.Select(h => reader.GetString(reader.GetGenericParameter(h).Name)))); }
/// <summary> /// Param Table Columns: /// Name (offset to #String) /// Flags, Sequence (2 byte unsigned) /// </summary> private void ValidateParam(MetadataReader reader, uint startIndex, uint count, bool isMod = false) { if (count == 0) { return; } // AppCS - 7 var expNames = new string[] { "p", "t", "p", "value", "t", "value", "t" }; // ================= // ModuleVB01 - 20 var modNames = new string[] { "index", "index", "value", "em", "cls", "del", "obj", "obj", "o", "e", "p", "TargetObject", "TargetMethod", "o", "e", "DelegateCallback", "DelegateAsyncState", "DelegateAsyncResult", "o", "e", }; var modFlags = new ushort[] { 0, 0, 0, 0, 0x1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; var modSeqs = new ushort[] { 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 3, 4, 1, 1, 2, }; if (startIndex > reader.ParamTable.NumberOfRows) { return; } uint zeroBased = startIndex - 1; uint delta = count; // Last one if (0xF0000000 == count) { delta = (uint)reader.ParamTable.NumberOfRows - zeroBased; if (0 == delta) { return; } } Assert.InRange((uint)reader.ParamTable.NumberOfRows, zeroBased + delta, uint.MaxValue); // 1 based for (uint i = zeroBased; i < zeroBased + delta; i++) { var handle = ParameterHandle.FromRowId((int)i + 1); var row = reader.GetParameter(handle); // Console.WriteLine("P: {0}", GetStringData(row.Name)); if (isMod) { Assert.Equal(modNames[i], reader.GetString(row.Name)); Assert.Equal(modFlags[i], (ushort)row.Attributes); Assert.Equal(modSeqs[i], row.SequenceNumber); } else { Assert.Equal(expNames[i], reader.GetString(row.Name)); Assert.Equal((ushort)0, (ushort)row.Attributes); Assert.Equal((ushort)1, row.SequenceNumber); } } // for }
private static AssemblyIdentity CreateAssemblyIdentityOrThrow( this MetadataReader reader, Version version, AssemblyFlags flags, BlobHandle publicKey, StringHandle name, StringHandle culture, bool isReference ) { string nameStr = reader.GetString(name); if (!MetadataHelpers.IsValidMetadataIdentifier(nameStr)) { throw new BadImageFormatException( string.Format(CodeAnalysisResources.InvalidAssemblyName, nameStr) ); } string cultureName = culture.IsNil ? null : reader.GetString(culture); if (cultureName != null && !MetadataHelpers.IsValidMetadataIdentifier(cultureName)) { throw new BadImageFormatException( string.Format(CodeAnalysisResources.InvalidCultureName, cultureName) ); } ImmutableArray <byte> publicKeyOrToken = reader.GetBlobContent(publicKey); bool hasPublicKey; if (isReference) { hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0; if (hasPublicKey) { if (!MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) { throw new BadImageFormatException(CodeAnalysisResources.InvalidPublicKey); } } else { if ( !publicKeyOrToken.IsEmpty && publicKeyOrToken.Length != AssemblyIdentity.PublicKeyTokenSize ) { throw new BadImageFormatException( CodeAnalysisResources.InvalidPublicKeyToken ); } } } else { // Assembly definitions never contain a public key token, they only can have a full key or nothing, // so the flag AssemblyFlags.PublicKey does not make sense for them and is ignored. // See Ecma-335, Partition II Metadata, 22.2 "Assembly : 0x20". // This also corresponds to the behavior of the native C# compiler and sn.exe tool. hasPublicKey = !publicKeyOrToken.IsEmpty; if (hasPublicKey && !MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) { throw new BadImageFormatException(CodeAnalysisResources.InvalidPublicKey); } } if (publicKeyOrToken.IsEmpty) { publicKeyOrToken = default(ImmutableArray <byte>); } return(new AssemblyIdentity( name: nameStr, version: version, cultureName: cultureName, publicKeyOrToken: publicKeyOrToken, hasPublicKey: hasPublicKey, isRetargetable: (flags & AssemblyFlags.Retargetable) != 0, contentType: (AssemblyContentType)( (int)(flags & AssemblyFlags.ContentTypeMask) >> 9 ), noThrow: true )); }
/// <summary> /// Extracts the method signature from the metadata by rid /// </summary> public ReadyToRunMethod( ReadyToRunReader readyToRunReader, MetadataReader metadataReader, EntityHandle methodHandle, int entryPointId, string owningType, string constrainedType, string[] instanceArgs, int?fixupOffset) { _readyToRunReader = readyToRunReader; _fixupOffset = fixupOffset; MethodHandle = methodHandle; EntryPointRuntimeFunctionId = entryPointId; MetadataReader = metadataReader; EntityHandle owningTypeHandle; GenericParameterHandleCollection genericParams = default(GenericParameterHandleCollection); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(typeParameters: Array.Empty <string>(), methodParameters: instanceArgs); DisassemblingTypeProvider typeProvider = new DisassemblingTypeProvider(); // get the method signature from the method handle switch (MethodHandle.Kind) { case HandleKind.MethodDefinition: { MethodDefinition methodDef = MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); Name = MetadataReader.GetString(methodDef.Name); Signature = methodDef.DecodeSignature <string, DisassemblingGenericContext>(typeProvider, genericContext); owningTypeHandle = methodDef.GetDeclaringType(); genericParams = methodDef.GetGenericParameters(); } break; case HandleKind.MemberReference: { MemberReference memberRef = MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); Name = MetadataReader.GetString(memberRef.Name); Signature = memberRef.DecodeMethodSignature <string, DisassemblingGenericContext>(typeProvider, genericContext); owningTypeHandle = memberRef.Parent; } break; default: throw new NotImplementedException(); } if (owningType != null) { DeclaringType = owningType; } else { DeclaringType = MetadataNameFormatter.FormatHandle(MetadataReader, owningTypeHandle); } StringBuilder sb = new StringBuilder(); sb.Append(Signature.ReturnType); sb.Append(" "); sb.Append(DeclaringType); sb.Append("."); sb.Append(Name); if (Signature.GenericParameterCount != 0) { sb.Append("<"); for (int i = 0; i < Signature.GenericParameterCount; i++) { if (i > 0) { sb.Append(", "); } if (instanceArgs != null && instanceArgs.Length > i) { sb.Append(instanceArgs[i]); } else { sb.Append("!"); sb.Append(i); } } sb.Append(">"); } sb.Append("("); for (int i = 0; i < Signature.ParameterTypes.Length; i++) { if (i > 0) { sb.Append(", "); } sb.AppendFormat($"{Signature.ParameterTypes[i]}"); } sb.Append(")"); SignatureString = sb.ToString(); }
public IEnumerable <TypeInfo> GetTypes() { foreach (var typeDefHandle in this.metadataReader.TypeDefinitions) { var typeDef = this.metadataReader.GetTypeDefinition(typeDefHandle); var name = this.metadataReader.GetString(typeDef.Name); var ns = this.metadataReader.GetString(typeDef.Namespace); if (name == "Apis") { continue; } // Some interfaces have the same name so use method names to determine uniqueness if (typeDef.Attributes.HasFlag(System.Reflection.TypeAttributes.Interface)) { name += "("; var handles = typeDef.GetMethods(); bool first = true; foreach (var handle in handles) { if (!first) { name += ","; } else { first = false; } var methodDef = this.metadataReader.GetMethodDefinition(handle); name += metadataReader.GetString(methodDef.Name); } name += ")"; } else { var fields = typeDef.GetFields(); bool first = true; foreach (var handle in fields.Take(10)) { name += "("; name += ")"; if (!first) { name += ","; } else { first = false; } var fieldDef = this.metadataReader.GetFieldDefinition(handle); name += metadataReader.GetString(fieldDef.Name); } } if (typeDef.IsNested) { continue; } yield return(new TypeInfo(ns, name)); } }
public static string FormatAssemblyInfo(this MetadataReader metadataReader, AssemblyReference assemblyReference) { var name = metadataReader.GetString(assemblyReference.Name); return(metadataReader.FormatAssemblyInfo(name, assemblyReference.Culture, assemblyReference.PublicKeyOrToken, assemblyReference.Version)); }
public VarInfo(Parameter p, MetadataReader pdbReader) { this.Name = pdbReader.GetString(p.Name); this.Index = (p.SequenceNumber) * -1; }
/// <summary> /// Creates a dictionary of all manifest resources in the given reader. /// </summary> private static ImmutableDictionary <string, ManifestResource> Resources(this MetadataReader reader) => reader.ManifestResources .Select(reader.GetManifestResource) .ToImmutableDictionary( resource => reader.GetString(resource.Name), resource => resource);
private void ValidateDefinitionAssemblyNameAgainst(AssemblyName assemblyName, MetadataReader reader, AssemblyReference assemblyRef) { Assert.NotEqual(reader.GetString(assemblyRef.Name), assemblyName.Name); }
private static string GetAssemblyReferenceName(MetadataReader reader, AssemblyReferenceHandle handle) { var reference = reader.GetAssemblyReference(handle); return(reader.GetString(reference.Name)); }
private EcmaModule AddModule(string filePath, string expectedSimpleName, bool useForBinding) { MemoryMappedViewAccessor mappedViewAccessor = null; PdbSymbolReader pdbReader = null; try { PEReader peReader = OpenPEFile(filePath, out mappedViewAccessor); pdbReader = OpenAssociatedSymbolFile(filePath, peReader); EcmaModule module = EcmaModule.Create(this, peReader, pdbReader); MetadataReader metadataReader = module.MetadataReader; string simpleName = metadataReader.GetString(metadataReader.GetAssemblyDefinition().Name); if (expectedSimpleName != null && !simpleName.Equals(expectedSimpleName, StringComparison.OrdinalIgnoreCase)) { throw new FileNotFoundException("Assembly name does not match filename " + filePath); } ModuleData moduleData = new ModuleData() { SimpleName = simpleName, FilePath = filePath, Module = module, MappedViewAccessor = mappedViewAccessor }; lock (this) { if (useForBinding) { ModuleData actualModuleData = _simpleNameHashtable.AddOrGetExisting(moduleData); if (actualModuleData != moduleData) { if (actualModuleData.FilePath != filePath) { throw new FileNotFoundException("Module with same simple name already exists " + filePath); } return(actualModuleData.Module); } } mappedViewAccessor = null; // Ownership has been transfered pdbReader = null; // Ownership has been transferred _moduleHashtable.AddOrGetExisting(moduleData); } return(module); } finally { if (mappedViewAccessor != null) { mappedViewAccessor.Dispose(); } if (pdbReader != null) { pdbReader.Dispose(); } } }
private EcmaModule AddModule(string filePath, string expectedSimpleName, byte[] moduleDataBytes, bool useForBinding, bool throwIfNotLoadable = true) { MemoryMappedViewAccessor mappedViewAccessor = null; PdbSymbolReader pdbReader = null; try { PEReader peReader = OpenPEFile(filePath, moduleDataBytes, out mappedViewAccessor); if ((!peReader.HasMetadata) && !throwIfNotLoadable) { return(null); } pdbReader = OpenAssociatedSymbolFile(filePath, peReader); EcmaModule module = EcmaModule.Create(this, peReader, containingAssembly: null, pdbReader); MetadataReader metadataReader = module.MetadataReader; string simpleName = metadataReader.GetString(metadataReader.GetAssemblyDefinition().Name); ModuleData moduleData = new ModuleData() { SimpleName = simpleName, FilePath = filePath, Module = module, MappedViewAccessor = mappedViewAccessor }; lock (this) { if (useForBinding) { ModuleData actualModuleData; if (!_simpleNameHashtable.TryGetValue(moduleData.SimpleName, out actualModuleData)) { _simpleNameHashtable.Add(moduleData.SimpleName, moduleData); actualModuleData = moduleData; } if (actualModuleData != moduleData) { if (actualModuleData.FilePath != filePath) { throw new FileNotFoundException("Module with same simple name already exists " + filePath); } return(actualModuleData.Module); } } mappedViewAccessor = null; // Ownership has been transfered pdbReader = null; // Ownership has been transferred _moduleHashtable.AddOrGetExisting(moduleData); } return(module); } catch when(!throwIfNotLoadable) { return(null); } finally { if (mappedViewAccessor != null) { mappedViewAccessor.Dispose(); } if (pdbReader != null) { pdbReader.Dispose(); } } }
private static string GetTypeName(StringHandle namespaceHandle, StringHandle typeHandle, MetadataReader reader) { return(namespaceHandle.IsNil ? reader.GetString(typeHandle) : reader.GetString(namespaceHandle) + "." + reader.GetString(typeHandle)); }
private static void ReadLocalScopeInformation( MetadataReader reader, MethodDefinitionHandle methodHandle, int ilOffset, EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider, bool isVisualBasicMethod, out ImmutableArray <ImmutableArray <ImportRecord> > importGroups, out ImmutableArray <ExternAliasRecord> externAliases, out ImmutableArray <string> localVariableNames, out ImmutableDictionary <int, ImmutableArray <bool> >?dynamicLocalMap, out ImmutableDictionary <int, ImmutableArray <string?> >?tupleLocalMap, out ImmutableArray <TLocalSymbol> localConstants, out ILSpan reuseSpan) { var localVariableNamesBuilder = ArrayBuilder <string> .GetInstance(); var localConstantsBuilder = ArrayBuilder <TLocalSymbol> .GetInstance(); ImmutableDictionary <int, ImmutableArray <bool> > .Builder? lazyDynamicLocalsBuilder = null; ImmutableDictionary <int, ImmutableArray <string?> > .Builder?lazyTupleLocalsBuilder = null; var innerMostImportScope = default(ImportScopeHandle); uint reuseSpanStart = 0; uint reuseSpanEnd = uint.MaxValue; try { foreach (var scopeHandle in reader.GetLocalScopes(methodHandle)) { try { var scope = reader.GetLocalScope(scopeHandle); if (ilOffset < scope.StartOffset) { // scopes are sorted by StartOffset, hence all scopes that follow can't contain ilOffset reuseSpanEnd = Math.Min(reuseSpanEnd, (uint)scope.StartOffset); break; } if (ilOffset >= scope.EndOffset) { // ilOffset is not in this scope, go to next one reuseSpanStart = Math.Max(reuseSpanStart, (uint)scope.EndOffset); continue; } // reuse span is a subspan of the inner-most scope containing the IL offset: reuseSpanStart = Math.Max(reuseSpanStart, (uint)scope.StartOffset); reuseSpanEnd = Math.Min(reuseSpanEnd, (uint)scope.EndOffset); // imports (use the inner-most): innerMostImportScope = scope.ImportScope; // locals (from all contained scopes): foreach (var variableHandle in scope.GetLocalVariables()) { var variable = reader.GetLocalVariable(variableHandle); if ((variable.Attributes & LocalVariableAttributes.DebuggerHidden) != 0) { continue; } localVariableNamesBuilder.SetItem(variable.Index, reader.GetString(variable.Name)); var dynamicFlags = ReadDynamicCustomDebugInformation(reader, variableHandle); if (!dynamicFlags.IsDefault) { lazyDynamicLocalsBuilder ??= ImmutableDictionary.CreateBuilder <int, ImmutableArray <bool> >(); lazyDynamicLocalsBuilder[variable.Index] = dynamicFlags; } var tupleElementNames = ReadTupleCustomDebugInformation(reader, variableHandle); if (!tupleElementNames.IsDefault) { lazyTupleLocalsBuilder ??= ImmutableDictionary.CreateBuilder <int, ImmutableArray <string?> >(); lazyTupleLocalsBuilder[variable.Index] = tupleElementNames; } } // constants (from all contained scopes): foreach (var constantHandle in scope.GetLocalConstants()) { var constant = reader.GetLocalConstant(constantHandle); var sigReader = reader.GetBlobReader(constant.Signature); symbolProvider.DecodeLocalConstant(ref sigReader, out var typeSymbol, out var value); var name = reader.GetString(constant.Name); var dynamicFlags = ReadDynamicCustomDebugInformation(reader, constantHandle); var tupleElementNames = ReadTupleCustomDebugInformation(reader, constantHandle); localConstantsBuilder.Add(symbolProvider.GetLocalConstant(name, typeSymbol, value, dynamicFlags, tupleElementNames)); } } catch (Exception e) when(e is UnsupportedSignatureContent || e is BadImageFormatException) { // ignore scopes with invalid data } } } finally { localVariableNames = localVariableNamesBuilder.ToImmutableAndFree(); localConstants = localConstantsBuilder.ToImmutableAndFree(); dynamicLocalMap = lazyDynamicLocalsBuilder?.ToImmutable(); tupleLocalMap = lazyTupleLocalsBuilder?.ToImmutable(); reuseSpan = new ILSpan(reuseSpanStart, reuseSpanEnd); } var importGroupsBuilder = ArrayBuilder <ImmutableArray <ImportRecord> > .GetInstance(); var externAliasesBuilder = ArrayBuilder <ExternAliasRecord> .GetInstance(); if (!innerMostImportScope.IsNil) { PopulateImports(reader, innerMostImportScope, symbolProvider, isVisualBasicMethod, importGroupsBuilder, externAliasesBuilder); } importGroups = importGroupsBuilder.ToImmutableAndFree(); externAliases = externAliasesBuilder.ToImmutableAndFree(); }
public override string GetEntityName(PEFile module, EntityHandle handle, bool fullName) { MetadataReader metadata = module.Metadata; switch (handle.Kind) { case HandleKind.TypeDefinition: return(ToCSharpString(metadata, (TypeDefinitionHandle)handle, fullName)); case HandleKind.FieldDefinition: var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)handle); var declaringType = fd.GetDeclaringType(); if (fullName) { return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(fd.Name)); } return(metadata.GetString(fd.Name)); case HandleKind.MethodDefinition: var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle); declaringType = md.GetDeclaringType(); string methodName = metadata.GetString(md.Name); switch (methodName) { case ".ctor": case ".cctor": var td = metadata.GetTypeDefinition(declaringType); methodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name)); break; case "Finalize": const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig); if ((md.Attributes & finalizerAttributes) != finalizerAttributes) { goto default; } MethodSignature <IType> methodSignature = md.DecodeSignature(MetadataExtensions.MinimalSignatureTypeProvider, default); if (methodSignature.GenericParameterCount != 0 || methodSignature.ParameterTypes.Length != 0) { goto default; } td = metadata.GetTypeDefinition(declaringType); methodName = "~" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name)); break; default: var genericParams = md.GetGenericParameters(); if (genericParams.Count > 0) { methodName += "<"; int i = 0; foreach (var h in genericParams) { if (i > 0) { methodName += ","; } var gp = metadata.GetGenericParameter(h); methodName += metadata.GetString(gp.Name); } methodName += ">"; } break; } if (fullName) { return(ToCSharpString(metadata, declaringType, fullName) + "." + methodName); } return(methodName); case HandleKind.EventDefinition: var ed = metadata.GetEventDefinition((EventDefinitionHandle)handle); declaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType(); if (fullName) { return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(ed.Name)); } return(metadata.GetString(ed.Name)); case HandleKind.PropertyDefinition: var pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle); declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType(); if (fullName) { return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(pd.Name)); } return(metadata.GetString(pd.Name)); default: return(null); } }
private static string GetString(MetadataReader metadataReader, StringHandle handle) { return CilDecoderHelpers.Instance.NormalizeString(metadataReader.GetString(handle)); }
/// <summary> /// Try to locate a (reference) assembly based on an AssemblyRef handle using the list of explicit reference assemblies /// and the list of reference paths passed to R2RDump. /// </summary> /// <param name="metadataReader">Containing metadata reader for the assembly reference handle</param> /// <param name="assemblyReferenceHandle">Handle representing the assembly reference</param> /// <param name="parentFile">Name of assembly from which we're performing the lookup</param> /// <returns></returns> public IAssemblyMetadata FindAssembly(MetadataReader metadataReader, AssemblyReferenceHandle assemblyReferenceHandle, string parentFile) { string simpleName = metadataReader.GetString(metadataReader.GetAssemblyReference(assemblyReferenceHandle).Name); return(FindAssembly(simpleName, parentFile)); }
/// <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; } }
private Object ResolveMemberReference(MemberReferenceHandle handle) { MemberReference memberReference = _metadataReader.GetMemberReference(handle); Object parent = GetObject(memberReference.Parent); TypeDesc parentTypeDesc = parent as TypeDesc; if (parentTypeDesc != null) { BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature); EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); string name = _metadataReader.GetString(memberReference.Name); if (parser.IsFieldSignature) { FieldDesc field = parentTypeDesc.GetField(name); if (field != null) { return(field); } throw new TypeSystemException.MissingFieldException(parentTypeDesc, name); } else { MethodSignature sig = parser.ParseMethodSignature(); TypeDesc typeDescToInspect = parentTypeDesc; // Try to resolve the name and signature in the current type, or any of the base types. do { // TODO: handle substitutions MethodDesc method = typeDescToInspect.GetMethod(name, sig); if (method != null) { // If this resolved to one of the base types, make sure it's not a constructor. // Instance constructors are not inherited. if (typeDescToInspect != parentTypeDesc && method.IsConstructor) { break; } return(method); } typeDescToInspect = typeDescToInspect.BaseType; } while (typeDescToInspect != null); throw new TypeSystemException.MissingMethodException(parentTypeDesc, name, sig); } } else if (parent is MethodDesc) { throw new NotSupportedException("Vararg methods not supported in .NET Core."); } else if (parent is ModuleDesc) { throw new NotImplementedException("MemberRef to a global function or variable."); } throw new BadImageFormatException(); }
/// <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 }
private void PrintVerifyMethodsResult(VerificationResult result, EcmaModule module, string pathOrModuleName) { Write("[IL]: Error ["); if (result.Code != VerifierError.None) { Write(result.Code); } else { Write(result.ExceptionID); } Write("]: "); Write("["); Write(pathOrModuleName); Write(" : "); MetadataReader metadataReader = module.MetadataReader; TypeDefinition typeDef = metadataReader.GetTypeDefinition(metadataReader.GetMethodDefinition(result.Method).GetDeclaringType()); string typeNamespace = metadataReader.GetString(typeDef.Namespace); Write(typeNamespace); Write("."); string typeName = metadataReader.GetString(typeDef.Name); Write(typeName); Write("::"); var method = (EcmaMethod)module.GetMethod(result.Method); PrintMethod(method); Write("]"); if (result.Code != VerifierError.None) { Write("[offset 0x"); Write(result.GetArgumentValue <int>("Offset").ToString("X8")); Write("]"); if (result.TryGetArgumentValue("Found", out string found)) { Write("[found "); Write(found); Write("]"); } if (result.TryGetArgumentValue("Expected", out string expected)) { Write("[expected "); Write(expected); Write("]"); } if (result.TryGetArgumentValue("Token", out int token)) { Write("[token 0x"); Write(token.ToString("X8")); Write("]"); } } Write(" "); WriteLine(result.Message); }
/// <summary> /// Helper method that will validate that a NamespaceDefinition (and all NamespaceDefinitions considered children /// of it) report correct values for their child namespaces, types, etc. All namespaces in the module are expected /// to be listed in the allNamespaces array. Additionally, the global namespace is expected to have type definitions /// for GlobalClassA, GlobalClassB, and Module. No type forwarder declarations are expected. /// /// All namespaces that aren't the global NS are expected to have type definitions equal to the array /// @namespaceName.Split('.') /// So, ns1.Ns2.NS3 is expected to have type definitions /// {"ns1", "Ns2", "NS3"}. /// /// definitionExceptions and forwarderExceptions may be used to override the default expectations. Pass in /// namespace (key) and what is expected (list of strings) for each exception. /// </summary> private void ValidateNamespaceChildren( MetadataReader reader, NamespaceDefinitionHandle initHandle, string[] allNamespaces, IReadOnlyDictionary<string, IList<string>> definitionExceptions = null, IReadOnlyDictionary<string, IList<string>> forwarderExceptions = null) { // Don't want to have to deal with null. if (definitionExceptions == null) { definitionExceptions = new Dictionary<string, IList<string>>(); } if (forwarderExceptions == null) { forwarderExceptions = new Dictionary<string, IList<string>>(); } var rootNamespaceDefinition = reader.GetNamespaceDefinition(initHandle); string rootNamespaceName = reader.GetString(initHandle); // We need to be in the table of all namespaces... Assert.Contains(rootNamespaceName, allNamespaces); // Cool. Now check to make sure that .Name only returns the last bit of our namespace name. var expNamespaceNameSegment = rootNamespaceName.Split('.').Last(); var rootNamespaceNameSegment = reader.GetString(rootNamespaceDefinition.Name); Assert.Equal(expNamespaceNameSegment, rootNamespaceNameSegment); bool isGlobalNamespace = rootNamespaceName.Length == 0; string[] expTypeDefinitions = null; // Special case: Global NS has GlobalClassA, GlobalClassB. Others just have autogenerated classes. if (definitionExceptions.ContainsKey(rootNamespaceName)) { expTypeDefinitions = definitionExceptions[rootNamespaceName].ToArray(); } else if (isGlobalNamespace) { expTypeDefinitions = new[] { "GlobalClassA", "GlobalClassB", "<Module>" }; } else { expTypeDefinitions = rootNamespaceName.Split('.'); } // Validating type definitions inside the namespace... int numberOfTypeDefinitions = 0; foreach (var definitionHandle in rootNamespaceDefinition.TypeDefinitions) { var definition = reader.GetTypeDefinition(definitionHandle); var definitionName = reader.GetString(definition.Name); var definitionFullNamespaceName = reader.GetString(definition.Namespace); Assert.Equal(rootNamespaceName, definitionFullNamespaceName); Assert.Contains(definitionName, expTypeDefinitions); numberOfTypeDefinitions += 1; } // Guarantee that there are no extra unexpected members... Assert.Equal(numberOfTypeDefinitions, expTypeDefinitions.Length); string[] expTypeForwarders = null; if (forwarderExceptions.ContainsKey(rootNamespaceName)) { expTypeForwarders = forwarderExceptions[rootNamespaceName].ToArray(); } else { expTypeForwarders = new string[] { }; } int numberOfTypeForwarders = 0; foreach (var forwarderHandle in rootNamespaceDefinition.ExportedTypes) { var forwarder = reader.GetExportedType(forwarderHandle); Assert.True(reader.StringComparer.Equals(forwarder.Namespace, rootNamespaceName)); var forwarderName = reader.GetString(forwarder.Name); Assert.Contains(forwarderName, expTypeForwarders); numberOfTypeForwarders += 1; } Assert.Equal(expTypeForwarders.Length, numberOfTypeForwarders); // Validate sub-namespaces // If the last index of '.' in a namespace name is == the current name's length, then // that ns is a direct child of the current one! IList<String> expChildren = null; // Special case: Global NS's children won't have .s in them. if (isGlobalNamespace) { expChildren = allNamespaces.Where(ns => !String.IsNullOrEmpty(ns) && !ns.Contains('.')).ToList(); } else { expChildren = allNamespaces .Where(ns => ns.StartsWith(rootNamespaceName) && ns.LastIndexOf('.') == rootNamespaceName.Length) .ToList(); } int numberOfSubNamespaces = 0; foreach (var subNamespaceHandle in rootNamespaceDefinition.NamespaceDefinitions) { Assert.False(subNamespaceHandle.IsNil); string subNamespaceFullName = reader.GetString(subNamespaceHandle); NamespaceDefinition subNamespace = reader.GetNamespaceDefinition(subNamespaceHandle); string subNamespaceName = subNamespaceFullName.Split('.').Last(); Assert.Equal(subNamespaceName, reader.GetString(subNamespace.Name)); Assert.True(reader.StringComparer.Equals(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName.Substring(0, subNamespaceName.Length - 1))); Assert.Equal(subNamespace.Parent, initHandle); Assert.Contains(subNamespaceFullName, expChildren); ValidateNamespaceChildren(reader, subNamespaceHandle, allNamespaces, definitionExceptions, forwarderExceptions); numberOfSubNamespaces += 1; } // Guarantee no extra unexpected namespaces... Assert.Equal(expChildren.Count, numberOfSubNamespaces); }
/// <summary> /// Workaround for unity mono being weird /// </summary> internal static AssemblyName GetAssemblyName(MetadataReader reader, StringHandle nameHandle, Version version, StringHandle cultureHandle, BlobHandle publicKeyOrTokenHandle, AssemblyHashAlgorithm assemblyHashAlgorithm, AssemblyFlags flags) { var name = reader.GetString(nameHandle); var cultureName = (!cultureHandle.IsNil) ? reader.GetString(cultureHandle) : null; var hashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)assemblyHashAlgorithm; var publicKeyOrToken = !publicKeyOrTokenHandle.IsNil ? reader.GetBlobBytes(publicKeyOrTokenHandle) : null; var assemblyName = new AssemblyName(name); try { assemblyName.Version = version; } catch (NotImplementedException) { } try { assemblyName.CultureName = cultureName; } catch (NotImplementedException) { } try { assemblyName.HashAlgorithm = hashAlgorithm; } catch (NotImplementedException) { } try { assemblyName.Flags = GetAssemblyNameFlags(flags); } catch (NotImplementedException) { } try { assemblyName.ContentType = GetContentTypeFromAssemblyFlags(flags); } catch (NotImplementedException) { } var hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0; if (hasPublicKey) { assemblyName.SetPublicKey(publicKeyOrToken); } else { assemblyName.SetPublicKeyToken(publicKeyOrToken); } return(assemblyName); }