Example #1
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);
        }
Example #2
0
        void AddImportScopeIndexes(Dictionary <uint, BlobDataInfoPosition> dict, TablesHeap tables, Table table, int column)
        {
            var mdTable = tables.MDTables[(int)table];

            if (mdTable.Rows == 0)
            {
                return;
            }

            var  heapStart = Span.Span.Start;
            var  heapEnd   = Span.Span.End;
            var  buffer    = Span.Buffer;
            var  recPos    = mdTable.Span.Start;
            var  rows      = mdTable.Rows;
            var  colInfo   = mdTable.Columns[column];
            uint recSize   = mdTable.RowSize;
            bool bigBlob   = colInfo.Size == 4;

            for (uint rid = 1; rid <= rows; rid++, recPos += recSize)
            {
                uint offs = bigBlob ? buffer.ReadUInt32(recPos + colInfo.Offset) : buffer.ReadUInt16(recPos + colInfo.Offset);
                if (offs == 0)
                {
                    continue;
                }

                var pos = heapStart + offs;
                int len = ReadCompressedUInt32(ref pos) ?? -1;
                if (len <= 0)
                {
                    continue;
                }
                var end = HexPosition.Min(heapEnd, pos + len);
                while (pos < end)
                {
                    var kind = ReadCompressedUInt32(ref pos);
                    if (kind == null || pos > end)
                    {
                        break;
                    }
                    var flags = GetImportFlags(kind.Value);
                    Debug.Assert(flags != 0);
                    if (flags == 0)
                    {
                        break;
                    }

                    if ((flags & ImportFlags.Alias) != 0)
                    {
                        var valueTmp = ReadCompressedUInt32(ref pos);
                        if (valueTmp == null || pos > end)
                        {
                            break;
                        }
                        var value = valueTmp.Value;
                        if (value != 0 && !dict.ContainsKey((uint)value))
                        {
                            var namePos = heapStart + value;
                            if (namePos < heapEnd)
                            {
                                dict[(uint)value] = new BlobDataInfoPosition(namePos, BlobDataKind.Utf8Name);
                            }
                        }
                    }

                    if ((flags & ImportFlags.TargetAssembly) != 0)
                    {
                        var valueTmp = ReadCompressedUInt32(ref pos);
                        if (valueTmp == null || pos > end)
                        {
                            break;
                        }
                    }

                    if ((flags & ImportFlags.TargetNamespace) != 0)
                    {
                        var valueTmp = ReadCompressedUInt32(ref pos);
                        if (valueTmp == null || pos > end)
                        {
                            break;
                        }
                        var value = valueTmp.Value;
                        if (value != 0 && !dict.ContainsKey((uint)value))
                        {
                            var namePos = heapStart + value;
                            if (namePos < heapEnd)
                            {
                                dict[(uint)value] = new BlobDataInfoPosition(namePos, BlobDataKind.Utf8Name);
                            }
                        }
                    }

                    if ((flags & ImportFlags.TargetType) != 0)
                    {
                        var valueTmp = ReadCompressedUInt32(ref pos);
                        if (valueTmp == null || pos > end)
                        {
                            break;
                        }
                    }
                }
            }
        }
        public override HexBufferLine GetLineFromPosition(HexBufferPoint position)
        {
            position = FilterAndVerify(position);
            ResetBuilderFields();

            var linePosition  = startPosition + (position.Position - startPosition).ToUInt64() / bytesPerLine * bytesPerLine;
            var lineEnd       = HexPosition.Min(linePosition + bytesPerLine, endPosition);
            var lineSpan      = HexSpan.FromBounds(linePosition, lineEnd);
            var logicalOffset = ToLogicalPosition(lineSpan.Start);

            var hexBytes = buffer.ReadHexBytes(lineSpan.Start, (long)lineSpan.Length.ToUInt64());

            var offsetSpan        = default(VST.Span);
            var fullValuesSpan    = default(VST.Span);
            var visibleValuesSpan = default(VST.Span);
            var fullAsciiSpan     = default(VST.Span);
            var visibleAsciiSpan  = default(VST.Span);

            var valueCells = Array.Empty <HexCell>();
            var asciiCells = Array.Empty <HexCell>();

            bool needSep = false;

            foreach (var column in columnOrder)
            {
                switch (column)
                {
                case HexColumnType.Offset:
                    if (showOffset)
                    {
                        if (needSep)
                        {
                            stringBuilder.Append(' ');
                        }
                        needSep = true;
                        WriteOffset(logicalOffset, out offsetSpan);
                    }
                    break;

                case HexColumnType.Values:
                    if (showValues)
                    {
                        if (needSep)
                        {
                            stringBuilder.Append(' ');
                        }
                        needSep    = true;
                        valueCells = WriteValues(hexBytes, lineSpan, out fullValuesSpan, out visibleValuesSpan);
                    }
                    break;

                case HexColumnType.Ascii:
                    if (showAscii)
                    {
                        if (needSep)
                        {
                            stringBuilder.Append(' ');
                        }
                        needSep    = true;
                        asciiCells = WriteAscii(hexBytes, lineSpan, out fullAsciiSpan, out visibleAsciiSpan);
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            var text = stringBuilder.ToString();

            if (text.Length != CharsPerLine)
            {
                throw new InvalidOperationException();
            }
            var valueCellColl = valueCells.Length == 0 ? HexCellCollection.Empty : new HexCellCollection(valueCells);
            var asciiCellColl = asciiCells.Length == 0 ? HexCellCollection.Empty : new HexCellCollection(asciiCells);
            var lineNumber    = GetLineNumberFromPosition(new HexBufferPoint(Buffer, lineSpan.Start));
            var res           = new HexBufferLineImpl(this, lineNumber, columnOrder, new HexBufferSpan(buffer, lineSpan), hexBytes, text, showOffset, showValues, showAscii, logicalOffset, valueCellColl, asciiCellColl, offsetSpan, fullValuesSpan, visibleValuesSpan, fullAsciiSpan, visibleAsciiSpan);

            ResetBuilderFields();
            return(res);
        }
Example #4
0
        /// <summary>
        /// Returns the span the field value references or null. The span can be empty.
        /// </summary>
        /// <param name="file">File</param>
        /// <returns></returns>
        public override HexSpan?GetFieldReferenceSpan(HexBufferFile file)
        {
            var offset = ReadValue();

            if (offset == 0)
            {
                return(null);
            }
            var pos = file.GetHeaders <PeHeaders>()?.FilePositionToBufferPosition(offset) ?? HexPosition.Min(HexPosition.MaxEndPosition - 1, file.Span.Start + offset);

            return(new HexSpan(pos, 0));
        }
Example #5
0
        HexCell[] WriteValues(HexBytes hexBytes, HexSpan visibleBytesSpan, out VST.Span fullSpan, out VST.Span visibleSpan)
        {
            Debug.Assert(showValues);
            cellList.Clear();
            int fullStart = CurrentTextIndex;

            ulong cellCount = bytesPerLine / (ulong)valueFormatter.ByteCount;
            var   flags     = valuesLowerCaseHex ? HexValueFormatterFlags.LowerCaseHex : HexValueFormatterFlags.None;
            var   pos       = visibleBytesSpan.Start;
            var   end       = visibleBytesSpan.Start + bytesPerLine;
            int?  visStart  = null;
            int?  visEnd    = null;
            int   cellPos   = 0;

            for (ulong i = 0; i < cellCount; i++)
            {
                if (i != 0)
                {
                    stringBuilder.Append(' ');
                }
                int groupIndex = (cellPos / groupSizeInBytes) & 1;

                HexBufferSpan bufferSpan;
                int           cellStart = CurrentTextIndex;
                int           spaces;
                if (visibleBytesSpan.Contains(pos))
                {
                    if (visStart == null)
                    {
                        visStart = CurrentTextIndex;
                    }
                    long valueIndex = (long)(pos - visibleBytesSpan.Start).ToUInt64();
                    spaces = valueFormatter.FormatValue(stringBuilder, hexBytes, valueIndex, flags);
                    var endPos = HexPosition.Min(endPosition, pos + (ulong)valueFormatter.ByteCount);
                    bufferSpan = new HexBufferSpan(new HexBufferPoint(buffer, pos), new HexBufferPoint(buffer, endPos));
                }
                else
                {
                    if (visStart != null && visEnd == null)
                    {
                        visEnd = CurrentTextIndex;
                    }
                    stringBuilder.Append(' ', valueFormatter.FormattedLength);
                    spaces     = valueFormatter.FormattedLength;
                    bufferSpan = default;
                }
                if (cellStart + valueFormatter.FormattedLength != CurrentTextIndex)
                {
                    throw new InvalidOperationException();
                }
                var      textSpan = VST.Span.FromBounds(cellStart + spaces, CurrentTextIndex);
                var      cellSpan = VST.Span.FromBounds(cellStart, CurrentTextIndex);
                VST.Span separatorSpan;
                if (i + 1 < cellCount)
                {
                    separatorSpan = new VST.Span(CurrentTextIndex, 1);
                }
                else
                {
                    separatorSpan = new VST.Span(CurrentTextIndex, 0);
                }
                var cellFullSpan = VST.Span.FromBounds(cellStart, separatorSpan.End);
                cellList.Add(new HexCell((int)i, groupIndex, bufferSpan, textSpan, cellSpan, separatorSpan, cellFullSpan));

                pos     += (ulong)valueFormatter.ByteCount;
                cellPos += valueFormatter.ByteCount;
            }
            if (pos != end)
            {
                throw new InvalidOperationException();
            }
            if (visStart != null && visEnd == null)
            {
                visEnd = CurrentTextIndex;
            }

            visibleSpan                       = visStart == null ? default : VST.Span.FromBounds(visStart.Value, visEnd.Value);
                                     fullSpan = VST.Span.FromBounds(fullStart, CurrentTextIndex);
                                     if (ValuesSpan != fullSpan)
                                     {
                                         throw new InvalidOperationException();
                                     }
                                     return(cellList.ToArray());
        }