Пример #1
0
        private CodedIndex DecodeIndex(uint value, IndexDetails withDetails)
        {
            byte code  = 0;
            uint index = 0;

            if (withDetails.IsLarge())
            {
                code  = (byte)(value & withDetails.Mask);
                index = (value & ~withDetails.Mask) >> withDetails.BitsToRepresentTag;
            }
            else
            {
                ushort inMask     = (ushort)withDetails.Mask;
                ushort shortValue = (ushort)value;
                code  = (byte)(value & inMask);
                index = (ushort)((shortValue & ~inMask) >> withDetails.BitsToRepresentTag); // shift to drop the masked bits
            }

            return(new CodedIndex(withDetails.Tables[code], index));
        }
Пример #2
0
        private Dictionary <CodedIndexes, IndexDetails> BuildDetailsMap(Dictionary <MetadataTables, int> rowsPerTableData)
        {
            IEnumerable <CodedIndexes> values           = Enum.GetValues(typeof(CodedIndexes)).Cast <CodedIndexes>();
            Dictionary <CodedIndexes, IndexDetails> map = new Dictionary <CodedIndexes, IndexDetails>();

            foreach (CodedIndexes current in values)
            {
                IndexDetails details = DetermineDetailsForIndexType(current);
                foreach (MetadataTables table in details.Tables)
                {
                    if (rowsPerTableData.Keys.Contains(table))
                    {
                        if (details.MaxRowsInTables < rowsPerTableData[table])
                        {
                            details.MaxRowsInTables = (uint)rowsPerTableData[table];
                        }
                    }
                }
                map.Add(current, details);
            }

            return(map);
        }
Пример #3
0
        internal MetadataStream(PeCoffFile file, uint address)
        {
            _owningFile = file;
            byte[] contents = file.FileContents;
            Offset offset   = (int)address;

            offset.Shift(4);        // reserved1 = BitConverter.ToUInt32(contents, offset.Shift(4));
            offset.Shift(1);        // majorVersion = contents[offset.Shift(1)];
            offset.Shift(1);        // minorVersion = contents[offset.Shift(1)];
            _heapOffsetSizes = (HeapOffsetSizes)contents.GetValue(offset.Shift(1));
            offset.Shift(1);        // reserved2 = contents[offset.Shift(1)];
            ulong valid = BitConverter.ToUInt64(contents, offset.Shift(8));

            offset.Shift(8);        // sorted = BitConverter.ToUInt64(contents, offset.Shift(8));

            // Now we need to read the number of rows present in the available tables, we have
            // had to add the unused tables to the MEtadatTables as mscorlib seems to use one. Not
            // sure which though.
            Dictionary <MetadataTables, int> rowsInPresentTables = new Dictionary <MetadataTables, int>();
            Array values = Enum.GetValues(typeof(MetadataTables));

            for (int i = 0; i < values.Length - 1; i++)
            {
                MetadataTables current = (MetadataTables)values.GetValue(i);
                ulong          mask    = (ulong)1 << (int)current;
                if ((mask & valid) == mask)
                {
                    rowsInPresentTables.Add(current, BitConverter.ToInt32(contents, offset.Shift(4)));
                }
            }

            // build index helper classes for metadata row creation
            ICodedIndexResolver resolver     = new CodedIndexResolver(rowsInPresentTables);
            IIndexDetails       indexDetails = new IndexDetails(rowsInPresentTables,
                                                                SizeOfStringIndexes,
                                                                SizeOfBlobIndexes,
                                                                SizeOfGuidIndexes
                                                                );

            // Following the array of row size we get the actual metadata tables
            _tables = new MetadataTablesDictionary(rowsInPresentTables.Count);
            for (int i = 0; i < values.Length; i++)
            {
                MetadataTables current = (MetadataTables)values.GetValue(i);
                if (!rowsInPresentTables.ContainsKey(current))
                {
                    continue;
                }

                int           numRows = rowsInPresentTables[current];
                MetadataRow[] rows    = new MetadataRow[numRows];

                switch (current)
                {
                case MetadataTables.Module:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ModuleMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.TypeRef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new TypeRefMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.TypeDef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new TypeDefMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.Field:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new FieldMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.MethodDef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new MethodMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.Param:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ParamMetadataTableRow(contents, offset, SizeOfStringIndexes);
                    }
                    break;

                case MetadataTables.InterfaceImpl:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new InterfaceImplMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.MemberRef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new MemberRefMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.Constant:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ConstantMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.CustomAttribute:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new CustomAttributeMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.FieldMarshal:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new FieldMarshalMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.DeclSecurity:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new DeclSecurityMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.ClassLayout:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ClassLayoutMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.FieldLayout:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new FieldLayoutMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.StandAloneSig:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new StandAloneSigMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.EventMap:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new EventMapMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.Event:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new EventMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.PropertyMap:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new PropertyMapMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.Property:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new PropertyMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.MethodSemantics:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new MethodSemanticsMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.MethodImpl:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new MethodImplMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.ModuleRef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ModuleRefMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.TypeSpec:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new TypeSpecMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.ImplMap:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ImplMapMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.FieldRVA:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new FieldRVAMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.Assembly:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.AssemblyProcessor:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyProcessorMetadataTableRow(contents, offset);
                    }
                    break;

                case MetadataTables.AssemblyOS:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyOSMetadataTableRow(contents, offset);
                    }
                    break;

                case MetadataTables.AssemblyRef:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyRefMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.AssemblyRefProcessor:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyRefProcessorMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.AssemblyRefOS:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new AssemblyRefOSMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.File:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new FileMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.ExportedType:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ExportedTypeMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.ManifestResource:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new ManifestResourceMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.NestedClass:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new NestedClassMetadataTableRow(contents, offset, indexDetails);
                    }
                    break;

                case MetadataTables.GenericParam:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new GenericParamMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.MethodSpec:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new MethodSpecMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;

                case MetadataTables.GenericParamConstraint:
                    for (int j = 0; j < numRows; j++)
                    {
                        rows[j] = new GenericParamConstraintMetadataTableRow(contents, offset, resolver, indexDetails);
                    }
                    break;
                }

                _tables.SetMetadataTable(current, rows);
            }
        }
Пример #4
0
        private IndexDetails DetermineDetailsForIndexType(CodedIndexes codedIndex)
        {
            IndexDetails details = new IndexDetails();

            details.Tables = new List <MetadataTables>();

            switch (codedIndex)
            {
            case CodedIndexes.HasFieldMarshall:
                details.Tables.Add(MetadataTables.Field);
                details.Tables.Add(MetadataTables.Param);
                details.Mask = 0x01;
                break;

            case CodedIndexes.HasSemantics:
                details.Tables.Add(MetadataTables.Event);
                details.Tables.Add(MetadataTables.Property);
                details.Mask = 0x01;
                break;

            case CodedIndexes.MethodDefOrRef:
                details.Tables.Add(MetadataTables.MethodDef);
                details.Tables.Add(MetadataTables.MemberRef);
                details.Mask = 0x01;
                break;

            case CodedIndexes.MemberForwarded:
                details.Tables.Add(MetadataTables.Field);
                details.Tables.Add(MetadataTables.MethodDef);
                details.Mask = 0x01;
                break;

            case CodedIndexes.TypeOrMethodDef:
                details.Tables.Add(MetadataTables.TypeDef);
                details.Tables.Add(MetadataTables.MethodDef);
                details.Mask = 0x01;
                break;

            case CodedIndexes.TypeDefOrRef:
                details.Tables.Add(MetadataTables.TypeDef);
                details.Tables.Add(MetadataTables.TypeRef);
                details.Tables.Add(MetadataTables.TypeSpec);
                details.Mask = 0x03;
                break;

            case CodedIndexes.HasConstant:
                details.Tables.Add(MetadataTables.Field);
                details.Tables.Add(MetadataTables.Param);
                details.Tables.Add(MetadataTables.Property);
                details.Mask = 0x03;
                break;

            case CodedIndexes.HasDeclSecurity:
                details.Tables.Add(MetadataTables.TypeDef);
                details.Tables.Add(MetadataTables.MethodDef);
                details.Tables.Add(MetadataTables.Assembly);
                details.Mask = 0x03;
                break;

            case CodedIndexes.Implementation:
                details.Tables.Add(MetadataTables.File);
                details.Tables.Add(MetadataTables.AssemblyRef);
                details.Tables.Add(MetadataTables.ExportedType);
                details.Mask = 0x03;
                break;

            case CodedIndexes.ResolutionScope:
                details.Tables.Add(MetadataTables.Module);
                details.Tables.Add(MetadataTables.ModuleRef);
                details.Tables.Add(MetadataTables.AssemblyRef);
                details.Tables.Add(MetadataTables.TypeRef);
                details.Mask = 0x03;
                break;

            case CodedIndexes.MemberRefParent:
                details.Tables.Add(MetadataTables.TypeDef);
                details.Tables.Add(MetadataTables.TypeRef);
                details.Tables.Add(MetadataTables.ModuleRef);
                details.Tables.Add(MetadataTables.MethodDef);
                details.Tables.Add(MetadataTables.TypeSpec);
                details.Mask = 0x07;
                break;

            case CodedIndexes.CustomAttributeType:
                details.Tables.Add(MetadataTables.Unused1);
                details.Tables.Add(MetadataTables.Unused1);
                details.Tables.Add(MetadataTables.MethodDef);
                details.Tables.Add(MetadataTables.MemberRef);
                details.Tables.Add(MetadataTables.Unused1);
                details.Mask = 0x07;
                break;

            case CodedIndexes.HasCustomAttribute:
                details.Tables.Add(MetadataTables.MethodDef);
                details.Tables.Add(MetadataTables.Field);
                details.Tables.Add(MetadataTables.TypeRef);
                details.Tables.Add(MetadataTables.TypeDef);
                details.Tables.Add(MetadataTables.Param);
                details.Tables.Add(MetadataTables.InterfaceImpl);
                details.Tables.Add(MetadataTables.MemberRef);
                details.Tables.Add(MetadataTables.Module);
                details.Tables.Add(MetadataTables.DeclSecurity);
                details.Tables.Add(MetadataTables.Property);
                details.Tables.Add(MetadataTables.Event);
                details.Tables.Add(MetadataTables.StandAloneSig);
                details.Tables.Add(MetadataTables.ModuleRef);
                details.Tables.Add(MetadataTables.TypeSpec);
                details.Tables.Add(MetadataTables.Assembly);
                details.Tables.Add(MetadataTables.AssemblyRef);
                details.Tables.Add(MetadataTables.File);
                details.Tables.Add(MetadataTables.ExportedType);
                details.Tables.Add(MetadataTables.ManifestResource);
                details.Tables.Add(MetadataTables.GenericParam);
                details.Tables.Add(MetadataTables.GenericParamConstraint);
                details.Tables.Add(MetadataTables.MethodSpec);
                details.Mask = 0x1F;
                break;
            }
            details.BitsToRepresentTag = details.Mask == 1
                ? (byte)1
                : (byte)Math.Round(Math.Log(details.Mask, 2), MidpointRounding.AwayFromZero);

            return(details);
        }