Пример #1
0
 private static TypeSignature ParseTypeSignature(BlobReader br)
 {
     var t = br.Read<ElementType>();
     if (PrimitiveTypeSignature.IsPrimitive(t))
         return new PrimitiveTypeSignature(t);
     switch (t)
     {
         case ElementType.Ptr:
             break;
         case ElementType.Byref:
             break;
         case ElementType.Valuetype:
             return new ValueTypeSignature(ReadCompressedToken(br));
         case ElementType.Class:
             return new ReferenceTypeSignature(ReadCompressedToken(br));
         case ElementType.Var:
             break;
         case ElementType.Array:
             break;
         case ElementType.Genericinst:
             break;
         case ElementType.Fnptr:
             return new FunctionPointerTypeSignature(ReadMethodSignature(br));
         case ElementType.Szarray:
             return new SZArrayTypeSignature(ParseTypeSignature(br));
         case ElementType.Mvar:
             break;
         default:
             break;
     }
     return null;
 }
Пример #2
0
        public MethodEntry(int rva, BlobReader reader)
        {
            RVA = rva;
            Flags = (MethodHeaderFlags)reader.ReadByte();
            if (!Flags.HasFlag(MethodHeaderFlags.FatFormat))
            {
                Size = (int)Flags & 0x3F;
                Flags = MethodHeaderFlags.TinyFormat;
                MethodBody = reader.ReadBytes((int)Size);
            }
            else
            {
                Size = (reader.ReadByte() & 0xF0) >> 4;
                MaxStack = reader.Read<ushort>();
                CodeSize = reader.Read<uint>();
                LocalVarSigTok = new MetadataToken(reader.Read<uint>());
                MethodBody = reader.ReadBytes((int)CodeSize);

                //var end = reader.BaseStream.Position + Size;
                //var data = new List<MethodData>();
                //while (reader.BaseStream.Position < end)
                //{
                //    data.Add(new MethodData(reader));
                //}
                //Data = data.ToArray();
            }
        }
Пример #3
0
        public unsafe void ReadBoolean1()
        {
            byte[] buffer = new byte[] { 1, 0xff, 0, 2 };
            fixed (byte* bufferPtr = buffer)
            {
                var reader = new BlobReader(new MemoryBlock(bufferPtr, buffer.Length));

                Assert.True(reader.ReadBoolean());
                Assert.True(reader.ReadBoolean());
                Assert.False(reader.ReadBoolean());
                Assert.True(reader.ReadBoolean());
            }
        }
Пример #4
0
        public unsafe void Offset()
        {
            byte[] buffer = new byte[] { 0, 1, 0, 2, 5, 6 };

            fixed (byte* bufferPtr = buffer)
            {
                var reader = new BlobReader(bufferPtr, 4);
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Equal(0, reader.Offset);
                Assert.Equal(4, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr);

                reader.Offset = 3;
                Assert.Equal(3, reader.Offset);
                Assert.Equal(1, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 3);

                reader.Offset = 1;
                Assert.Equal(1, reader.Offset);
                Assert.Equal(3, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 1);

                Assert.Equal(1, reader.ReadByte());
                Assert.Equal(2, reader.Offset);
                Assert.Equal(2, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 2);

                reader.Offset = 4;
                Assert.Equal(4, reader.Offset);
                Assert.Equal(0, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 4);

                Assert.Throws<BadImageFormatException>(() => reader.Offset = 5);
                Assert.Equal(4, reader.Offset);
                Assert.Equal(0, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 4);

                Assert.Throws<BadImageFormatException>(() => reader.Offset = -1);
                Assert.Equal(4, reader.Offset);
                Assert.Equal(0, reader.RemainingBytes);
                Assert.True(reader.CurrentPointer == bufferPtr + 4);

                Assert.Throws<BadImageFormatException>(() => reader.Offset = int.MaxValue);
                Assert.Throws<BadImageFormatException>(() => reader.Offset = int.MinValue);
            }
        }
Пример #5
0
        /// <summary>
        /// Creates a new immutable instance of this class.
        /// </summary>
        /// <param name="filePath">A file path the points to a PE file.</param>
        public PortableExecutable(string filePath)
        {
            _data = File.ReadAllBytes(filePath);
            using (var br = new BlobReader(_data, 0, _data.Length))
            {
                br.Read(ref _dosHeader);
                br.Seek((int)_dosHeader.e_lfanew);
                br.Read(ref _signature);
                br.Read(ref _fileHeader);
                if (_fileHeader.OptionalHeaderSize > 0)
                {
                    br.Read(ref _imageType);
                    switch (_imageType)
                    {
                        case ImageType.PE32:
                            br.Read(ref _optionalHeader32);
                            br.Read(ref _dataDirectories, (int)_optionalHeader32.DataDirectoryCount);
                            break;
                        case ImageType.PE64:
                            br.Read(ref _optionalHeader64);
                            br.Read(ref _dataDirectories, (int)_optionalHeader64.DataDirectoryCount);
                            break;
                        default:
                            throw new ArgumentException("UnknownImageType");
                    }
                }
                br.Read(ref _sectionHeaders, _fileHeader.SectionCount);

                if (_dataDirectories[(int)DataDirectoryType.CliHeader].RVA > 0)
                {
                    var cliHeaderOffset = FindDataDirectoryOffset(DataDirectoryType.CliHeader);
                    br.Seek(cliHeaderOffset);
                    br.Read(ref _cliHeader);

                    var metaDataRootOffset = FindRvaOffset(_cliHeader.MetadataRVA);
                    _metadataRoot = new MetadataRoot(new Slice(_data, metaDataRootOffset, (int)_cliHeader.MetadataSize));
                }

                var resourceHeader = _dataDirectories[(int)DataDirectoryType.Resource];
                if (resourceHeader.RVA > 0)
                {
                    var offset = FindDataDirectoryOffset(DataDirectoryType.Resource);
                    br.Seek(offset);
                    _resourceDirectory = new ResourceDirectory(br.ReadSlice((int)resourceHeader.Size), this);
                }
            }
        }
Пример #6
0
        public unsafe void Properties()
        {
            byte[] buffer = new byte[] { 0, 1, 0, 2, 5, 6 };

            fixed (byte* bufferPtr = buffer)
            {
                var reader = new BlobReader(bufferPtr, 4);
                Assert.True(reader.StartPointer == bufferPtr);
                Assert.True(reader.CurrentPointer == bufferPtr);
                Assert.Equal(0, reader.Offset);
                Assert.Equal(4, reader.RemainingBytes);
                Assert.Equal(4, reader.Length);

                Assert.Equal(0, reader.ReadByte());
                Assert.True(reader.StartPointer == bufferPtr);
                Assert.True(reader.CurrentPointer == bufferPtr + 1);
                Assert.Equal(1, reader.Offset);
                Assert.Equal(3, reader.RemainingBytes);
                Assert.Equal(4, reader.Length);

                Assert.Equal(1, reader.ReadInt16());
                Assert.True(reader.StartPointer == bufferPtr);
                Assert.True(reader.CurrentPointer == bufferPtr + 3);
                Assert.Equal(3, reader.Offset);
                Assert.Equal(1, reader.RemainingBytes);
                Assert.Equal(4, reader.Length);

                Assert.Throws<BadImageFormatException>(() => reader.ReadInt16());
                Assert.True(reader.StartPointer == bufferPtr);
                Assert.True(reader.CurrentPointer == bufferPtr + 3);
                Assert.Equal(3, reader.Offset);
                Assert.Equal(1, reader.RemainingBytes);
                Assert.Equal(4, reader.Length);

                Assert.Equal(2, reader.ReadByte());
                Assert.True(reader.StartPointer == bufferPtr);
                Assert.True(reader.CurrentPointer == bufferPtr + 4);
                Assert.Equal(4, reader.Offset);
                Assert.Equal(0, reader.RemainingBytes);
                Assert.Equal(4, reader.Length);
            }
        }
Пример #7
0
 private static CustomModSignature ReadCustomModSignatures(BlobReader br)
 {
     var b = br.TryRead<ElementType>();
     if (b == null)
         return null;
     if (b.Value != ElementType.Cmod_opt && b.Value != ElementType.Cmod_reqd)
     {
         br.Offset(-1);
         return null;
     }
     var cm = new CustomModSignature(b.Value == ElementType.Cmod_reqd, ReadCompressedToken(br));
     cm.Next = ReadCustomModSignatures(br);
     return cm;
 }
Пример #8
0
 private static IEnumerable<CilInstruction> DecodeMethodBody(BlobReader ilReader, MetadataReader metadataReader, CilTypeProvider provider, CilMethodDefinition methodDefinition)
 {
     ilReader.Reset();
     int intOperand;
     ushort shortOperand;
     int ilOffset = 0;
     CilInstruction instruction = null;
     while (ilReader.Offset < ilReader.Length)
     {
         OpCode opCode;
         int expectedSize;
         byte _byte = ilReader.ReadByte();
         /*If the byte read is 0xfe it means is a two byte instruction, 
         so since it is going to read the second byte to get the actual
         instruction it has to check that the offset is still less than the length.*/
         if (_byte == 0xfe && ilReader.Offset < ilReader.Length)
         {
             opCode = CilDecoderHelpers.Instance.twoByteOpCodes[ilReader.ReadByte()];
             expectedSize = 2;
         }
         else
         {
             opCode = CilDecoderHelpers.Instance.oneByteOpCodes[_byte];
             expectedSize = 1;
         }
         switch (opCode.OperandType)
         {
             //The instruction size is the expected size (1 or 2 depending if it is a one or two byte instruction) + the size of the operand.
             case OperandType.InlineField:
                 intOperand = ilReader.ReadInt32();
                 string fieldInfo = GetFieldInformation(metadataReader, intOperand, provider);
                 instruction = new CilStringInstruction(opCode, fieldInfo, intOperand, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.InlineString:
                 intOperand = ilReader.ReadInt32();
                 bool isPrintable;
                 string str = GetArgumentString(metadataReader, intOperand, out isPrintable);
                 instruction = new CilStringInstruction(opCode, str, intOperand, expectedSize + (int)CilInstructionSize.Int32, isPrintable);
                 break;
             case OperandType.InlineMethod:
                 intOperand = ilReader.ReadInt32();
                 string methodCall = SolveMethodName(metadataReader, intOperand, provider);
                 instruction = new CilStringInstruction(opCode, methodCall, intOperand, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.InlineType:
                 intOperand = ilReader.ReadInt32();
                 string type = GetTypeInformation(metadataReader, intOperand, provider);
                 instruction = new CilStringInstruction(opCode, type, intOperand, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.InlineTok:
                 intOperand = ilReader.ReadInt32();
                 string tokenType = GetInlineTokenType(metadataReader, intOperand, provider);
                 instruction = new CilStringInstruction(opCode, tokenType, intOperand, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.InlineI:
                 instruction = new CilInt32Instruction(opCode, ilReader.ReadInt32(), -1, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.InlineI8:
                 instruction = new CilInt64Instruction(opCode, ilReader.ReadInt64(), -1, expectedSize + (int)CilInstructionSize.Int64);
                 break;
             case OperandType.InlineR:
                 instruction = new CilDoubleInstruction(opCode, ilReader.ReadDouble(), -1, expectedSize + (int)CilInstructionSize.Double);
                 break;
             case OperandType.InlineSwitch:
                 instruction = CreateSwitchInstruction(ref ilReader, expectedSize, ilOffset, opCode);
                 break;
             case OperandType.ShortInlineBrTarget:
                 instruction = new CilInt16BranchInstruction(opCode, ilReader.ReadSByte(), ilOffset, expectedSize + (int)CilInstructionSize.Byte);
                 break;
             case OperandType.InlineBrTarget:
                 instruction = new CilBranchInstruction(opCode, ilReader.ReadInt32(), ilOffset, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             case OperandType.ShortInlineI:
                 instruction = new CilByteInstruction(opCode, ilReader.ReadByte(), -1, expectedSize + (int)CilInstructionSize.Byte);
                 break;
             case OperandType.ShortInlineR:
                 instruction = new CilSingleInstruction(opCode, ilReader.ReadSingle(), -1, expectedSize + (int)CilInstructionSize.Single);
                 break;
             case OperandType.InlineNone:
                 instruction = new CilInstructionWithNoValue(opCode, expectedSize);
                 break;
             case OperandType.ShortInlineVar:
                 byte token = ilReader.ReadByte();
                 instruction = new CilInt16VariableInstruction(opCode, GetVariableName(opCode, token, methodDefinition), token, expectedSize + (int)CilInstructionSize.Byte);
                 break;
             case OperandType.InlineVar:
                 shortOperand = ilReader.ReadUInt16();
                 instruction = new CilVariableInstruction(opCode, GetVariableName(opCode, shortOperand, methodDefinition), shortOperand, expectedSize + (int)CilInstructionSize.Int16);
                 break;
             case OperandType.InlineSig:
                 intOperand = ilReader.ReadInt32();
                 instruction = new CilStringInstruction(opCode, GetSignature(metadataReader, intOperand, provider), intOperand, expectedSize + (int)CilInstructionSize.Int32);
                 break;
             default:
                 break;
         }
         ilOffset += instruction.Size;
         yield return instruction;
     }
 }
Пример #9
0
        private ImmutableArray <CustomAttributeTypedArgument <TType> > DecodeFixedArguments(ref BlobReader signatureReader, ref BlobReader valueReader, int count)
        {
            if (count == 0)
            {
                return(ImmutableArray <CustomAttributeTypedArgument <TType> > .Empty);
            }

            var arguments = ImmutableArray.CreateBuilder <CustomAttributeTypedArgument <TType> >(count);

            for (int i = 0; i < count; i++)
            {
                ArgumentTypeInfo info = DecodeFixedArgumentType(ref signatureReader);
                arguments.Add(DecodeArgument(ref valueReader, info));
            }

            return(arguments.MoveToImmutable());
        }
Пример #10
0
        private CustomAttributeTypedArgument <TType> DecodeArgument(ref BlobReader valueReader, ArgumentTypeInfo info)
        {
            if (info.TypeCode == SerializationTypeCode.TaggedObject)
            {
                info = DecodeNamedArgumentType(ref valueReader);
            }

            // PERF_TODO: https://github.com/dotnet/corefx/issues/6533
            //   Cache /reuse common arguments to avoid boxing (small integers, true, false).
            object value;

            switch (info.TypeCode)
            {
            case SerializationTypeCode.Boolean:
                value = valueReader.ReadBoolean();
                break;

            case SerializationTypeCode.Byte:
                value = valueReader.ReadByte();
                break;

            case SerializationTypeCode.Char:
                value = valueReader.ReadChar();
                break;

            case SerializationTypeCode.Double:
                value = valueReader.ReadDouble();
                break;

            case SerializationTypeCode.Int16:
                value = valueReader.ReadInt16();
                break;

            case SerializationTypeCode.Int32:
                value = valueReader.ReadInt32();
                break;

            case SerializationTypeCode.Int64:
                value = valueReader.ReadInt64();
                break;

            case SerializationTypeCode.SByte:
                value = valueReader.ReadSByte();
                break;

            case SerializationTypeCode.Single:
                value = valueReader.ReadSingle();
                break;

            case SerializationTypeCode.UInt16:
                value = valueReader.ReadUInt16();
                break;

            case SerializationTypeCode.UInt32:
                value = valueReader.ReadUInt32();
                break;

            case SerializationTypeCode.UInt64:
                value = valueReader.ReadUInt64();
                break;

            case SerializationTypeCode.String:
                value = valueReader.ReadSerializedString();
                break;

            case SerializationTypeCode.Type:
                string typeName = valueReader.ReadSerializedString();
                value = _provider.GetTypeFromSerializedName(typeName);
                break;

            case SerializationTypeCode.SZArray:
                value = DecodeArrayArgument(ref valueReader, info);
                break;

            default:
                throw new BadImageFormatException();
            }

            return(new CustomAttributeTypedArgument <TType>(info.Type, value));
        }
Пример #11
0
 public EcmaSignatureParser(TypeSystemContext tsc, Func <EntityHandle, NotFoundBehavior, TypeDesc> typeResolver, BlobReader reader, NotFoundBehavior notFoundBehavior)
 {
     _notFoundBehavior = notFoundBehavior;
     _ecmaModule       = null;
     _tsc          = tsc;
     _typeResolver = typeResolver;
     _reader       = reader;
     _indexStack   = null;
     _embeddedSignatureDataList = null;
     _resolutionFailure         = null;
 }
Пример #12
0
 public MethodData(BlobReader reader)
 {
     Flags = (MethodDataFlags)reader.ReadByte();
     Size = reader.ReadByte();
     Data = reader.ReadBytes(Size);
 }
Пример #13
0
        private unsafe static void UncompressLambdaMap(
            ImmutableArray <byte> compressedLambdaMap,
            out int methodOrdinal,
            out ImmutableArray <ClosureDebugInfo> closures,
            out ImmutableArray <LambdaDebugInfo> lambdas)
        {
            methodOrdinal = DebugId.UndefinedOrdinal;
            closures      = default(ImmutableArray <ClosureDebugInfo>);
            lambdas       = default(ImmutableArray <LambdaDebugInfo>);

            if (compressedLambdaMap.IsDefaultOrEmpty)
            {
                return;
            }

            var closuresBuilder = ArrayBuilder <ClosureDebugInfo> .GetInstance();

            var lambdasBuilder = ArrayBuilder <LambdaDebugInfo> .GetInstance();

            fixed(byte *blobPtr = &compressedLambdaMap.ToArray()[0])
            {
                var blobReader = new BlobReader(blobPtr, compressedLambdaMap.Length);

                try
                {
                    // Note: integer operations below can't overflow since compressed integers are in range [0, 0x20000000)

                    // [-1, inf)
                    methodOrdinal = blobReader.ReadCompressedInteger() - 1;

                    int syntaxOffsetBaseline = -blobReader.ReadCompressedInteger();

                    int closureCount = blobReader.ReadCompressedInteger();

                    for (int i = 0; i < closureCount; i++)
                    {
                        int syntaxOffset = blobReader.ReadCompressedInteger();

                        var closureId = new DebugId(closuresBuilder.Count, generation: 0);
                        closuresBuilder.Add(new ClosureDebugInfo(syntaxOffset + syntaxOffsetBaseline, closureId));
                    }

                    while (blobReader.RemainingBytes > 0)
                    {
                        int syntaxOffset   = blobReader.ReadCompressedInteger();
                        int closureOrdinal = blobReader.ReadCompressedInteger() + LambdaDebugInfo.MinClosureOrdinal;

                        if (closureOrdinal >= closureCount)
                        {
                            throw CreateInvalidDataException(compressedLambdaMap, blobReader.Offset);
                        }

                        var lambdaId = new DebugId(lambdasBuilder.Count, generation: 0);
                        lambdasBuilder.Add(new LambdaDebugInfo(syntaxOffset + syntaxOffsetBaseline, lambdaId, closureOrdinal));
                    }
                }
                catch (BadImageFormatException)
                {
                    throw CreateInvalidDataException(compressedLambdaMap, blobReader.Offset);
                }
            }

            closures = closuresBuilder.ToImmutableAndFree();
            lambdas  = lambdasBuilder.ToImmutableAndFree();
        }
Пример #14
0
        private PEExportTable(PEReader peReader)
        {
            Debug.Assert(peReader.PEHeaders is object);
            Debug.Assert(peReader.PEHeaders.PEHeader is object);

            _namedExportRva = new Dictionary <string, int>();

            DirectoryEntry exportTable = peReader.PEHeaders.PEHeader.ExportTableDirectory;

            if ((exportTable.Size == 0) || (exportTable.RelativeVirtualAddress == 0))
            {
                return;
            }

            PEMemoryBlock peImage           = peReader.GetEntireImage();
            BlobReader    exportTableHeader = peImage.GetReader(
                peReader.GetOffset(exportTable.RelativeVirtualAddress),
                exportTable.Size
                );

            if (exportTableHeader.Length == 0)
            {
                return;
            }

            // +0x00: reserved
            exportTableHeader.ReadUInt32();
            // +0x04: TODO: time/date stamp
            exportTableHeader.ReadUInt32();
            // +0x08: major version
            exportTableHeader.ReadUInt16();
            // +0x0A: minor version
            exportTableHeader.ReadUInt16();
            // +0x0C: DLL name RVA
            exportTableHeader.ReadUInt32();
            // +0x10: ordinal base
            int minOrdinal = exportTableHeader.ReadInt32();
            // +0x14: number of entries in the address table
            int addressEntryCount = exportTableHeader.ReadInt32();
            // +0x18: number of name pointers
            int namePointerCount = exportTableHeader.ReadInt32();
            // +0x1C: export address table RVA
            int addressTableRVA = exportTableHeader.ReadInt32();
            // +0x20: name pointer RVA
            int namePointerRVA = exportTableHeader.ReadInt32();
            // +0x24: ordinal table RVA
            int ordinalTableRVA = exportTableHeader.ReadInt32();

            int[]      addressTable       = new int[addressEntryCount];
            BlobReader addressTableReader = peImage.GetReader(
                peReader.GetOffset(addressTableRVA),
                sizeof(int) * addressEntryCount
                );

            for (int entryIndex = 0; entryIndex < addressEntryCount; entryIndex++)
            {
                addressTable[entryIndex] = addressTableReader.ReadInt32();
            }

            ushort[]   ordinalTable       = new ushort[namePointerCount];
            BlobReader ordinalTableReader = peImage.GetReader(
                peReader.GetOffset(ordinalTableRVA),
                sizeof(ushort) * namePointerCount
                );

            for (int entryIndex = 0; entryIndex < namePointerCount; entryIndex++)
            {
                ushort ordinalIndex = ordinalTableReader.ReadUInt16();
                ordinalTable[entryIndex] = ordinalIndex;
            }

            BlobReader namePointerReader = peImage.GetReader(
                peReader.GetOffset(namePointerRVA),
                sizeof(int) * namePointerCount
                );

            for (int entryIndex = 0; entryIndex < namePointerCount; entryIndex++)
            {
                int nameRVA = namePointerReader.ReadInt32();
                if (nameRVA != 0)
                {
                    int        nameOffset = peReader.GetOffset(nameRVA);
                    BlobReader nameReader = peImage.GetReader(
                        nameOffset,
                        peImage.Length - nameOffset
                        );
                    StringBuilder nameBuilder = new StringBuilder();
                    for (byte ascii; (ascii = nameReader.ReadByte()) != 0;)
                    {
                        nameBuilder.Append((char)ascii);
                    }
                    _namedExportRva.Add(
                        nameBuilder.ToString(),
                        addressTable[ordinalTable[entryIndex]]
                        );
                }
            }
        }
Пример #15
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);
            ReadyToRunCodegenNodeFactory r2rFactory = ((ReadyToRunCodegenNodeFactory)factory);

            BlobReader reader = _module.PEReader.GetEntireImage().GetReader();

            reader.Offset = _module.PEReader.PEHeaders.CorHeaderStartOffset;

            // Header Size
            int headerSize = reader.ReadInt32();

            builder.EmitInt(headerSize);

            // Runtime major, minor version
            builder.EmitUShort(reader.ReadUInt16());
            builder.EmitUShort(reader.ReadUInt16());

            // Metadata Directory
            ReadDirectoryEntry(ref reader);
            var metadataBlob = r2rFactory.CopiedMetadataBlob(_module);

            builder.EmitReloc(metadataBlob, RelocType.IMAGE_REL_BASED_ADDR32NB);
            builder.EmitInt(metadataBlob.Size);

            // Flags
            builder.EmitUInt((uint)(((CorFlags)reader.ReadUInt32() & ~CorFlags.ILOnly) | CorFlags.ILLibrary));

            // Entrypoint
            builder.EmitInt(reader.ReadInt32());

            // Resources Directory
            if (ReadDirectoryEntry(ref reader).Size > 0)
            {
                var managedResources = r2rFactory.CopiedManagedResources(_module);
                builder.EmitReloc(managedResources, RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitInt(managedResources.Size);
            }
            else
            {
                WriteEmptyDirectoryEntry(ref builder);
            }

            // Strong Name Signature Directory
            if (ReadDirectoryEntry(ref reader).Size > 0)
            {
                var strongNameSignature = r2rFactory.CopiedStrongNameSignature(_module);
                builder.EmitReloc(strongNameSignature, RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitInt(strongNameSignature.Size);
            }
            else
            {
                WriteEmptyDirectoryEntry(ref builder);
            }


            // Code Manager Table Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // VTable Fixups Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // Export Address Table Jumps Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // Managed Native (ReadyToRun) Header Directory
            ReadDirectoryEntry(ref reader);
            builder.EmitReloc(r2rFactory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB);
            builder.EmitInt(r2rFactory.Header.GetData(factory, relocsOnly).Data.Length);

            // Did we fully read the header?
            Debug.Assert(reader.Offset - headerSize == _module.PEReader.PEHeaders.CorHeaderStartOffset);
            Debug.Assert(builder.CountBytes == headerSize);
            Debug.Assert(headerSize == Size);

            return(builder.ToObjectData());
        }
Пример #16
0
        private object ReadAndTranslateValue(ref BlobReader sigReader, SignatureTypeCode typeCode, out bool isEnumTypeCode)
        {
            switch (typeCode)
            {
            case SignatureTypeCode.Boolean:
                isEnumTypeCode = true;
                return((short)(sigReader.ReadBoolean() ? 1 : 0));

            case SignatureTypeCode.Char:
                isEnumTypeCode = true;
                return((ushort)sigReader.ReadChar());

            case SignatureTypeCode.SByte:
                isEnumTypeCode = true;
                return((short)sigReader.ReadSByte());

            case SignatureTypeCode.Byte:
                isEnumTypeCode = true;
                return((short)sigReader.ReadByte());

            case SignatureTypeCode.Int16:
                isEnumTypeCode = true;
                return(sigReader.ReadInt16());

            case SignatureTypeCode.UInt16:
                isEnumTypeCode = true;
                return(sigReader.ReadUInt16());

            case SignatureTypeCode.Int32:
                isEnumTypeCode = true;
                return(sigReader.ReadInt32());

            case SignatureTypeCode.UInt32:
                isEnumTypeCode = true;
                return(sigReader.ReadUInt32());

            case SignatureTypeCode.Int64:
                isEnumTypeCode = true;
                return(sigReader.ReadInt64());

            case SignatureTypeCode.UInt64:
                isEnumTypeCode = true;
                return(sigReader.ReadUInt64());

            case SignatureTypeCode.Single:
                isEnumTypeCode = false;
                return(sigReader.ReadSingle());

            case SignatureTypeCode.Double:
                isEnumTypeCode = false;
                return(sigReader.ReadDouble());

            case SignatureTypeCode.String:
                isEnumTypeCode = false;

                if (sigReader.RemainingBytes == 1)
                {
                    if (sigReader.ReadByte() != 0xff)
                    {
                        throw new BadImageFormatException();
                    }

                    return(s_nullReferenceValue);
                }

                if (sigReader.RemainingBytes % 2 != 0)
                {
                    throw new BadImageFormatException();
                }

                return(sigReader.ReadUTF16(sigReader.RemainingBytes));

            case SignatureTypeCode.Object:
                // null reference
                isEnumTypeCode = false;
                return(s_nullReferenceValue);

            default:
                throw new BadImageFormatException();
            }
        }
Пример #17
0
        private TType DecodeType(ref BlobReader blobReader, int typeCode)
        {
            TType elementType;
            int   index;

            switch (typeCode)
            {
            case (int)SignatureTypeCode.Boolean:
            case (int)SignatureTypeCode.Char:
            case (int)SignatureTypeCode.SByte:
            case (int)SignatureTypeCode.Byte:
            case (int)SignatureTypeCode.Int16:
            case (int)SignatureTypeCode.UInt16:
            case (int)SignatureTypeCode.Int32:
            case (int)SignatureTypeCode.UInt32:
            case (int)SignatureTypeCode.Int64:
            case (int)SignatureTypeCode.UInt64:
            case (int)SignatureTypeCode.Single:
            case (int)SignatureTypeCode.Double:
            case (int)SignatureTypeCode.IntPtr:
            case (int)SignatureTypeCode.UIntPtr:
            case (int)SignatureTypeCode.Object:
            case (int)SignatureTypeCode.String:
            case (int)SignatureTypeCode.Void:
            case (int)SignatureTypeCode.TypedReference:
                return(_provider.GetPrimitiveType((PrimitiveTypeCode)typeCode));

            case (int)SignatureTypeCode.Pointer:
                elementType = DecodeType(ref blobReader);
                return(_provider.GetPointerType(elementType));

            case (int)SignatureTypeCode.ByReference:
                elementType = DecodeType(ref blobReader);
                return(_provider.GetByReferenceType(elementType));

            case (int)SignatureTypeCode.Pinned:
                elementType = DecodeType(ref blobReader);
                return(_provider.GetPinnedType(elementType));

            case (int)SignatureTypeCode.SZArray:
                elementType = DecodeType(ref blobReader);
                return(_provider.GetSZArrayType(elementType));

            case (int)SignatureTypeCode.FunctionPointer:
                MethodSignature <TType> methodSignature = DecodeMethodSignature(ref blobReader);
                return(_provider.GetFunctionPointerType(methodSignature));

            case (int)SignatureTypeCode.Array:
                return(DecodeArrayType(ref blobReader));

            case (int)SignatureTypeCode.RequiredModifier:
                return(DecodeModifiedType(ref blobReader, isRequired: true));

            case (int)SignatureTypeCode.OptionalModifier:
                return(DecodeModifiedType(ref blobReader, isRequired: false));

            case (int)SignatureTypeCode.GenericTypeInstance:
                return(DecodeGenericTypeInstance(ref blobReader));

            case (int)SignatureTypeCode.GenericTypeParameter:
                index = blobReader.ReadCompressedInteger();
                return(_provider.GetGenericTypeParameter(index));

            case (int)SignatureTypeCode.GenericMethodParameter:
                index = blobReader.ReadCompressedInteger();
                return(_provider.GetGenericMethodParameter(index));

            case (int)SignatureTypeHandleCode.Class:
            case (int)SignatureTypeHandleCode.ValueType:
                return(DecodeTypeDefOrRef(ref blobReader, (SignatureTypeHandleCode)typeCode));

            default:
                throw new BadImageFormatException(SR.Format(SR.UnexpectedSignatureTypeCode, typeCode));
            }
        }
Пример #18
0
 /// <summary>
 /// Decodes a type embedded in a signature and advances the reader past the type.
 /// </summary>
 /// <param name="blobReader">The blob reader positioned at the leading SignatureTypeCode</param>
 /// <returns>The decoded type.</returns>
 /// <exception cref="System.BadImageFormatException">The reader was not positioned at a valid signature type.</exception>
 public TType DecodeType(ref BlobReader blobReader)
 {
     return(DecodeType(ref blobReader, blobReader.ReadCompressedInteger()));
 }
Пример #19
0
 private static ParamSignature ReadParams(BlobReader br, uint count)
 {
     var ps = new ParamSignature();
     ps.FirstMod = ReadCustomModSignatures(br);
     ps.Type = ParseTypeSignature(br);
     if (count > 1)
         ps.Next = ReadParams(br, count - 1);
     return ps;
 }
Пример #20
0
        private Object ResolveMemberReference(MemberReferenceHandle handle)
        {
            MemberReference memberReference = _metadataReader.GetMemberReference(handle);

            Object parent = GetObject(memberReference.Parent, NotFoundBehavior.ReturnResolutionFailure);

            if (parent is ResolutionFailure)
            {
                return(parent);
            }

            TypeDesc parentTypeDesc = parent as TypeDesc;

            if (parentTypeDesc != null)
            {
                BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature);

                EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure);

                string name = _metadataReader.GetString(memberReference.Name);

                if (parser.IsFieldSignature)
                {
                    FieldDesc field = parentTypeDesc.GetField(name);
                    if (field != null)
                    {
                        return(field);
                    }

                    return(ResolutionFailure.GetMissingFieldFailure(parentTypeDesc, name));
                }
                else
                {
                    MethodSignature sig = parser.ParseMethodSignature();
                    if (sig == null)
                    {
                        return(parser.ResolutionFailure);
                    }
                    TypeDesc      typeDescToInspect = parentTypeDesc;
                    Instantiation substitution      = default(Instantiation);

                    // Try to resolve the name and signature in the current type, or any of the base types.
                    do
                    {
                        MethodDesc method = typeDescToInspect.GetMethod(name, sig, substitution);
                        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);
                        }
                        var baseType = typeDescToInspect.BaseType;
                        if (baseType != null)
                        {
                            if (!baseType.HasInstantiation)
                            {
                                substitution = default(Instantiation);
                            }
                            else
                            {
                                // If the base type is generic, any signature match for methods on the base type with the generic details from
                                // the deriving type
                                Instantiation newSubstitution = typeDescToInspect.GetTypeDefinition().BaseType.Instantiation;
                                if (!substitution.IsNull)
                                {
                                    TypeDesc[] newSubstitutionTypes = new TypeDesc[newSubstitution.Length];
                                    for (int i = 0; i < newSubstitution.Length; i++)
                                    {
                                        newSubstitutionTypes[i] = newSubstitution[i].InstantiateSignature(substitution, default(Instantiation));
                                    }
                                    newSubstitution = new Instantiation(newSubstitutionTypes);
                                }
                                substitution = newSubstitution;
                            }
                        }
                        typeDescToInspect = baseType;
                    } while (typeDescToInspect != null);

                    return(ResolutionFailure.GetMissingMethodFailure(parentTypeDesc, name, sig));
                }
            }
            else if (parent is MethodDesc)
            {
                ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramVararg, (MethodDesc)parent);
            }
            else if (parent is ModuleDesc)
            {
                throw new NotImplementedException("MemberRef to a global function or variable.");
            }

            ThrowHelper.ThrowBadImageFormatException();
            return(null);
        }
Пример #21
0
 public abstract void DecodeLocalConstant(ref BlobReader reader, out TTypeSymbol type, out ConstantValue value);
Пример #22
0
 internal static CilType DecodeType(ref BlobReader reader, CilTypeProvider provider)
 {
     return NewDecoder(provider).DecodeType(ref reader);
 }
Пример #23
0
 public bool TryGetMetadataCompilationOptionsBlobReader(out BlobReader reader)
 {
     return(TryGetCustomDebugInformationBlobReader(CompilationOptionsGuid, out reader));
 }
Пример #24
0
        protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodDefinition, ref BlobReader blob)
        {
            int offset = blob.Offset;

            if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
            {
                var sp = sequencePoints[nextSequencePointIndex];
                if (sp.Offset <= offset)
                {
                    output.Write("// sequence point: ");
                    if (sp.Offset != offset)
                    {
                        output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!");
                    }
                    if (sp.IsHidden)
                    {
                        output.WriteLine("hidden");
                    }
                    else
                    {
                        output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}");
                    }
                    nextSequencePointIndex++;
                }
            }
            ILOpCode opCode = ILParser.DecodeOpCode(ref blob);

            output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
            output.Write(": ");
            if (opCode.IsDefined())
            {
                WriteOpCode(opCode);
                switch (opCode.GetOperandType())
                {
                case OperandType.BrTarget:
                case OperandType.ShortBrTarget:
                    output.Write(' ');
                    int targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode);
                    output.WriteLocalReference($"IL_{targetOffset:x4}", targetOffset);
                    break;

                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Type:
                    output.Write(' ');
                    int          metadataToken = blob.ReadInt32();
                    EntityHandle?handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Tok:
                    output.Write(' ');
                    metadataToken = blob.ReadInt32();
                    handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    switch (handle?.Kind)
                    {
                    case HandleKind.MemberReference:
                        switch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind())
                        {
                        case MemberReferenceKind.Method:
                            output.Write("method ");
                            break;

                        case MemberReferenceKind.Field:
                            output.Write("field ");
                            break;
                        }
                        break;

                    case HandleKind.FieldDefinition:
                        output.Write("field ");
                        break;

                    case HandleKind.MethodDefinition:
                        output.Write("method ");
                        break;
                    }
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.ShortI:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSByte());
                    break;

                case OperandType.I:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt32());
                    break;

                case OperandType.I8:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt64());
                    break;

                case OperandType.ShortR:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSingle());
                    break;

                case OperandType.R:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadDouble());
                    break;

                case OperandType.String:
                    metadataToken = blob.ReadInt32();
                    output.Write(' ');
                    UserStringHandle?userString;
                    string           text;
                    try {
                        userString = MetadataTokens.UserStringHandle(metadataToken);
                        text       = metadata.GetUserString(userString.Value);
                    } catch (BadImageFormatException) {
                        userString = null;
                        text       = null;
                    }
                    if (userString != null)
                    {
                        DisassemblerHelpers.WriteOperand(output, text);
                    }
                    WriteMetadataToken(userString, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Switch:
                    int[] targets = ILParser.DecodeSwitchTargets(ref blob);
                    output.Write(" (");
                    for (int i = 0; i < targets.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Write(", ");
                        }
                        output.WriteLocalReference($"IL_{targets[i]:x4}", targets[i]);
                    }
                    output.Write(")");
                    break;

                case OperandType.Variable:
                    output.Write(' ');
                    int index = blob.ReadUInt16();
                    if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;

                case OperandType.ShortVariable:
                    output.Write(' ');
                    index = blob.ReadByte();
                    if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;
                }
            }
            else
            {
                ushort opCodeValue = (ushort)opCode;
                if (opCodeValue > 0xFF)
                {
                    // split 16-bit value into two emitbyte directives
                    output.WriteLine($".emitbyte 0x{(byte)(opCodeValue >> 8):x}");
                    // add label
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true);
                    output.Write(": ");
                    output.Write($".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}");
                }
                else
                {
                    output.Write($".emitbyte 0x{(byte)opCodeValue:x}");
                }
            }
            output.WriteLine();
        }
Пример #25
0
        // Mimic what at least one version of at least one obfuscator has done to use the undocumented/non-standard extra-data flag.
        // If setFlag is false, do everything but setting the flag.
        private static unsafe byte[] ObfuscateWithExtraData(byte[] unobfuscated, bool setFlag = true)
        {
            int offsetToMetadata;
            int offsetToModuleTable;
            int offsetToMetadataSize;
            int tableStreamIndex = -1;
            StreamHeaderInfo[] streamHeaders;

            fixed (byte* ptr = unobfuscated)
            {
                using (var peReader = new PEReader(ptr, unobfuscated.Length))
                {
                    PEMemoryBlock metadata = peReader.GetMetadata();
                    offsetToMetadata = peReader.PEHeaders.MetadataStartOffset;
                    offsetToMetadataSize = peReader.PEHeaders.CorHeaderStartOffset + 12;
                    offsetToModuleTable = offsetToMetadata + peReader.GetMetadataReader().GetTableMetadataOffset(TableIndex.Module);

                    // skip root header
                    BlobReader blobReader = new BlobReader(metadata.Pointer, metadata.Length);
                    blobReader.ReadUInt32(); // signature
                    blobReader.ReadUInt16(); // major version
                    blobReader.ReadUInt16(); // minor version
                    blobReader.ReadUInt32(); // reserved
                    int versionStringSize = blobReader.ReadInt32();
                    blobReader.SkipBytes(versionStringSize);

                    // read stream headers to collect offsets and sizes to adjust later
                    blobReader.ReadUInt16(); // reserved
                    int streamCount = blobReader.ReadInt16();
                    streamHeaders = new StreamHeaderInfo[streamCount];

                    for (int i = 0; i < streamCount; i++)
                    {
                        streamHeaders[i].OffsetToOffset = offsetToMetadata + blobReader.Offset;
                        streamHeaders[i].Offset = blobReader.ReadInt32();
                        streamHeaders[i].OffsetToSize = offsetToMetadata + blobReader.Offset;
                        streamHeaders[i].Size = blobReader.ReadInt32();

                        string name = blobReader.ReadUtf8NullTerminated();
                        if (name == "#~")
                        {
                            tableStreamIndex = i;
                        }

                        blobReader.Align(4);
                    }
                }
            }

            const int sizeOfExtraData = 4;
            int offsetToTableStream = offsetToMetadata + streamHeaders[tableStreamIndex].Offset;
            int offsetToHeapSizeFlags = offsetToTableStream + 6;

            // copy unobfuscated to obfuscated, leaving room for 4 bytes of data right before the module table.
            byte[] obfuscated = new byte[unobfuscated.Length + sizeOfExtraData];
            Array.Copy(unobfuscated, 0, obfuscated, 0, offsetToModuleTable);
            Array.Copy(unobfuscated, offsetToModuleTable, obfuscated, offsetToModuleTable + sizeOfExtraData, unobfuscated.Length - offsetToModuleTable);

            fixed (byte* ptr = obfuscated)
            {
                // increase size of metadata
                *(int*)(ptr + offsetToMetadataSize) += sizeOfExtraData;

                // increase size of table stream
                *(int*)(ptr + streamHeaders[tableStreamIndex].OffsetToSize) += sizeOfExtraData;

                // adjust offset of any streams that follow it
                for (int i = 0; i < streamHeaders.Length; i++)
                    if (streamHeaders[i].Offset > streamHeaders[tableStreamIndex].Offset)
                        *(int*)(ptr + streamHeaders[i].OffsetToOffset) += sizeOfExtraData;
            }

            // write non-zero "extra data" to make sure so that our assertion of leading Module.Generation == 0
            // cannot succeed if extra data is interpreted as the start of the module table.
            for (int i = 0; i < sizeOfExtraData; i++)
            {
                obfuscated[offsetToModuleTable + i] = 0xCC;
            }

            if (setFlag)
            {
                // set the non-standard ExtraData flag indicating that these 4 bytes are present
                obfuscated[offsetToHeapSizeFlags] |= (byte)HeapSizes.ExtraData;
            }

            return obfuscated;
        }
        internal unsafe InternalManifestResourceInfo GetInternalManifestResourceInfo(string resourceName)
        {
            MetadataReader reader = Reader;

            InternalManifestResourceInfo     result            = new InternalManifestResourceInfo();
            ManifestResourceHandleCollection manifestResources = reader.ManifestResources;

            foreach (ManifestResourceHandle resourceHandle in manifestResources)
            {
                ManifestResource resource = resourceHandle.GetManifestResource(reader);
                if (resource.Name.Equals(resourceName, reader))
                {
                    result.Found = true;
                    if (resource.Implementation.IsNil)
                    {
                        checked
                        {
                            // Embedded data resource
                            result.ResourceLocation = ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile;
                            PEReader pe = _guardedPEReader.PEReader;

                            PEMemoryBlock resourceDirectory = pe.GetSectionData(pe.PEHeaders.CorHeader.ResourcesDirectory.RelativeVirtualAddress);
                            BlobReader    blobReader        = resourceDirectory.GetReader((int)resource.Offset, resourceDirectory.Length - (int)resource.Offset);
                            uint          length            = blobReader.ReadUInt32();
                            result.PointerToResource = blobReader.CurrentPointer;

                            // Length check the size of the resource to ensure it fits in the PE file section, note, this is only safe as its in a checked region
                            if (length + sizeof(Int32) > blobReader.Length)
                            {
                                throw new BadImageFormatException();
                            }
                            result.SizeOfResource = length;
                        }
                    }
                    else
                    {
                        if (resource.Implementation.Kind == HandleKind.AssemblyFile)
                        {
                            // Get file name
                            result.ResourceLocation = default;
                            AssemblyFile file = ((AssemblyFileHandle)resource.Implementation).GetAssemblyFile(reader);
                            result.FileName = file.Name.GetString(reader);
                            if (file.ContainsMetadata)
                            {
                                EcmaModule module = (EcmaModule)Assembly.GetModule(result.FileName);
                                if (module == null)
                                {
                                    throw new BadImageFormatException(SR.Format(SR.ManifestResourceInfoReferencedBadModule, result.FileName));
                                }
                                result = module.GetInternalManifestResourceInfo(resourceName);
                            }
                        }
                        else if (resource.Implementation.Kind == HandleKind.AssemblyReference)
                        {
                            // Resolve assembly reference
                            result.ResourceLocation = ResourceLocation.ContainedInAnotherAssembly;
                            RoAssemblyName destinationAssemblyName = ((AssemblyReferenceHandle)resource.Implementation).ToRoAssemblyName(reader);
                            result.ReferencedAssembly = Loader.ResolveAssembly(destinationAssemblyName);
                        }
                    }
                }
            }

            return(result);
        }
Пример #27
0
 /// <exception cref="BadImageFormatException"></exception>
 /// <exception cref="UnsupportedSignatureContent"></exception>
 public override void DecodeLocalConstant(ref BlobReader reader, out TypeSymbol type, out ConstantValue value)
 {
     _metadataDecoder.DecodeLocalConstantBlobOrThrow(ref reader, out type, out value);
 }
Пример #28
0
        public unsafe void ReadFromMemoryReader()
        {
            byte[] buffer = new byte[4] {
                0, 1, 0, 2
            };
            fixed(byte *bufferPtr = buffer)
            {
                var reader = new BlobReader(new MemoryBlock(bufferPtr, buffer.Length));

                Assert.Equal(0, reader.Offset);
                Assert.Throws <BadImageFormatException>(() => reader.ReadUInt64());
                Assert.Equal(0, reader.Offset);

                reader.Offset = 1;
                Assert.Throws <BadImageFormatException>(() => reader.ReadDouble());
                Assert.Equal(1, reader.Offset);

                reader.Offset = 2;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUInt32());
                Assert.Equal((ushort)0x0200, reader.ReadUInt16());
                Assert.Equal(4, reader.Offset);

                reader.Offset = 2;
                Assert.Throws <BadImageFormatException>(() => reader.ReadSingle());
                Assert.Equal(2, reader.Offset);

                reader.Offset = 0;
                Assert.Equal(9.404242E-38F, reader.ReadSingle());
                Assert.Equal(4, reader.Offset);

                reader.Offset = 3;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUInt16());
                Assert.Equal((byte)0x02, reader.ReadByte());
                Assert.Equal(4, reader.Offset);

                reader.Offset = 0;
                Assert.Equal("\u0000\u0001\u0000\u0002", reader.ReadUTF8(4));
                Assert.Equal(4, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUTF8(5));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUTF8(-1));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Equal("\u0100\u0200", reader.ReadUTF16(4));
                Assert.Equal(4, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUTF16(5));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUTF16(-1));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUTF16(6));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Equal(buffer, reader.ReadBytes(4));
                Assert.Equal(4, reader.Offset);

                reader.Offset = 0;
                Assert.Same(string.Empty, reader.ReadUtf8NullTerminated());
                Assert.Equal(1, reader.Offset);

                reader.Offset = 1;
                Assert.Equal("\u0001", reader.ReadUtf8NullTerminated());
                Assert.Equal(3, reader.Offset);

                reader.Offset = 3;
                Assert.Equal("\u0002", reader.ReadUtf8NullTerminated());
                Assert.Equal(4, reader.Offset);

                reader.Offset = 0;
                Assert.Same(string.Empty, reader.ReadUtf8NullTerminated());
                Assert.Equal(1, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadBytes(5));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.ReadBytes(int.MinValue));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.GetMemoryBlockAt(-1, 1));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Throws <BadImageFormatException>(() => reader.GetMemoryBlockAt(1, -1));
                Assert.Equal(0, reader.Offset);

                reader.Offset = 0;
                Assert.Equal(3, reader.GetMemoryBlockAt(1, 3).Length);
                Assert.Equal(0, reader.Offset);

                reader.Offset = 3;
                reader.ReadByte();
                Assert.Equal(4, reader.Offset);

                reader.Offset = 4;
                Assert.Equal(0, reader.ReadBytes(0).Length);

                reader.Offset = 4;
                int value;

                Assert.False(reader.TryReadCompressedInteger(out value));
                Assert.Equal(BlobReader.InvalidCompressedInteger, value);

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadCompressedInteger());

                reader.Offset = 4;
                Assert.Equal(SerializationTypeCode.Invalid, reader.ReadSerializationTypeCode());

                reader.Offset = 4;
                Assert.Equal(SignatureTypeCode.Invalid, reader.ReadSignatureTypeCode());

                reader.Offset = 4;
                Assert.Equal(default(EntityHandle), reader.ReadTypeHandle());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadBoolean());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadByte());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadSByte());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUInt32());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadInt32());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadUInt64());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadInt64());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadSingle());

                reader.Offset = 4;
                Assert.Throws <BadImageFormatException>(() => reader.ReadDouble());

                reader.Offset = 4;
            }

            byte[] buffer2 = new byte[8] {
                1, 2, 3, 4, 5, 6, 7, 8
            };
            fixed(byte *bufferPtr2 = buffer2)
            {
                var reader = new BlobReader(new MemoryBlock(bufferPtr2, buffer2.Length));

                Assert.Equal(0, reader.Offset);
                Assert.Equal(0x0807060504030201UL, reader.ReadUInt64());
                Assert.Equal(8, reader.Offset);

                reader.Reset();
                Assert.Equal(0, reader.Offset);
                Assert.Equal(0x0807060504030201L, reader.ReadInt64());

                reader.Reset();
                Assert.Equal(0, reader.Offset);
                Assert.Equal(BitConverter.Int64BitsToDouble(0x0807060504030201L), reader.ReadDouble());
            }
        }
Пример #29
0
        private ImmutableArray <CustomAttributeTypedArgument <TType> >?DecodeArrayArgument(ref BlobReader blobReader, ArgumentTypeInfo info)
        {
            int count = blobReader.ReadInt32();

            if (count == -1)
            {
                return(null);
            }

            if (count == 0)
            {
                return(ImmutableArray <CustomAttributeTypedArgument <TType> > .Empty);
            }

            if (count < 0)
            {
                throw new BadImageFormatException();
            }

            var elementInfo = new ArgumentTypeInfo
            {
                Type     = info.ElementType,
                TypeCode = info.ElementTypeCode,
            };

            var array = ImmutableArray.CreateBuilder <CustomAttributeTypedArgument <TType> >(count);

            for (int i = 0; i < count; i++)
            {
                array.Add(DecodeArgument(ref blobReader, elementInfo));
            }

            return(array.MoveToImmutable());
        }
 public ArrayShapeSignature(BlobReader blobReader)
 {
     _reader = blobReader;
 }
Пример #31
0
        private ImmutableArray <CustomAttributeNamedArgument <TType> > DecodeNamedArguments(ref BlobReader valueReader)
        {
            int count = valueReader.ReadUInt16();

            if (count == 0)
            {
                return(ImmutableArray <CustomAttributeNamedArgument <TType> > .Empty);
            }

            var arguments = ImmutableArray.CreateBuilder <CustomAttributeNamedArgument <TType> >(count);

            for (int i = 0; i < count; i++)
            {
                CustomAttributeNamedArgumentKind kind = (CustomAttributeNamedArgumentKind)valueReader.ReadSerializationTypeCode();
                if (kind != CustomAttributeNamedArgumentKind.Field && kind != CustomAttributeNamedArgumentKind.Property)
                {
                    throw new BadImageFormatException();
                }

                ArgumentTypeInfo info = DecodeNamedArgumentType(ref valueReader);
                string           name = valueReader.ReadSerializedString();
                CustomAttributeTypedArgument <TType> argument = DecodeArgument(ref valueReader, info);
                arguments.Add(new CustomAttributeNamedArgument <TType>(name, kind, argument.Type, argument.Value));
            }

            return(arguments.MoveToImmutable());
        }
Пример #32
0
        public static object ConstantValueAsObject(ConstantHandle constantHandle, MetadataReader metadataReader)
        {
            if (constantHandle.IsNil)
            {
                throw new BadImageFormatException();
            }

            Constant constantValue = metadataReader.GetConstant(constantHandle);

            if (constantValue.Value.IsNil)
            {
                throw new BadImageFormatException();
            }

            BlobReader reader = metadataReader.GetBlobReader(constantValue.Value);

            switch (constantValue.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(reader.ReadBoolean());

            case ConstantTypeCode.Char:
                return(reader.ReadChar());

            case ConstantTypeCode.SByte:
                return(reader.ReadSByte());

            case ConstantTypeCode.Int16:
                return(reader.ReadInt16());

            case ConstantTypeCode.Int32:
                return(reader.ReadInt32());

            case ConstantTypeCode.Int64:
                return(reader.ReadInt64());

            case ConstantTypeCode.Byte:
                return(reader.ReadByte());

            case ConstantTypeCode.UInt16:
                return(reader.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return(reader.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return(reader.ReadUInt64());

            case ConstantTypeCode.Single:
                return(reader.ReadSingle());

            case ConstantTypeCode.Double:
                return(reader.ReadDouble());

            case ConstantTypeCode.String:
                return(reader.ReadUTF16(reader.Length));

            case ConstantTypeCode.NullReference:
                // Partition II section 22.9:
                // The encoding of Type for the nullref value is ELEMENT_TYPE_CLASS with a Value of a 4-byte zero.
                // Unlike uses of ELEMENT_TYPE_CLASS in signatures, this one is not followed by a type token.
                if (reader.ReadUInt32() == 0)
                {
                    return(null);
                }

                break;
            }

            throw new BadImageFormatException();
        }
Пример #33
0
 private static CilInstruction CreateSwitchInstruction(ref BlobReader ilReader, int expectedSize, int ilOffset, OpCode opCode)
 {
     uint caseNumber = ilReader.ReadUInt32();
     int[] jumps = new int[caseNumber];
     for (int i = 0; i < caseNumber; i++)
     {
         jumps[i] = ilReader.ReadInt32();
     }
     int size = (int)CilInstructionSize.Int32 + expectedSize;
     size += (int)caseNumber * (int)CilInstructionSize.Int32;
     return new CilSwitchInstruction(opCode, ilOffset, jumps, (int)caseNumber, caseNumber, size);
 }
Пример #34
0
        /// <summary>
        /// Decodes a method specification signature blob.
        /// </summary>
        /// <param name="handle">The handle to the method specification signature blob. See <see cref="MethodSpecification.Signature"/>.</param>
        /// <param name="provider">The type provider.</param>
        /// <returns>The types used to instantiate a generic method via a method specification.</returns>
        /// <exception cref="System.BadImageFormatException">The method specification signature is invalid.</exception>
        public static ImmutableArray <TType> DecodeMethodSpecificationSignature <TType>(BlobHandle handle, ISignatureTypeProvider <TType> provider)
        {
            BlobReader blobReader = provider.Reader.GetBlobReader(handle);

            return(DecodeMethodSpecificationSignature(ref blobReader, provider));
        }
Пример #35
0
 private static MethodSignature ReadMethodSignature(BlobReader br)
 {
     return null;
 }
Пример #36
0
        /// <summary>
        /// Decodes a method specification signature blob.
        /// </summary>
        /// <param name="blobReader">A BlobReader positioned at a valid method specification signature.</param>
        /// <param name="provider">The type provider.</param>
        /// <returns>The types used to instantiate a generic method via the method specification.</returns>
        public static ImmutableArray <TType> DecodeMethodSpecificationSignature <TType>(ref BlobReader blobReader, ISignatureTypeProvider <TType> provider)
        {
            SignatureHeader header = blobReader.ReadSignatureHeader();

            if (header.Kind != SignatureKind.MethodSpecification)
            {
                throw new BadImageFormatException();
            }

            return(DecodeTypes(ref blobReader, provider));
        }
Пример #37
0
 private static ReturnTypeSignature ReadReturnTypeSignature(BlobReader br)
 {
     var rt = new ReturnTypeSignature();
     rt.FirstMod = ReadCustomModSignatures(br);
     rt.Type = ParseTypeSignature(br);
     return rt;
 }
Пример #38
0
        /// <summary>
        /// Decodes a field signature.
        /// </summary>
        /// <param name="handle">The field signature handle.</param>
        /// <param name="provider">The type provider.</param>
        /// <returns>The decoded field type.</returns>
        /// <exception cref="System.BadImageFormatException">The field signature is invalid.</exception>
        public static TType DecodeFieldSignature <TType>(BlobHandle handle, ISignatureTypeProvider <TType> provider)
        {
            BlobReader blobReader = provider.Reader.GetBlobReader(handle);

            return(DecodeFieldSignature(ref blobReader, provider));
        }
Пример #39
0
 private static MetadataToken ReadCompressedToken(BlobReader br)
 {
     var val = br.ReadCompressedUInt32();
     var tag = (val & 0x00000003);
     var index = (val & 0xFFFFFFFC) >> 2;
     return new MetadataToken((tag << 24) | index);
 }
Пример #40
0
        // Decodes a type definition, reference, or specification from the type handle at the given blob reader's current position.
        private static TType DecodeTypeHandle <TType>(ref BlobReader blobReader, ISignatureTypeProvider <TType> provider, bool?isValueType)
        {
            Handle handle = blobReader.ReadTypeHandle();

            return(DecodeType(handle, provider, isValueType));
        }
Пример #41
0
        public unsafe void IndexOf()
        {
            byte[] buffer = new byte[]
            {
                0xF0, 0x90, 0x8D,
            };

            fixed (byte* bufferPtr = buffer)
            {
                var reader = new BlobReader(bufferPtr, buffer.Length);

                Assert.Equal(0, reader.IndexOf(0xF0));
                Assert.Equal(1, reader.IndexOf(0x90));
                Assert.Equal(2, reader.IndexOf(0x8D));
                Assert.Equal(-1, reader.IndexOf(0x8C));
                Assert.Equal(-1, reader.IndexOf(0));
                Assert.Equal(-1, reader.IndexOf(0xff));

                reader.ReadByte();
                Assert.Equal(-1, reader.IndexOf(0xF0));
                Assert.Equal(0, reader.IndexOf(0x90));
                Assert.Equal(1, reader.IndexOf(0x8D));

                reader.ReadByte();
                Assert.Equal(-1, reader.IndexOf(0xF0));
                Assert.Equal(-1, reader.IndexOf(0x90));
                Assert.Equal(0, reader.IndexOf(0x8D));

                reader.ReadByte();
                Assert.Equal(-1, reader.IndexOf(0xF0));
                Assert.Equal(-1, reader.IndexOf(0x90));
                Assert.Equal(-1, reader.IndexOf(0x8D));
            }
        }
Пример #42
0
        public unsafe void ReadFromMemoryReader()
        {
            byte[] buffer = new byte[4] { 0, 1, 0, 2 };
            fixed (byte* bufferPtr = buffer)
            {
                var reader = new BlobReader(new MemoryBlock(bufferPtr, buffer.Length));

                Assert.False(reader.SeekOffset(-1));
                Assert.False(reader.SeekOffset(Int32.MaxValue));
                Assert.False(reader.SeekOffset(Int32.MinValue));
                Assert.False(reader.SeekOffset(buffer.Length));
                Assert.True(reader.SeekOffset(buffer.Length - 1));

                Assert.True(reader.SeekOffset(0));
                Assert.Equal(0, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadUInt64());
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(1));
                Assert.Equal(1, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadDouble());
                Assert.Equal(1, reader.Offset);

                Assert.True(reader.SeekOffset(2));
                Assert.Equal(2, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadUInt32());
                Assert.Equal((ushort)0x0200, reader.ReadUInt16());
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(2));
                Assert.Equal(2, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadSingle());
                Assert.Equal(2, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Equal(9.404242E-38F, reader.ReadSingle());
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(3));
                Assert.Equal(3, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadUInt16());
                Assert.Equal((byte)0x02, reader.ReadByte());
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Equal("\u0000\u0001\u0000\u0002", reader.ReadUTF8(4));
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadUTF8(5));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadUTF8(-1));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Equal("\u0100\u0200", reader.ReadUTF16(4));
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadUTF16(5));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadUTF16(-1));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadUTF16(6));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Equal(buffer, reader.ReadBytes(4));
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Same(String.Empty, reader.ReadUtf8NullTerminated());
                Assert.Equal(1, reader.Offset);

                Assert.True(reader.SeekOffset(1));
                Assert.Equal("\u0001", reader.ReadUtf8NullTerminated());
                Assert.Equal(3, reader.Offset);

                Assert.True(reader.SeekOffset(3));
                Assert.Equal("\u0002", reader.ReadUtf8NullTerminated());
                Assert.Equal(4, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Same(String.Empty, reader.ReadUtf8NullTerminated());
                Assert.Equal(1, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadBytes(5));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.ReadBytes(Int32.MinValue));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.GetMemoryBlockAt(-1, 1));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Throws<BadImageFormatException>(() => reader.GetMemoryBlockAt(1, -1));
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(0));
                Assert.Equal(3, reader.GetMemoryBlockAt(1, 3).Length);
                Assert.Equal(0, reader.Offset);

                Assert.True(reader.SeekOffset(3));
                reader.ReadByte();
                Assert.Equal(4, reader.Offset);

                Assert.Equal(4, reader.Offset);
                Assert.Equal(0, reader.ReadBytes(0).Length);

                Assert.Equal(4, reader.Offset);
                int value;
                Assert.False(reader.TryReadCompressedInteger(out value));
                Assert.Equal(BlobReader.InvalidCompressedInteger, value);

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadCompressedInteger());

                Assert.Equal(4, reader.Offset);
                Assert.Equal(SerializationTypeCode.Invalid, reader.ReadSerializationTypeCode());

                Assert.Equal(4, reader.Offset);
                Assert.Equal(SignatureTypeCode.Invalid, reader.ReadSignatureTypeCode());

                Assert.Equal(4, reader.Offset);
                Assert.Equal(default(EntityHandle), reader.ReadTypeHandle());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadBoolean());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadByte());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadSByte());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadUInt32());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadInt32());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadUInt64());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadInt64());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadSingle());

                Assert.Equal(4, reader.Offset);
                Assert.Throws<BadImageFormatException>(() => reader.ReadDouble());

                Assert.Equal(4, reader.Offset);
            }

            byte[] buffer2 = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
            fixed (byte* bufferPtr2 = buffer2)
            {
                var reader = new BlobReader(new MemoryBlock(bufferPtr2, buffer2.Length));
                Assert.Equal(reader.Offset, 0);
                Assert.Equal(0x0807060504030201UL, reader.ReadUInt64());
                Assert.Equal(reader.Offset, 8);

                reader.Reset();
                Assert.Equal(reader.Offset, 0);
                Assert.Equal(0x0807060504030201L, reader.ReadInt64());

                reader.Reset();
                Assert.Equal(reader.Offset, 0);
                Assert.Equal(BitConverter.ToDouble(buffer2, 0), reader.ReadDouble());
            }
        }
Пример #43
0
 public StreamHeader(BlobReader reader)
 {
     Offset = reader.Read<int>();
     Size = reader.Read<int>();
     Name = reader.ReadNullTerminatedASCIIString(32, 4);
 }
Пример #44
0
 private static void MethodSpecSignatureToString(MetadataReader reader, SignatureHeader header, ref BlobReader blobReader, StringBuilder stringBuilder)
 {
     TypeSequenceSignatureToString(reader, ref blobReader, stringBuilder);
 }
Пример #45
0
        private static void TypeSignatureToString(MetadataReader reader, ref BlobReader blobReader, StringBuilder stringBuilder)
        {
            var typeCode = blobReader.ReadCompressedInteger();

            if (typeCode != (int)SignatureTypeKind.Class && typeCode != (int)SignatureTypeKind.ValueType)
            {
                stringBuilder.Append($"{(SignatureTypeCode) typeCode} ");
            }

            switch (typeCode)
            {
            case (int)SignatureTypeCode.Boolean:
            case (int)SignatureTypeCode.Char:
            case (int)SignatureTypeCode.SByte:
            case (int)SignatureTypeCode.Byte:
            case (int)SignatureTypeCode.Int16:
            case (int)SignatureTypeCode.UInt16:
            case (int)SignatureTypeCode.Int32:
            case (int)SignatureTypeCode.UInt32:
            case (int)SignatureTypeCode.Int64:
            case (int)SignatureTypeCode.UInt64:
            case (int)SignatureTypeCode.Single:
            case (int)SignatureTypeCode.Double:
            case (int)SignatureTypeCode.IntPtr:
            case (int)SignatureTypeCode.UIntPtr:
            case (int)SignatureTypeCode.Object:
            case (int)SignatureTypeCode.String:
            case (int)SignatureTypeCode.Void:
            case (int)SignatureTypeCode.TypedReference:

            case (int)SignatureTypeCode.Sentinel:
                break;

            case (int)SignatureTypeCode.Pointer:
            case (int)SignatureTypeCode.ByReference:
            case (int)SignatureTypeCode.Pinned:
            case (int)SignatureTypeCode.SZArray:
                TypeSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case (int)SignatureTypeCode.FunctionPointer:
                var header = blobReader.ReadSignatureHeader();
                MethodSignatureToString(reader, header, ref blobReader, stringBuilder);
                break;

            case (int)SignatureTypeCode.Array:
                ArrayTypeSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case (int)SignatureTypeCode.RequiredModifier:
            case (int)SignatureTypeCode.OptionalModifier:
                ModifiedTypeSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case (int)SignatureTypeCode.GenericTypeInstance:
                GenericTypeInstanceSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case (int)SignatureTypeCode.GenericTypeParameter:
            case (int)SignatureTypeCode.GenericMethodParameter:
                var index = blobReader.ReadCompressedInteger();
                stringBuilder.Append($"{index} ");
                break;

            case (int)SignatureTypeKind.Class:
            case (int)SignatureTypeKind.ValueType:
                TypeHandleSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            default:
                throw new BadImageFormatException();
            }
        }
Пример #46
0
        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();
        }
Пример #47
0
 /// <summary>
 /// Decodes a type from within a signature from a BlobReader positioned at its leading SignatureTypeCode.
 /// </summary>
 /// <param name="blobReader">The blob reader.</param>
 /// <param name="provider">The type provider.</param>
 /// <returns>The decoded type.</returns>
 /// <exception cref="System.BadImageFormatException">The reader was not positioned at a valid signature type.</exception>
 public static TType DecodeType <TType>(ref BlobReader blobReader, ISignatureTypeProvider <TType> provider)
 {
     return(DecodeType(ref blobReader, blobReader.ReadCompressedInteger(), provider));
 }
Пример #48
0
 internal static CilType DecodeType(ref BlobReader reader, CilTypeProvider provider)
 {
     return(NewDecoder(provider).DecodeType(ref reader));
 }
Пример #49
0
        private unsafe int ReadCompressedInteger(byte[] bytes, TryReadFunc tryRead, ReadFunc read)
        {
            fixed (byte* ptr = bytes)
            {
                var reader = new BlobReader(new MemoryBlock(ptr, bytes.Length));

                int value;
                bool valid = tryRead(ref reader, out value);

                if (valid)
                {
                    Assert.Equal(bytes.Length, reader.Offset);
                    reader.Reset();
                    Assert.Equal(value, read(ref reader));
                    Assert.Equal(bytes.Length, reader.Offset);
                }
                else
                {
                    Assert.Equal(0, reader.Offset);
                    Assert.Throws<BadImageFormatException>(() => reader.ReadCompressedInteger());
                    Assert.Equal(value, BlobReader.InvalidCompressedInteger);
                    Assert.Equal(0, reader.Offset);
                }

                return value;
            }
        }
Пример #50
0
        /// <summary>
        /// Decodes a type from within a signature from a BlobReader positioned immediately past the given SignatureTypeCode.
        /// </summary>
        /// <param name="blobReader">The blob reader.</param>
        /// <param name="typeCode">The SignatureTypeCode that immediately preceded the reader's current position.</param>
        /// <param name="provider">The type provider.</param>
        /// <returns>The decoded type.</returns>
        /// <exception cref="System.BadImageFormatException">The reader was not positioned at a valud signature type.</exception>
        private static TType DecodeType <TType>(ref BlobReader blobReader, int typeCode, ISignatureTypeProvider <TType> provider)
        {
            TType elementType;
            int   index;

            if (typeCode > byte.MaxValue)
            {
                typeCode = (int)SignatureTypeCode.Invalid;
            }
            switch (typeCode)
            {
            case (int)SignatureTypeCode.Boolean:
            case (int)SignatureTypeCode.Char:
            case (int)SignatureTypeCode.SByte:
            case (int)SignatureTypeCode.Byte:
            case (int)SignatureTypeCode.Int16:
            case (int)SignatureTypeCode.UInt16:
            case (int)SignatureTypeCode.Int32:
            case (int)SignatureTypeCode.UInt32:
            case (int)SignatureTypeCode.Int64:
            case (int)SignatureTypeCode.UInt64:
            case (int)SignatureTypeCode.Single:
            case (int)SignatureTypeCode.Double:
            case (int)SignatureTypeCode.IntPtr:
            case (int)SignatureTypeCode.UIntPtr:
            case (int)SignatureTypeCode.Object:
            case (int)SignatureTypeCode.String:
            case (int)SignatureTypeCode.Void:
            case (int)SignatureTypeCode.TypedReference:
                return(provider.GetPrimitiveType((PrimitiveTypeCode)typeCode));

            case (int)SignatureTypeCode.Pointer:
                elementType = DecodeType(ref blobReader, provider);
                return(provider.GetPointerType(elementType));

            case (int)SignatureTypeCode.ByReference:
                elementType = DecodeType(ref blobReader, provider);
                return(provider.GetByReferenceType(elementType));

            case (int)SignatureTypeCode.Pinned:
                elementType = DecodeType(ref blobReader, provider);
                return(provider.GetPinnedType(elementType));

            case (int)SignatureTypeCode.SZArray:
                elementType = DecodeType(ref blobReader, provider);
                return(provider.GetSZArrayType(elementType));

            case (int)SignatureTypeCode.FunctionPointer:
                MethodSignature <TType> methodSignature = DecodeMethodSignature(ref blobReader, provider);
                return(provider.GetFunctionPointerType(methodSignature));

            case (int)SignatureTypeCode.Array:
                return(DecodeArrayType(ref blobReader, provider));

            case (int)SignatureTypeCode.RequiredModifier:
                return(DecodeModifiedType(ref blobReader, provider, isRequired: true));

            case (int)SignatureTypeCode.OptionalModifier:
                return(DecodeModifiedType(ref blobReader, provider, isRequired: false));

            case (int)SignatureTypeCode.GenericTypeInstance:
                return(DecodeGenericTypeInstance(ref blobReader, provider));

            case (int)SignatureTypeCode.GenericTypeParameter:
                index = blobReader.ReadCompressedInteger();
                return(provider.GetGenericTypeParameter(index));

            case (int)SignatureTypeCode.GenericMethodParameter:
                index = blobReader.ReadCompressedInteger();
                return(provider.GetGenericMethodParameter(index));

            case 0x11:    //(int)CorElementType.ELEMENT_TYPE_CLASS
                return(DecodeTypeHandle(ref blobReader, provider, false));

            case 0x12:     //(int)CorElementType.ELEMENT_TYPE_VALUETYPE:
                return(DecodeTypeHandle(ref blobReader, provider, true));

            default:
                throw new BadImageFormatException();
            }
        }