예제 #1
0
        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;
        }
예제 #2
0
        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();
        }