/// <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 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); }