private static object ReadRawOperand(IBinaryStreamReader reader, MsilOperandType msilOperandType) { switch (msilOperandType) { case MsilOperandType.InlineNone: return(null); case MsilOperandType.InlineArgument: case MsilOperandType.InlineVar: return(reader.ReadInt16()); case MsilOperandType.InlineI: case MsilOperandType.InlineBrTarget: return(reader.ReadInt32()); case MsilOperandType.ShortInlineArgument: case MsilOperandType.ShortInlineVar: case MsilOperandType.ShortInlineBrTarget: case MsilOperandType.ShortInlineI: return(reader.ReadSByte()); case MsilOperandType.ShortInlineR: return(reader.ReadSingle()); case MsilOperandType.InlineR: return(reader.ReadDouble()); case MsilOperandType.InlineI8: return(reader.ReadInt64()); case MsilOperandType.InlineField: case MsilOperandType.InlineMethod: case MsilOperandType.InlineSig: case MsilOperandType.InlineTok: case MsilOperandType.InlineType: case MsilOperandType.InlineString: return(new MetadataToken(reader.ReadUInt32())); case MsilOperandType.InlineSwitch: var offsets = new int[reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; i++) { offsets[i] = reader.ReadInt32(); } return(offsets); } throw new NotSupportedException(); }
/// <summary> /// Reads a metadata directory from an input stream. /// </summary> /// <param name="context">The reader context.</param> /// <param name="directoryReader">The input stream containing the metadata directory.</param> /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception> /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception> /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception> public SerializedMetadata(PEReaderContext context, IBinaryStreamReader directoryReader) { if (directoryReader == null) { throw new ArgumentNullException(nameof(directoryReader)); } _context = context ?? throw new ArgumentNullException(nameof(context)); _streamContentsReader = directoryReader.Fork(); var signature = (MetadataSignature)directoryReader.ReadUInt32(); switch (signature) { case MetadataSignature.Bsjb: // BSJB header is the default header. break; case MetadataSignature.Moc: _context.NotSupported("Old +MOC metadata header format is not supported."); return; default: _context.BadImage($"Invalid metadata header ({(uint) signature:X8})."); return; } MajorVersion = directoryReader.ReadUInt16(); MinorVersion = directoryReader.ReadUInt16(); Reserved = directoryReader.ReadUInt32(); int versionLength = directoryReader.ReadInt32(); if (!directoryReader.CanRead(versionLength)) { _context.BadImage($"Invalid version length in metadata header ({versionLength.ToString()} characters)."); return; } var versionBytes = new byte[versionLength]; directoryReader.ReadBytes(versionBytes, 0, versionBytes.Length); VersionString = Encoding.ASCII.GetString(versionBytes); Flags = directoryReader.ReadUInt16(); _numberOfStreams = directoryReader.ReadInt16(); _streamEntriesReader = directoryReader.Fork(); }
/// <summary> /// Reads a metadata directory from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="metadataStreamReader"></param> /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception> /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception> /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception> public SerializedMetadata(IBinaryStreamReader reader, IMetadataStreamReader metadataStreamReader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } _metadataStreamReader = metadataStreamReader; _streamContentsReader = reader.Fork(); var signature = (MetadataSignature)reader.ReadUInt32(); switch (signature) { case MetadataSignature.Bsjb: // BSJB header is the default header. break; case MetadataSignature.Moc: throw new NotSupportedException("Old +MOC metadata header format is not supported."); default: throw new BadImageFormatException($"Invalid metadata header ({(uint) signature:X8})."); } MajorVersion = reader.ReadUInt16(); MinorVersion = reader.ReadUInt16(); Reserved = reader.ReadUInt32(); int versionLength = reader.ReadInt32(); if (!reader.CanRead(versionLength)) { throw new BadImageFormatException($"Invalid version length in metadata header ({versionLength} characters)."); } var versionBytes = new byte[versionLength]; reader.ReadBytes(versionBytes, 0, versionBytes.Length); VersionString = Encoding.ASCII.GetString(versionBytes); Flags = reader.ReadUInt16(); _numberOfStreams = reader.ReadInt16(); _streamEntriesReader = reader.Fork(); }
private object ReadSignedImmediateData(X86OperandSize size) { switch (size) { case X86OperandSize.Byte: return(_reader.ReadSByte()); case X86OperandSize.Word: return(_reader.ReadInt16()); case X86OperandSize.Dword: return(_reader.ReadInt32()); case X86OperandSize.WordOrDword: return(_reader.ReadInt32()); // TODO: use operand-size override opcode // TODO: fword } throw new NotSupportedException(); }
private static object ReadElement(IBinaryStreamReader reader, ElementType elementType) { switch (elementType) { case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); } ThrowUnsupportedElementType(elementType); return(null); }
private static object ReadValue(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader) { switch (typeSignature.ElementType) { case ElementType.Boolean: return(reader.ReadByte() == 1); case ElementType.Char: return((char)reader.ReadUInt16()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.String: return(reader.ReadSerString()); case ElementType.Object: case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = header.MetadataResolver.ResolveType(typeSignature); if (enumTypeDef == null) { throw new MemberResolutionException(typeSignature); } if (enumTypeDef.IsEnum) { return(ReadValue(header, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (typeSignature.IsTypeOf("System", "Type")) { return(reader.ReadSerString()); } throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType); }
private static object ReadValue(ModuleDefinition parentModule, TypeSignature valueType, IBinaryStreamReader reader) { switch (valueType.ElementType) { case ElementType.Boolean: return(reader.ReadByte() == 1); case ElementType.Char: return((char)reader.ReadUInt16()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.String: return(reader.ReadSerString()); case ElementType.Object: return(ReadValue(parentModule, TypeSignature.ReadFieldOrPropType(parentModule, reader), reader)); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = parentModule.MetadataResolver.ResolveType(valueType); if (enumTypeDef != null && enumTypeDef.IsEnum) { return(ReadValue(parentModule, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (valueType.IsTypeOf("System", "Type")) { return(TypeNameParser.Parse(parentModule, reader.ReadSerString())); } throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); }
private static object ReadValue(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader) { switch (typeSignature.ElementType) { case ElementType.Boolean: return reader.ReadByte() == 1; case ElementType.Char: return (char)reader.ReadUInt16(); case ElementType.R4: return reader.ReadSingle(); case ElementType.R8: return reader.ReadDouble(); case ElementType.I1: return reader.ReadSByte(); case ElementType.I2: return reader.ReadInt16(); case ElementType.I4: return reader.ReadInt32(); case ElementType.I8: return reader.ReadInt64(); case ElementType.U1: return reader.ReadByte(); case ElementType.U2: return reader.ReadUInt16(); case ElementType.U4: return reader.ReadUInt32(); case ElementType.U8: return reader.ReadUInt64(); case ElementType.String: return reader.ReadSerString(); case ElementType.Object: return ReadValue(header, TypeSignature.ReadFieldOrPropType(header, reader), reader); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = header.MetadataResolver.ResolveType(typeSignature); if (enumTypeDef == null) throw new MemberResolutionException(typeSignature); if (enumTypeDef.IsEnum) return ReadValue(header, enumTypeDef.GetEnumUnderlyingType(), reader); break; } if (typeSignature.IsTypeOf("System", "Type")) return TypeSignature.FromAssemblyQualifiedName(header, reader.ReadSerString()); throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType); }
public void ReadValue(TypeSignature valueType) { if (valueType.IsTypeOf("System", "Type")) { Elements.Add(TypeNameParser.Parse(_parentModule, _reader.ReadSerString())); return; } switch (valueType.ElementType) { case ElementType.Boolean: Elements.Add(_reader.ReadByte() == 1); break; case ElementType.Char: Elements.Add((char)_reader.ReadUInt16()); break; case ElementType.R4: Elements.Add(_reader.ReadSingle()); break; case ElementType.R8: Elements.Add(_reader.ReadDouble()); break; case ElementType.I1: Elements.Add(_reader.ReadSByte()); break; case ElementType.I2: Elements.Add(_reader.ReadInt16()); break; case ElementType.I4: Elements.Add(_reader.ReadInt32()); break; case ElementType.I8: Elements.Add(_reader.ReadInt64()); break; case ElementType.U1: Elements.Add(_reader.ReadByte()); break; case ElementType.U2: Elements.Add(_reader.ReadUInt16()); break; case ElementType.U4: Elements.Add(_reader.ReadUInt32()); break; case ElementType.U8: Elements.Add(_reader.ReadUInt64()); break; case ElementType.String: Elements.Add(_reader.ReadSerString()); break; case ElementType.Object: var reader = new CustomAttributeArgumentReader(_parentModule, _reader); var type = TypeSignature.ReadFieldOrPropType(_parentModule, _reader); reader.ReadValue(type); Elements.Add(new BoxedArgument(type, type.ElementType == ElementType.SzArray ? reader.Elements.ToArray() : reader.Elements[0])); break; case ElementType.SzArray: var arrayElementType = ((SzArrayTypeSignature)valueType).BaseType; uint elementCount = _reader.CanRead(sizeof(uint)) ? _reader.ReadUInt32() : uint.MaxValue; IsNullArray = elementCount == uint.MaxValue; if (!IsNullArray) { for (uint i = 0; i < elementCount; i++) { ReadValue(arrayElementType); } } break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: // Value is an enum, resolve it and get underlying type. // If that fails, most enums are int32s, assume that is the case in an attempt to recover. var enumTypeDef = _parentModule.MetadataResolver.ResolveType(valueType); TypeSignature underlyingType; if (enumTypeDef is null) { underlyingType = _parentModule.CorLibTypeFactory.Int32; } else if (enumTypeDef.IsEnum) { underlyingType = enumTypeDef.GetEnumUnderlyingType() ?? _parentModule.CorLibTypeFactory.Int32; } else { throw new NotSupportedException($"Type {valueType} is not an enum."); } ReadValue(underlyingType); break; default: throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); } }