private PEReader([NotNull] PEFile pefile, [NotNull] System.IO.FileStream file, bool refs, bool skipBody) : base(new MemoryStream(new BinaryReader(file).ReadBytes(System.Convert.ToInt32(file.Length)))) { Contract.Requires(pefile != null); Contract.Requires(file != null); this.skipBody = skipBody; thisScope = pefile; refsOnly = refs; verInfo.fromExisting = true; try { ReadDOSHeader(); } catch (PEFileException) { Console.WriteLine("Bad DOS header"); return; } ReadFileHeader(); ReadSectionHeaders(); ReadCLIHeader(); ReadMetaData(); if (refsOnly) this.ReadMetaDataTableRefs(); else { this.ReadMetaDataTables(); pefile.metaDataTables = new MetaDataTables(tables); this.SaveUnmanagedResources(); } file.Close(); if (thisScope != null) { thisScope.buffer = this; if (pefile != null) { pefile.versionInfo = verInfo; } } strings = null; userstring = null; blob = null; guid = null; }
private void ReadMetaData() { if (Diag.DiagOn) Console.WriteLine("MetaData at RVA = " + Hex.Int(metaDataRVA) + " and offset = " + Hex.Int(GetOffset(metaDataRVA))); BaseStream.Seek(GetOffset(metaDataRVA), SeekOrigin.Begin); uint sig = ReadUInt32(); // check verInfo.mdMajVer = ReadUInt16(); // check verInfo.mdMinVer = ReadUInt16(); // check ReadZeros(4); int verStrLen = ReadInt32(); int end = -1; char[] verString = new char[verStrLen + 1]; for (int i = 0; i < verStrLen; i++) { verString[i] = (char)ReadByte(); if ((verString[i] == 0) && (end == -1)) end = i; } verString[verStrLen] = (char)0; // check if (end == -1) end = verStrLen; verInfo.netVerString = new string(verString, 0, end); verInfo.SetVersionFromString(); // Beware of unknown netVerString values here ... Needs a better fix (kjg 31-Oct-2007) GenericParam.extraField = verInfo.netVersion < NetVersion.Whidbey41; if (Diag.DiagOn && GenericParam.extraField) { Console.WriteLine("Version = " + verInfo.netVerString + " has extra field for GenericParam"); } int alignNum = 0; if ((verStrLen % 4) != 0) alignNum = 4 - (verStrLen % 4); ReadZeros(alignNum); flags = ReadUInt16(); // check int numStreams = ReadUInt16(); streamOffsets = new uint[numStreams]; streamSizes = new uint[numStreams]; streamNames = new String[numStreams]; if (Diag.DiagOn) Console.WriteLine("MetaData Streams"); for (int i = 0; i < numStreams; i++) { streamOffsets[i] = ReadUInt32(); streamSizes[i] = ReadUInt32(); streamNames[i] = ReadStreamName(); if (Diag.DiagOn) Console.WriteLine(" " + streamNames[i] + " Offset = " + Hex.Int(streamOffsets[i]) + " Size = " + Hex.Int(streamSizes[i])); } uint tildeIx = 0; for (uint i = 0; i < numStreams; i++) { String nam = streamNames[i]; if (MetaData.tildeName.CompareTo(nam) == 0) tildeIx = i; else { uint streamoff = GetOffset(metaDataRVA + streamOffsets[i]); if (Diag.DiagOn) Console.WriteLine("getting stream bytes at offset " + Hex.Int(streamoff)); BaseStream.Seek(GetOffset(metaDataRVA + streamOffsets[i]), SeekOrigin.Begin); long streamStart = BaseStream.Position; byte[] strBytes = ReadBytes((int)streamSizes[i]); if (MetaData.stringsName.CompareTo(nam) == 0) { strings = new MetaDataInStream(strBytes); } else if (MetaData.userstringName.CompareTo(nam) == 0) { userstring = new MetaDataStringStream(strBytes); } else if (MetaData.blobName.CompareTo(nam) == 0) { blobStreamStartOffset = streamStart; blob = new MetaDataInStream(strBytes); } else if (MetaData.guidName.CompareTo(nam) == 0) { guid = new MetaDataInStream(strBytes); } else if (nam.CompareTo("#-") == 0) { tildeIx = i; //throw new Exception("Illegal uncompressed data stream #-"); } else { Console.WriteLine("Unknown stream - " + nam); } } } // go to beginning of tilde stream BaseStream.Seek(GetOffset(metaDataRVA + streamOffsets[tildeIx]), SeekOrigin.Begin); ReadTildeStreamStart(); }