コード例 #1
0
        public MethodEntry(int rva, BlobReader reader)
        {
            RVA = rva;
            Flags = (MethodHeaderFlags)reader.ReadByte();
            if (!Flags.HasFlag(MethodHeaderFlags.FatFormat))
            {
                Size = (int)Flags & 0x3F;
                Flags = MethodHeaderFlags.TinyFormat;
                MethodBody = reader.ReadBytes((int)Size);
            }
            else
            {
                Size = (reader.ReadByte() & 0xF0) >> 4;
                MaxStack = reader.Read<ushort>();
                CodeSize = reader.Read<uint>();
                LocalVarSigTok = new MetadataToken(reader.Read<uint>());
                MethodBody = reader.ReadBytes((int)CodeSize);

                //var end = reader.BaseStream.Position + Size;
                //var data = new List<MethodData>();
                //while (reader.BaseStream.Position < end)
                //{
                //    data.Add(new MethodData(reader));
                //}
                //Data = data.ToArray();
            }
        }
コード例 #2
0
        internal CliMetadataMethodHeader(ICliMetadataRoot metadataRoot, uint relativeVirtualAddress, Action <byte[]> bodyBuilder)
        {
            var image           = metadataRoot.SourceImage;
            var rvaLocationScan = image.ResolveRelativeVirtualAddress(relativeVirtualAddress);

            if (rvaLocationScan.Resolved)
            {
                var section       = rvaLocationScan.Section;
                var bodySubstream = new Substream(section.SectionData, rvaLocationScan.Offset, 65536, false);
                var bodyReader    = new EndianAwareBinaryReader(bodySubstream, Endianness.LittleEndian, false);
                var peekedChar    = bodyReader.PeekByte();
                if (peekedChar != -1)
                {
                    MethodHeaderFlags headerType = ((MethodHeaderFlags)peekedChar) & MethodHeaderFlags.WideFormat;
                    if (headerType == MethodHeaderFlags.NarrowFormat)
                    {
                        this.ReadNarrow(bodyReader, metadataRoot, bodyBuilder);
                    }
                    else
                    {
                        this.ReadWide(bodyReader, metadataRoot, bodyBuilder);
                    }
                }
            }
        }
コード例 #3
0
        private void ReadWide(EndianAwareBinaryReader reader, ICliMetadataRoot metadataRoot, Action <byte[]> bodyBuilder)
        {
            var flagsAndSize = reader.ReadUInt16();

            this.flags      = ((MethodHeaderFlags)(flagsAndSize & 0x0FFF)) & ~MethodHeaderFlags.WideFormat;
            this.headerSize = (byte)((flagsAndSize & 0xF000) >> 0xA);
            this.maxStack   = reader.ReadUInt16();
            this.codeSize   = reader.ReadUInt32();
            var localVarSigToken = reader.ReadUInt32();

            if (localVarSigToken != 0)
            {
                var sigTableKind = (CliMetadataTableKinds)(1UL << (int)((localVarSigToken & 0xFF000000) >> 24));
                var sigIndex     = localVarSigToken & 0x00FFFFFF;
                ICliMetadataTable table;
                if (metadataRoot.TableStream.TryGetValue(sigTableKind, out table))
                {
                    if (table is ICliMetadataStandAloneSigTable)
                    {
                        ICliMetadataStandAloneSigTable sigTable = (ICliMetadataStandAloneSigTable)table;
                        var entry = sigTable[(int)sigIndex];
                        if (entry.Signature is ICliMetadataLocalVarSignature)
                        {
                            var sigEntry = (ICliMetadataLocalVarSignature)entry.Signature;
                            this.locals = sigEntry;
                        }
                    }
                }
                long codePosition = reader.BaseStream.Position;
                bodyBuilder(reader.ReadBytes((int)this.codeSize));
                if ((reader.BaseStream.Position % 4) != 0)
                {
                    reader.BaseStream.Position += 4 - reader.BaseStream.Position % 4;
                }
                var ehTable = new byte[0];
                if ((flags & MethodHeaderFlags.ContainsMoreSections) == MethodHeaderFlags.ContainsMoreSections)
                {
readSection:
                    MethodHeaderSectionFlags sectionFlags = (MethodHeaderSectionFlags)reader.ReadByte();
                    var smallFormat = ((sectionFlags & MethodHeaderSectionFlags.FatFormat) != MethodHeaderSectionFlags.FatFormat);
                    int dataSize    = 0;
                    if (smallFormat)
                    {
                        dataSize = reader.ReadByte();
                        reader.ReadUInt16();
                    }
                    else
                    {
                        dataSize = (int)new BitVector(new byte[] { reader.ReadByte(), reader.ReadByte(), reader.ReadByte() }).GetUInt32Nibbits(0, 24);
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ExceptionHandlerTable) == MethodHeaderSectionFlags.ExceptionHandlerTable)
                    {
                        ehTable = ehTable.AddInlineArray(reader.ReadBytes(dataSize - 4));
                    }
                    else
                    {
                        reader.BaseStream.Position += dataSize - 4;
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ContainsMoreSections) == MethodHeaderSectionFlags.ContainsMoreSections)
                    {
                        goto readSection;
                    }
                }
                if (ehTable.Length > 0)
                {
                    this.exceptionTable = new CliMetadataMethodExceptionTable(ehTable);
                }
                reader.BaseStream.Position = codePosition;
            }
        }