/// <summary> /// Reads a single exception handler from the given input stream. /// </summary> /// <param name="cilMethodBody">The method body that contains the exception handler.</param> /// <param name="reader">The input stream to read from.</param> /// <param name="fatFormat">A value indicating whether the fat format or the small format should be used.</param> /// <returns>The exception handler.</returns> public static ExceptionHandler FromReader(CilMethodBody cilMethodBody, IBinaryStreamReader reader, bool fatFormat) { var handlerType = (ExceptionHandlerType)(fatFormat ? reader.ReadUInt32() : reader.ReadUInt16()); int tryOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); int tryLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); int handlerOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); int handlerLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); uint classTokenOrFilterOffset = reader.ReadUInt32(); var handler = new ExceptionHandler(handlerType) { IsFat = fatFormat, TryStart = cilMethodBody.Instructions.GetByOffset(tryOffset), TryEnd = cilMethodBody.Instructions.GetByOffset(tryOffset + tryLength), HandlerStart = cilMethodBody.Instructions.GetByOffset(handlerOffset), HandlerEnd = cilMethodBody.Instructions.GetByOffset(handlerOffset + handlerLength), }; switch (handler.HandlerType) { case ExceptionHandlerType.Exception: handler.CatchType = (ITypeDefOrRef)((IOperandResolver)cilMethodBody).ResolveMember( new MetadataToken(classTokenOrFilterOffset)); break; case ExceptionHandlerType.Filter: handler.FilterStart = cilMethodBody.Instructions.GetByOffset((int)classTokenOrFilterOffset); break; } return(handler); }
public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader) { long position = reader.Position; if (!reader.CanRead(sizeof (ushort)) || reader.ReadUInt16() != 0x0001) throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature."); var signature = new CustomAttributeSignature() { StartOffset = position, }; if (parent.Constructor != null) { var methodSignature = parent.Constructor.Signature as MethodSignature; if (methodSignature != null) { foreach (var parameter in methodSignature.Parameters) { signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Header, parameter.ParameterType, reader)); } } } var namedElementCount = reader.CanRead(sizeof (ushort)) ? reader.ReadUInt16() : 0; for (uint i = 0; i < namedElementCount; i++) { signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Header, reader)); } return signature; }
/// <summary> /// Reads a single parameter definition row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the parameter definition table.</param> /// <returns>The row.</returns> public static ParameterDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new ParameterDefinitionRow( (ParameterAttributes)reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[2].Size))); }
/// <summary> /// Reads a single custom attribute signature from the input stream. /// </summary> /// <param name="parentModule">The module that contains the attribute signature.</param> /// <param name="ctor">The constructor that was called.</param> /// <param name="reader">The input stream.</param> /// <returns>The signature.</returns> /// <exception cref="FormatException">Occurs when the input stream does not point to a valid signature.</exception> public static CustomAttributeSignature FromReader(ModuleDefinition parentModule, ICustomAttributeType ctor, IBinaryStreamReader reader) { ushort prologue = reader.ReadUInt16(); if (prologue != CustomAttributeSignaturePrologue) { throw new FormatException("Input stream does not point to a valid custom attribute signature."); } var result = new CustomAttributeSignature(); // Read fixed arguments. var parameterTypes = ctor.Signature.ParameterTypes; for (int i = 0; i < parameterTypes.Count; i++) { var argument = CustomAttributeArgument.FromReader(parentModule, parameterTypes[i], reader); result.FixedArguments.Add(argument); } // Read named arguments. ushort namedArgumentCount = reader.ReadUInt16(); for (int i = 0; i < namedArgumentCount; i++) { var argument = CustomAttributeNamedArgument.FromReader(parentModule, reader); result.NamedArguments.Add(argument); } return(result); }
/// <summary> /// Reads a single resource directory from an input stream. /// </summary> /// <param name="peFile">The PE file containing the resource.</param> /// <param name="entry">The entry to read. If this value is <c>null</c>, the root directory is assumed.</param> /// <param name="directoryReader">The input stream.</param> /// <param name="depth"> /// The current depth of the resource directory tree structure. /// If this value exceeds <see cref="MaxDepth"/>, this class will not initialize any entries. /// </param> public SerializedResourceDirectory(IPEFile peFile, ResourceDirectoryEntry?entry, IBinaryStreamReader directoryReader, int depth = 0) { _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile)); _depth = depth; if (entry.HasValue) { var value = entry.Value; if (value.IsByName) { Name = value.Name; } else { Id = value.IdOrNameOffset; } } if (directoryReader != null) { Characteristics = directoryReader.ReadUInt32(); TimeDateStamp = directoryReader.ReadUInt32(); MajorVersion = directoryReader.ReadUInt16(); MinorVersion = directoryReader.ReadUInt16(); _namedEntries = directoryReader.ReadUInt16(); _idEntries = directoryReader.ReadUInt16(); _entriesRva = directoryReader.Rva; directoryReader.Offset = (directoryReader.Offset + (ulong)((_namedEntries + _idEntries) * ResourceDirectoryEntry.EntrySize)); } }
public new static CilRawFatMethodBody FromReader(IBinaryStreamReader reader) { var body = new CilRawFatMethodBody { _header = reader.ReadUInt16(), MaxStack = reader.ReadUInt16() }; int codeSize = reader.ReadInt32(); body.LocalVarSigToken = reader.ReadUInt32(); body.Code = reader.ReadBytes(codeSize); if (body.HasSections) { reader.Align(4); CilExtraSection section; do { section = CilExtraSection.FromReader(reader); body.ExtraSections.Add(section); } while (section.HasMoreSections); } return(body); }
public static ExceptionHandler FromReader(MethodBody methodBody, IBinaryStreamReader reader, bool fatFormat) { var offset = reader.Position; var handerType = fatFormat ? reader.ReadUInt32() : reader.ReadUInt16(); var tryOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); var tryLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); var handlerOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); var handlerLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); var classTokenOrFilterOffset = reader.ReadUInt32(); var handler = new ExceptionHandler((ExceptionHandlerType)handerType) { StartOffset = offset, IsFat = fatFormat, MethodBody = methodBody, TryStart = methodBody.GetInstructionByOffset(tryOffset), TryEnd = methodBody.GetInstructionByOffset(tryOffset + tryLength), HandlerStart = methodBody.GetInstructionByOffset(handlerOffset), HandlerEnd = methodBody.GetInstructionByOffset(handlerOffset + handlerLength), }; switch (handler.HandlerType) { case ExceptionHandlerType.Exception: handler.CatchType = (ITypeDefOrRef)((IOperandResolver)methodBody).ResolveMember(new MetadataToken(classTokenOrFilterOffset)); break; case ExceptionHandlerType.Filter: handler.FilterStart = methodBody.GetInstructionByOffset((int)classTokenOrFilterOffset); break; } return(handler); }
/// <summary> /// Reads a .NET directory from an input stream. /// </summary> /// <param name="peFile">The PE file containing the .NET directory.</param> /// <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> public SerializedDotNetDirectory(IPEFile peFile, IBinaryStreamReader reader, IMetadataStreamReader metadataStreamReader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile)); _metadataStreamReader = metadataStreamReader; Offset = reader.Offset; uint cb = reader.ReadUInt32(); MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); _metadataDirectory = DataDirectory.FromReader(reader); Flags = (DotNetDirectoryFlags)reader.ReadUInt32(); Entrypoint = reader.ReadUInt32(); _resourcesDirectory = DataDirectory.FromReader(reader); _strongNameDirectory = DataDirectory.FromReader(reader); _codeManagerDirectory = DataDirectory.FromReader(reader); _vtableFixupsDirectory = DataDirectory.FromReader(reader); _exportsDirectory = DataDirectory.FromReader(reader); _nativeHeaderDirectory = DataDirectory.FromReader(reader); }
public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader) { if (!reader.CanRead(sizeof(ushort)) || reader.ReadUInt16() != 0x0001) { throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature."); } var signature = new CustomAttributeSignature(); if (parent.Constructor != null) { var methodSignature = parent.Constructor.Signature as MethodSignature; if (methodSignature != null) { foreach (var parameter in methodSignature.Parameters) { signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Image, parameter.ParameterType, reader)); } } } var namedElementCount = reader.CanRead(sizeof(ushort)) ? reader.ReadUInt16() : 0; for (uint i = 0; i < namedElementCount; i++) { signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Image, reader)); } return(signature); }
/// <summary> /// Reads a single generic parameter row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the generic parameter table.</param> /// <returns>The row.</returns> public static GenericParameterRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new GenericParameterRow( reader.ReadUInt16(), (GenericParameterAttributes)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[2].Size), reader.ReadIndex((IndexSize)layout.Columns[3].Size))); }
/// <summary> /// Reads a raw method body from the given binary input stream using the fat method body format. /// </summary> /// <param name="errorListener">The object responsible for recording parser errors.</param> /// <param name="reader">The binary input stream to read from.</param> /// <returns>The raw method body.</returns> /// <exception cref="FormatException">Occurs when the method header indicates an method body that is not in the /// fat format.</exception> public new static CilRawFatMethodBody FromReader(IErrorListener errorListener, IBinaryStreamReader reader) { ulong fileOffset = reader.Offset; uint rva = reader.Rva; // Read flags. ushort header = reader.ReadUInt16(); var flags = (CilMethodBodyAttributes)(header & 0xFFF); int headerSize = (header >> 12) * sizeof(uint); // Verify this is a fat method body. if ((flags & CilMethodBodyAttributes.Fat) != CilMethodBodyAttributes.Fat) { errorListener.BadImage("Invalid fat CIL method body header."); return(null); } // Read remaining header. ushort maxStack = reader.ReadUInt16(); uint codeSize = reader.ReadUInt32(); uint localVarSigToken = reader.ReadUInt32(); // Move to code. reader.Offset = fileOffset + (ulong)headerSize; // Verify code size. if (reader.Offset + codeSize > reader.StartOffset + reader.Length) { errorListener.BadImage("Invalid fat CIL method body code size."); return(null); } // Read code. var code = new byte[codeSize]; reader.ReadBytes(code, 0, code.Length); // Create body. var body = new CilRawFatMethodBody(flags, maxStack, localVarSigToken, code); body.UpdateOffsets(fileOffset, rva); // Read any extra sections. if (body.HasSections) { reader.Align(4); CilExtraSection section; do { section = CilExtraSection.FromReader(reader); body.ExtraSections.Add(section); } while (section.HasMoreSections); } return(body); }
private static System.Version ReadVersion(IBinaryStreamReader reader) { ushort minor = reader.ReadUInt16(); ushort major = reader.ReadUInt16(); ushort revision = reader.ReadUInt16(); ushort build = reader.ReadUInt16(); return(new System.Version(major, minor, build, revision)); }
/// <summary> /// Reads a single exception handler from the provided input stream. /// </summary> /// <param name="body">The method body containing the exception handler.</param> /// <param name="reader">The input stream.</param> /// <param name="isFat"><c>true</c> if the fat format should be used, <c>false</c> otherwise.</param> /// <returns>The exception handler.</returns> public static CilExceptionHandler FromReader(CilMethodBody body, IBinaryStreamReader reader, bool isFat) { CilExceptionHandlerType handlerType; int tryStartOffset; int tryEndOffset; int handlerStartOffset; int handlerEndOffset; // Read raw structure. if (isFat) { handlerType = (CilExceptionHandlerType)reader.ReadUInt32(); tryStartOffset = reader.ReadInt32(); tryEndOffset = tryStartOffset + reader.ReadInt32(); handlerStartOffset = reader.ReadInt32(); handlerEndOffset = handlerStartOffset + reader.ReadInt32(); } else { handlerType = (CilExceptionHandlerType)reader.ReadUInt16(); tryStartOffset = reader.ReadUInt16(); tryEndOffset = tryStartOffset + reader.ReadByte(); handlerStartOffset = reader.ReadUInt16(); handlerEndOffset = handlerStartOffset + reader.ReadByte(); } int exceptionTokenOrFilterStart = reader.ReadInt32(); // Create handler. var handler = new CilExceptionHandler { HandlerType = handlerType, TryStart = body.Instructions.GetByOffset(tryStartOffset)?.CreateLabel() ?? new CilOffsetLabel(tryStartOffset), TryEnd = body.Instructions.GetByOffset(tryEndOffset)?.CreateLabel() ?? new CilOffsetLabel(tryEndOffset), HandlerStart = body.Instructions.GetByOffset(handlerStartOffset)?.CreateLabel() ?? new CilOffsetLabel(handlerStartOffset), HandlerEnd = body.Instructions.GetByOffset(handlerEndOffset)?.CreateLabel() ?? new CilOffsetLabel(handlerEndOffset), }; // Interpret last field. switch (handler.HandlerType) { case CilExceptionHandlerType.Exception when body.Owner.Module.TryLookupMember(exceptionTokenOrFilterStart, out var member): handler.ExceptionType = member as ITypeDefOrRef; break; case CilExceptionHandlerType.Filter: handler.FilterStart = body.Instructions.GetByOffset(exceptionTokenOrFilterStart)?.CreateLabel() ?? new CilOffsetLabel(exceptionTokenOrFilterStart); break;; } return(handler); }
/// <summary> /// Reads a single resource table header. /// </summary> /// <param name="reader">The reader.</param> /// <returns>The table header.</returns> public static VersionTableEntryHeader FromReader(IBinaryStreamReader reader) { return(new VersionTableEntryHeader { Length = reader.ReadUInt16(), ValueLength = reader.ReadUInt16(), Type = (VersionTableValueType)reader.ReadUInt16(), Key = reader.ReadUnicodeString(), }); }
/// <summary> /// Reads a single method definition row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the method definition table.</param> /// <param name="referenceResolver">The resolver to use for resolving the virtual address of the method body.</param> /// <returns>The row.</returns> public static MethodDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout, ISegmentReferenceResolver referenceResolver) { return(new MethodDefinitionRow( referenceResolver.GetReferenceToRva(reader.ReadUInt32()), (MethodImplAttributes)reader.ReadUInt16(), (MethodAttributes)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[3].Size), reader.ReadIndex((IndexSize)layout.Columns[4].Size), reader.ReadIndex((IndexSize)layout.Columns[5].Size))); }
/// <summary> /// Reads a single method definition row from an input stream. /// </summary> /// <param name="context">The reader context.</param> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the method definition table.</param> /// <returns>The row.</returns> public static MethodDefinitionRow FromReader(PEReaderContext context, IBinaryStreamReader reader, TableLayout layout) { return(new MethodDefinitionRow( context.File.GetReferenceToRva(reader.ReadUInt32()), (MethodImplAttributes)reader.ReadUInt16(), (MethodAttributes)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[3].Size), reader.ReadIndex((IndexSize)layout.Columns[4].Size), reader.ReadIndex((IndexSize)layout.Columns[5].Size))); }
/// <summary> /// Reads a single assembly definition row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the assembly definition table.</param> /// <returns>The row.</returns> public static AssemblyReferenceRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new AssemblyReferenceRow( reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), (AssemblyAttributes)reader.ReadUInt32(), reader.ReadIndex((IndexSize)layout.Columns[5].Size), reader.ReadIndex((IndexSize)layout.Columns[6].Size), reader.ReadIndex((IndexSize)layout.Columns[7].Size), reader.ReadIndex((IndexSize)layout.Columns[8].Size))); }
/// <summary> /// Reads a single assembly definition row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the assembly definition table.</param> /// <returns>The row.</returns> public static AssemblyDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new AssemblyDefinitionRow( (AssemblyHashAlgorithm)reader.ReadUInt32(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), (AssemblyAttributes)reader.ReadUInt32(), reader.ReadIndex((IndexSize)layout.Columns[6].Size), reader.ReadIndex((IndexSize)layout.Columns[7].Size), reader.ReadIndex((IndexSize)layout.Columns[8].Size))); }
public static FileHeader FromReader(IBinaryStreamReader reader) { return(new FileHeader { FileOffset = reader.FileOffset, Machine = (MachineType)reader.ReadUInt16(), NumberOfSections = reader.ReadUInt16(), TimeDateStamp = reader.ReadUInt32(), PointerToSymbolTable = reader.ReadUInt32(), NumberOfSymbols = reader.ReadUInt32(), SizeOfOptionalHeader = reader.ReadUInt16(), Characteristics = (Characteristics)reader.ReadUInt16() }); }
/// <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 single extra section from the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <returns>The extra section that was read.</returns> public static CilExtraSection FromReader(IBinaryStreamReader reader) { var section = new CilExtraSection { Attributes = (CilExtraSectionAttributes)reader.ReadByte() }; int dataSize; if (section.IsFat) { dataSize = reader.ReadByte() | (reader.ReadByte() << 0x08) | (reader.ReadByte() << 0x10); } else { dataSize = reader.ReadByte(); reader.ReadUInt16(); } section.Data = new byte[dataSize]; reader.ReadBytes(section.Data, 0, dataSize); return(section); }
/// <summary> /// Reads a single class layout row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the class layout table.</param> /// <returns>The row.</returns> public static ClassLayoutRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new ClassLayoutRow( reader.ReadUInt16(), reader.ReadUInt32(), reader.ReadIndex((IndexSize)layout.Columns[2].Size))); }
/// <summary> /// Reads a DOS header structure at the current position of the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <returns>The read DOS header.</returns> /// <exception cref="BadImageFormatException">Occurs when the input stream does not point to a valid DOS header.</exception> public static DosHeader FromReader(IBinaryStreamReader reader) { ulong offset = reader.Offset; uint rva = reader.Rva; var stub = new byte[DefaultNewHeaderOffset]; ushort magic = reader.ReadUInt16(); if (magic != ValidPEMagic) { throw new BadImageFormatException(); } reader.Offset += NextHeaderFieldOffset - 2; uint nextHeaderOffset = reader.ReadUInt32(); if (nextHeaderOffset != DefaultNewHeaderOffset) { Array.Resize(ref stub, (int)nextHeaderOffset); } reader.Offset -= NextHeaderFieldOffset + 4; reader.ReadBytes(stub, 0, stub.Length); return(new DosHeader(stub) { Offset = offset, Rva = rva, NextHeaderOffset = nextHeaderOffset }); }
/// <summary> /// Reads a single security declaration row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the security declaration table.</param> /// <returns>The row.</returns> public static SecurityDeclarationRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new SecurityDeclarationRow( (SecurityAction)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[1].Size), reader.ReadIndex((IndexSize)layout.Columns[2].Size))); }
/// <summary> /// Reads a single method semantics row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the method semantics table.</param> /// <returns>The row.</returns> public static MethodSemanticsRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new MethodSemanticsRow( (MethodSemanticsAttributes)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[1].Size), reader.ReadIndex((IndexSize)layout.Columns[2].Size))); }
public static CilExtraSection FromReader(IBinaryStreamReader reader) { var section = new CilExtraSection { Attributes = (CilExtraSectionAttributes)reader.ReadByte() }; if (!section.IsExceptionHandler) { throw new NotSupportedException("Invalid or unsupported extra section."); } int dataSize; if (section.IsFat) { dataSize = reader.ReadByte() | (reader.ReadByte() << 0x08) | (reader.ReadByte() << 0x10); } else { dataSize = reader.ReadByte(); reader.ReadUInt16(); } section.Data = reader.ReadBytes(dataSize); return(section); }
private void ReadRelocationEntry(IBinaryStreamReader reader, uint pageRva) { ushort rawValue = reader.ReadUInt16(); var type = (RelocationType)(rawValue >> 12); int offset = rawValue & 0xFFF; Items.Add(new BaseRelocation(type, _peFile.GetReferenceToRva((uint)(pageRva + offset)))); }
/// <summary> /// Reads a single implementation map row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the implementation map table.</param> /// <returns>The row.</returns> public static ImplementationMapRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new ImplementationMapRow( (ImplementationMapAttributes)reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[1].Size), reader.ReadIndex((IndexSize)layout.Columns[2].Size), reader.ReadIndex((IndexSize)layout.Columns[3].Size))); }
/// <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(); }
/// <summary> /// Reads an icon group resource entry from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The parsed group icon resource entry.</returns> public static IconGroupDirectoryEntry FromReader(IBinaryStreamReader reader) { var entry = new IconGroupDirectoryEntry { Offset = reader.Offset, Rva = reader.Rva, Width = reader.ReadByte(), Height = reader.ReadByte(), ColorCount = reader.ReadByte(), Reserved = reader.ReadByte(), ColorPlanes = reader.ReadUInt16(), PixelBitCount = reader.ReadUInt16(), BytesInRes = reader.ReadUInt32(), Id = reader.ReadUInt16() }; return(entry); }
/// <summary> /// Reads a single module definition row from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="layout">The layout of the module definition table.</param> /// <returns>The row.</returns> public static ModuleDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout) { return(new ModuleDefinitionRow( reader.ReadUInt16(), reader.ReadIndex((IndexSize)layout.Columns[1].Size), reader.ReadIndex((IndexSize)layout.Columns[2].Size), reader.ReadIndex((IndexSize)layout.Columns[3].Size), reader.ReadIndex((IndexSize)layout.Columns[4].Size))); }
private static object ReadRawOperand(IBinaryStreamReader reader, MsilOperandType msilOperandType) { switch (msilOperandType) { case MsilOperandType.InlineNone: return null; case MsilOperandType.InlineArgument: case MsilOperandType.InlineVar: return reader.ReadUInt16(); case MsilOperandType.InlineI: case MsilOperandType.InlineBrTarget: return reader.ReadInt32(); case MsilOperandType.ShortInlineArgument: case MsilOperandType.ShortInlineVar: return reader.ReadByte(); 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(); }
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 static ExceptionHandler FromReader(MethodBody methodBody, IBinaryStreamReader reader, bool fatFormat) { var offset = reader.Position; var handerType = fatFormat ? reader.ReadUInt32() : reader.ReadUInt16(); var tryOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); var tryLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); var handlerOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16(); var handlerLength = fatFormat ? reader.ReadInt32() : reader.ReadByte(); var classTokenOrFilterOffset = reader.ReadUInt32(); var handler = new ExceptionHandler((ExceptionHandlerType)handerType) { StartOffset = offset, IsFat = fatFormat, TryStart = methodBody.GetInstructionByOffset(tryOffset), TryEnd = methodBody.GetInstructionByOffset(tryOffset + tryLength), HandlerStart = methodBody.GetInstructionByOffset(handlerOffset), HandlerEnd = methodBody.GetInstructionByOffset(handlerOffset + handlerLength), }; switch (handler.HandlerType) { case ExceptionHandlerType.Exception: handler.CatchType = (ITypeDefOrRef)((IOperandResolver)methodBody).ResolveMember(new MetadataToken(classTokenOrFilterOffset)); break; case ExceptionHandlerType.Filter: handler.FilterStart = methodBody.GetInstructionByOffset((int)classTokenOrFilterOffset); break; } return handler; }