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; }
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(); } }
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()); } }
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); } }
/// <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); } } }
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); } }
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; }
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; } }
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()); }
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)); }
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; }
public MethodData(BlobReader reader) { Flags = (MethodDataFlags)reader.ReadByte(); Size = reader.ReadByte(); Data = reader.ReadBytes(Size); }
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(); }
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]] ); } } }
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()); }
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(); } }
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)); } }
/// <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())); }
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; }
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); }
public abstract void DecodeLocalConstant(ref BlobReader reader, out TTypeSymbol type, out ConstantValue value);
internal static CilType DecodeType(ref BlobReader reader, CilTypeProvider provider) { return NewDecoder(provider).DecodeType(ref reader); }
public bool TryGetMetadataCompilationOptionsBlobReader(out BlobReader reader) { return(TryGetCustomDebugInformationBlobReader(CompilationOptionsGuid, out reader)); }
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(); }
// 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); }
/// <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); }
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()); } }
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; }
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()); }
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(); }
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); }
/// <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)); }
private static MethodSignature ReadMethodSignature(BlobReader br) { return null; }
/// <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)); }
private static ReturnTypeSignature ReadReturnTypeSignature(BlobReader br) { var rt = new ReturnTypeSignature(); rt.FirstMod = ReadCustomModSignatures(br); rt.Type = ParseTypeSignature(br); return rt; }
/// <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)); }
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); }
// 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)); }
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)); } }
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()); } }
public StreamHeader(BlobReader reader) { Offset = reader.Read<int>(); Size = reader.Read<int>(); Name = reader.ReadNullTerminatedASCIIString(32, 4); }
private static void MethodSpecSignatureToString(MetadataReader reader, SignatureHeader header, ref BlobReader blobReader, StringBuilder stringBuilder) { TypeSequenceSignatureToString(reader, ref blobReader, stringBuilder); }
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(); } }
private Object ResolveMemberReference(MemberReferenceHandle handle) { MemberReference memberReference = _metadataReader.GetMemberReference(handle); Object parent = GetObject(memberReference.Parent); TypeDesc parentTypeDesc = parent as TypeDesc; if (parentTypeDesc != null) { BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature); EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); string name = _metadataReader.GetString(memberReference.Name); if (parser.IsFieldSignature) { FieldDesc field = parentTypeDesc.GetField(name); if (field != null) { return(field); } throw new TypeSystemException.MissingFieldException(parentTypeDesc, name); } else { MethodSignature sig = parser.ParseMethodSignature(); TypeDesc typeDescToInspect = parentTypeDesc; // Try to resolve the name and signature in the current type, or any of the base types. do { // TODO: handle substitutions MethodDesc method = typeDescToInspect.GetMethod(name, sig); if (method != null) { // If this resolved to one of the base types, make sure it's not a constructor. // Instance constructors are not inherited. if (typeDescToInspect != parentTypeDesc && method.IsConstructor) { break; } return(method); } typeDescToInspect = typeDescToInspect.BaseType; } while (typeDescToInspect != null); throw new TypeSystemException.MissingMethodException(parentTypeDesc, name, sig); } } else if (parent is MethodDesc) { throw new NotSupportedException("Vararg methods not supported in .NET Core."); } else if (parent is ModuleDesc) { throw new NotImplementedException("MemberRef to a global function or variable."); } throw new BadImageFormatException(); }
/// <summary> /// 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)); }
internal static CilType DecodeType(ref BlobReader reader, CilTypeProvider provider) { return(NewDecoder(provider).DecodeType(ref reader)); }
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; } }
/// <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(); } }