示例#1
0
        MDStreamFlags GetMDStreamFlags()
        {
            MDStreamFlags flags = 0;

            if (bigStrings)
            {
                flags |= MDStreamFlags.BigStrings;
            }
            if (bigGuid)
            {
                flags |= MDStreamFlags.BigGUID;
            }
            if (bigBlob)
            {
                flags |= MDStreamFlags.BigBlob;
            }
            if (options.ExtraData.HasValue)
            {
                flags |= MDStreamFlags.ExtraData;
            }
            if (hasDeletedRows)
            {
                flags |= MDStreamFlags.HasDelete;
            }
            return(flags);
        }
        /// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="peImage">The PEImage</param>
        public void Initialize(IPEImage peImage)
        {
            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

            var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
                var newRva = currentRva + (uint)dataLen;
                if (newRva < currentRva)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentRva = newRva;
            }

            InitializeTables();
        }
示例#3
0
 public TablesHeapWriter(TablesMDHeap tablesHeap, StringsMDHeap stringsHeap, GuidMDHeap guidHeap, BlobMDHeap blobHeap)
 {
     this.tablesHeap  = tablesHeap;
     this.stringsHeap = stringsHeap;
     this.guidHeap    = guidHeap;
     this.blobHeap    = blobHeap;
     if (stringsHeap.IsBig)
     {
         mdStreamFlags |= MDStreamFlags.BigStrings;
     }
     if (guidHeap.IsBig)
     {
         mdStreamFlags |= MDStreamFlags.BigGUID;
     }
     if (blobHeap.IsBig)
     {
         mdStreamFlags |= MDStreamFlags.BigBlob;
     }
 }
示例#4
0
        void Initialize()
        {
            if (initialized)
            {
                return;
            }
            initialized = true;

            var buffer = Span.Buffer;
            var pos    = Span.Span.Start;

            reserved1    = buffer.ReadUInt32(pos);
            majorVersion = buffer.ReadByte(pos + 4);
            minorVersion = buffer.ReadByte(pos + 5);
            flags        = (MDStreamFlags)buffer.ReadByte(pos + 6);
            log2Rid      = buffer.ReadByte(pos + 7);
            validMask    = buffer.ReadUInt64(pos + 8);
            sortedMask   = buffer.ReadUInt64(pos + 0x10);
            pos         += 0x18;
            Debug.Assert(Span.Span.Start + MinimumSize == pos);
            Debug.Assert(Span.Span.Contains(pos - 1), "Creator should've verified this");

            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables);
            var rowsCount    = new uint[tableInfos.Length];

            ulong valid          = validMask;
            var   sizes          = new uint[64];
            int   rowsFieldCount = 0;

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows;
                if ((valid & 1) == 0 || !Span.Span.Contains(pos + 3))
                {
                    rows = 0;
                }
                else
                {
                    rowsFieldCount++;
                    rows = buffer.ReadUInt32(pos);
                    pos += 4;
                }
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                // Mono ignores the high byte
                rows    &= 0x00FFFFFF;
                sizes[i] = rows;
                if (i < rowsCount.Length)
                {
                    rowsCount[i] = rows;
                }
            }

            bool hasExtraData = false;

            if ((flags & MDStreamFlags.ExtraData) != 0 && Span.Span.Contains(pos + 3))
            {
                hasExtraData = true;
                extraData    = buffer.ReadUInt32(pos);
                pos         += 4;
            }

            headerSpan = HexSpan.FromBounds(Span.Span.Start, pos);

            dnTableSizes.InitializeSizes((flags & MDStreamFlags.BigStrings) != 0, (flags & MDStreamFlags.BigGUID) != 0, (flags & MDStreamFlags.BigBlob) != 0, sizes);
            mdTables                 = new MDTable[tableInfos.Length];
            mdTablesReadOnly         = new ReadOnlyCollection <MDTable>(mdTables);
            tableRecordDataFactories = new TableRecordDataFactory[tableInfos.Length];
            var  tablesStartPos = pos;
            bool bad            = !Span.Span.Contains(pos);

            for (int i = 0; i < rowsCount.Length; i++)
            {
                var rows    = rowsCount[i];
                var mdTable = new MDTable(pos, (Table)i, rows, tableInfos[i]);
                if (bad || mdTable.Span.End > Span.End.Position)
                {
                    mdTable = new MDTable(pos, (Table)i, 0, tableInfos[i]);
                    bad     = true;
                }
                pos         = mdTable.Span.End;
                mdTables[i] = mdTable;
                tableRecordDataFactories[i] = CreateFactory(mdTable);
            }

            tablesSpan       = HexSpan.FromBounds(HexPosition.Min(Span.End.Position, tablesStartPos), HexPosition.Min(Span.End.Position, pos));
            tablesHeaderData = new TablesHeaderDataImpl(new HexBufferSpan(buffer, headerSpan), hasExtraData, rowsFieldCount);
        }
		/// <summary>
		/// Initializes MD tables
		/// </summary>
		/// <param name="peImage">The PEImage</param>
		public void Initialize(IPEImage peImage) {
			if (initialized)
				throw new Exception("Initialize() has already been called");
			initialized = true;

			reserved1 = imageStream.ReadUInt32();
			majorVersion = imageStream.ReadByte();
			minorVersion = imageStream.ReadByte();
			flags = (MDStreamFlags)imageStream.ReadByte();
			log2Rid = imageStream.ReadByte();
			validMask = imageStream.ReadUInt64();
			sortedMask = imageStream.ReadUInt64();

			int maxPresentTables;
			var dnTableSizes = new DotNetTableSizes();
			var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);
			mdTables = new MDTable[tableInfos.Length];

			ulong valid = validMask;
			var sizes = new uint[64];
			for (int i = 0; i < 64; valid >>= 1, i++) {
				uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
				if (i >= maxPresentTables)
					rows = 0;
				sizes[i] = rows;
				if (i < mdTables.Length)
					mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
			}

			if (HasExtraData)
				extraData = imageStream.ReadUInt32();

			dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

			var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;
			foreach (var mdTable in mdTables) {
				var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
				mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
				var newRva = currentRva + (uint)dataLen;
				if (newRva < currentRva)
					throw new BadImageFormatException("Too big MD table");
				currentRva = newRva;
			}

			InitializeTables();
		}
示例#6
0
        /// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="typeSystemTableRows">Type system table rows (from #Pdb stream)</param>
        public void Initialize(uint[] typeSystemTableRows)
        {
            if (initialized)
            {
                throw new Exception("Initialize() has already been called");
            }
            initialized = true;

            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            if (typeSystemTableRows != null)
            {
                maxPresentTables = DotNetTableSizes.normalMaxTables;
            }
            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            var debugSizes = sizes;

            if (typeSystemTableRows != null)
            {
                debugSizes = new uint[sizes.Length];
                for (int i = 0; i < 64; i++)
                {
                    if (DotNetTableSizes.IsSystemTable((Table)i))
                    {
                        debugSizes[i] = typeSystemTableRows[i];
                    }
                    else
                    {
                        debugSizes[i] = sizes[i];
                    }
                }
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes, debugSizes);

            var currentPos = (FileOffset)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = imageStream.Create(currentPos, dataLen);
                var newPos = currentPos + (uint)dataLen;
                if (newPos < currentPos)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentPos = newPos;
            }

            InitializeTables();
        }