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(); GenericParam.extraField = verInfo.netVerString.CompareTo(MetaData.versions[1]) <= 0; // after version 2.0.40607 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(); }
private PEReader(PEFile pefile, System.IO.FileStream file, bool refs, bool skipBody) : base(new MemoryStream(new BinaryReader(file).ReadBytes(System.Convert.ToInt32(file.Length)))) { 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) ReadMetaDataTableRefs(); else { ReadMetaDataTables(); pefile.metaDataTables = new MetaDataTables(tables); } file.Close(); if (thisScope != null) { thisScope.buffer = this; if (pefile != null) { pefile.versionInfo = verInfo; } } strings = null; userstring = null; blob = null; guid = null; }