static HexSpan?TryGetRvaSpan(HexBufferFile file, HexPosition position, RvaData rvaData, UInt32Data sizeData)
        {
            if (!rvaData.Span.Span.Contains(position))
            {
                return(null);
            }
            var peHeaders = file.GetHeaders <PeHeaders>();

            if (peHeaders == null)
            {
                return(null);
            }
            uint rva = rvaData.ReadValue();

            if (rva == 0)
            {
                return(null);
            }
            uint size = sizeData.ReadValue();

            if (size == 0)
            {
                return(null);
            }
            var pos = peHeaders.RvaToBufferPosition(rva);

            if (pos + size > file.Span.End)
            {
                return(new HexSpan(pos, 0));
            }
            return(new HexSpan(pos, size));
        }
        HexSpan?GetFieldReferenceSpan(HexBufferFile file, DotNetMetadataHeaderData header, HexPosition position)
        {
            if (header.StreamHeaders.Data.Span.Span.Contains(position))
            {
                var stream = (DotNetStorageStream)header.StreamHeaders.Data.GetFieldByPosition(position).Data;
                if (stream.Offset.Data.Span.Span.Contains(position))
                {
                    uint offset = stream.Offset.Data.ReadValue();
                    uint size   = stream.Size.Data.ReadValue();
                    var  pos    = header.Span.Span.Start + offset;
                    if (pos >= file.Span.End)
                    {
                        return(null);
                    }
                    var mdHeaders = file.GetHeaders <DotNetMetadataHeaders>();
                    if (mdHeaders == null)
                    {
                        return(new HexSpan(pos, 0));
                    }
                    if (pos >= mdHeaders.MetadataSpan.End)
                    {
                        return(null);
                    }
                    var end = pos + size;
                    if (end > mdHeaders.MetadataSpan.End)
                    {
                        return(new HexSpan(pos, 0));
                    }
                    return(HexSpan.FromBounds(pos, end));
                }
                return(null);
            }

            return(null);
        }
        static HexSpan?TryGetFileSpan(HexBufferFile file, HexPosition position, FileOffsetData offsetData, UInt32Data sizeData)
        {
            if (!offsetData.Span.Span.Contains(position))
            {
                return(null);
            }
            var peHeaders = file.GetHeaders <PeHeaders>();

            if (peHeaders == null)
            {
                return(null);
            }
            uint offset = offsetData.ReadValue();

            if (offset == 0)
            {
                return(null);
            }
            uint size = sizeData.ReadValue();

            if (size == 0)
            {
                return(null);
            }
            var pos = peHeaders.FilePositionToBufferPosition(offset);

            if (pos + size > file.Span.End)
            {
                return(new HexSpan(pos, 0));
            }
            return(new HexSpan(pos, size));
        }
        public static HexSpan?TryGetSpan(HexBufferFile file, DataDirectoryData data, HexPosition position)
        {
            if (!data.VirtualAddress.Data.Span.Span.Contains(position))
            {
                return(null);
            }
            uint rva = data.VirtualAddress.Data.ReadValue();

            if (rva == 0)
            {
                return(null);
            }
            uint size = data.Size.Data.ReadValue();

            if (size == 0)
            {
                return(null);
            }
            var peHeaders = file.GetHeaders <PeHeaders>();

            if (peHeaders == null)
            {
                return(null);
            }
            var pos = peHeaders.RvaToBufferPosition(rva);

            if (pos + size > file.Span.End)
            {
                return(new HexSpan(pos, 0));
            }
            return(new HexSpan(pos, size));
        }
Beispiel #5
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 mdHeaders = file.GetHeaders <DotNetMetadataHeaders>();

            if (mdHeaders is null)
            {
                return(null);
            }
            var tablesStream = mdHeaders.TablesStream;

            if (tablesStream is null)
            {
                return(null);
            }
            var token = new MDToken(ReadValue());

            if ((uint)token.Table >= (uint)tablesStream.MDTables.Count)
            {
                return(null);
            }
            var mdTable = tablesStream.MDTables[(int)token.Table];

            if (!mdTable.IsValidRID(token.Rid))
            {
                return(null);
            }
            return(new HexSpan(mdTable.Span.Start + (token.Rid - 1) * mdTable.RowSize, mdTable.RowSize));
        }
Beispiel #6
0
        HexSpan?GetFieldReferenceSpan(HexBufferFile file, DotNetCor20Data cor20, HexPosition position)
        {
            HexSpan?span;

            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.Metadata.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.Resources.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.StrongNameSignature.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.CodeManagerTable.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.VTableFixups.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.ExportAddressTableJumps.Data, position)) != null)
            {
                return(span);
            }
            if ((span = DataDirectoryDataUtils.TryGetSpan(file, cor20.ManagedNativeHeader.Data, position)) != null)
            {
                return(span);
            }

            if (cor20.EntryPointTokenOrRVA.Data.Span.Span.Contains(position))
            {
                uint value = cor20.EntryPointTokenOrRVA.Data.ReadValue();
                if (value == 0)
                {
                    return(null);
                }
                if ((cor20.Flags.Data.ReadValue() & 0x10) != 0)
                {
                    var peHeaders = file.GetHeaders <PeHeaders>();
                    if (peHeaders == null)
                    {
                        return(null);
                    }
                    return(new HexSpan(peHeaders.RvaToBufferPosition(value), 0));
                }
                else
                {
                    return(TryGetTokenSpan(file, value));
                }
            }

            return(null);
        }
Beispiel #7
0
        HexSpan?GetFieldReferenceSpan(HexBufferFile file, TableRecordData record, HexPosition position)
        {
            if (record.Token.Table == Table.ManifestResource)
            {
                var recordOffset = (position - record.Span.Span.Start).ToUInt64();
                // Check if it's not Offset column
                if (recordOffset >= 4)
                {
                    return(null);
                }

                var mdTable = record.TablesHeap.MDTables[(int)Table.ManifestResource];
                Debug.Assert(mdTable.IsValidRID(record.Token.Rid));
                if (!mdTable.IsValidRID(record.Token.Rid))
                {
                    return(null);
                }
                var  recordPos      = mdTable.Span.Start + (record.Token.Rid - 1) * mdTable.RowSize;
                var  buffer         = file.Buffer;
                uint offset         = buffer.ReadUInt32(recordPos);
                uint implementation = mdTable.TableInfo.Columns[3].Size == 2 ?
                                      buffer.ReadUInt16(recordPos + mdTable.RowSize - 2) :
                                      buffer.ReadUInt32(recordPos + mdTable.RowSize - 4);
                MDToken implementationToken;
                if (!CodedToken.Implementation.Decode(implementation, out implementationToken))
                {
                    return(null);
                }
                if (implementationToken.Rid != 0)
                {
                    return(null);
                }

                var resources = file.GetHeaders <DotNetHeaders>()?.ResourceProvider;
                if (resources == null)
                {
                    return(null);
                }
                if (offset >= resources.ResourcesSpan.Length)
                {
                    return(null);
                }
                var  pos  = resources.ResourcesSpan.Start + offset;
                uint size = pos + 4 > resources.ResourcesSpan.End ? 0 : buffer.ReadUInt32(pos);
                var  end  = (pos + 4) + size;
                if (end > resources.ResourcesSpan.End)
                {
                    return(new HexSpan(pos, 0));
                }
                return(HexSpan.FromBounds(pos, end));
            }

            return(null);
        }
Beispiel #8
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));
        }
Beispiel #9
0
        public override PEStructureProvider TryGetProvider(HexBufferFile file)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            var peHeaders = file.GetHeaders <PeHeaders>();

            if (peHeaders == null)
            {
                return(null);
            }
            return(file.Properties.GetOrCreateSingletonProperty(typeof(PEStructureProviderImpl), () => new PEStructureProviderImpl(file, peHeaders)));
        }
Beispiel #10
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 peHeaders = file.GetHeaders <PeHeaders>();

            if (peHeaders == null)
            {
                return(null);
            }
            var rva = ReadValue();

            if (rva == 0)
            {
                return(null);
            }
            return(new HexSpan(peHeaders.RvaToBufferPosition(rva), 0));
        }
Beispiel #11
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 guidStream = file.GetHeaders <DotNetMetadataHeaders>()?.GUIDStream;

            if (guidStream == null)
            {
                return(null);
            }
            uint index = ReadIndex();

            if (index == 0 || !guidStream.IsValidIndex(index))
            {
                return(null);
            }
            return(new HexSpan(guidStream.Span.Span.Start + (index - 1) * 16, 16));
        }
Beispiel #12
0
        public override bool Initialize()
        {
            HexSpan?resourcesSpan = null;
            var     peHeaders     = file.GetHeaders <PeHeaders>();

            if (peHeaders != null)
            {
                if (peHeaders.OptionalHeader.DataDirectory.Data.FieldCount < 15)
                {
                    return(false);
                }
                var cor20Span = Read(peHeaders, peHeaders.OptionalHeader.DataDirectory.Data[14].Data);
                if (cor20Span == null)
                {
                    return(false);
                }
                cor20 = DotNetCor20DataImpl.TryCreate(file, cor20Span.Value.Start);
                if (cor20 == null)
                {
                    return(false);
                }

                var mdSpan = Read(peHeaders, cor20.MetaData.Data);
                resourcesSpan = Read(peHeaders, cor20.Resources.Data);
                var snSpan = Read(peHeaders, cor20.StrongNameSignature.Data);

                ReadDotNetMetadataHeader(peHeaders, mdSpan);
                ReadStrongNameSignature(peHeaders, snSpan);
            }
            else
            {
                // Could be a portable PDB file (or a metadata only file)
                ReadDotNetMetadataHeader(file.Span);
            }

            if (mdHeader != null && dotNetHeaps != null)
            {
                dotNetMetadataHeaders = new DotNetMetadataHeadersImpl(metadataSpan, mdHeader, dotNetHeaps);
            }
            if (peHeaders != null && cor20 != null)
            {
                dotNetMethodProvider   = new DotNetMethodProviderImpl(file, peHeaders, dotNetMetadataHeaders?.TablesStream);
                dotNetResourceProvider = new DotNetResourceProviderImpl(file, peHeaders, dotNetMetadataHeaders, resourcesSpan);
                dotNetHeaders          = new DotNetHeadersImpl(peHeaders, cor20, dotNetMetadataHeaders, strongNameSignature, dotNetMethodProvider, dotNetResourceProvider);
            }
            return(cor20 != null || !metadataSpan.IsEmpty);
        }
Beispiel #13
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 stringsStream = file.GetHeaders <DotNetMetadataHeaders>()?.StringsStream;

            if (stringsStream == null)
            {
                return(null);
            }
            uint offset = ReadOffset();

            if (offset >= stringsStream.Span.Length)
            {
                return(null);
            }
            var pos = stringsStream.Span.Span.Start + offset;
            int len = GetStringLength(pos, stringsStream.Span.Span.End);

            return(new HexSpan(pos, (ulong)len));
        }
Beispiel #14
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 blobStream = file.GetHeaders <DotNetMetadataHeaders>()?.BlobStream;

            if (blobStream == null)
            {
                return(null);
            }
            uint offset = ReadOffset();

            if (offset >= blobStream.Span.Length)
            {
                return(null);
            }
            var   start    = blobStream.Span.Span.Start + offset;
            var   pos      = start;
            int   size     = (int)Utils.ReadCompressedUInt32(Span.Buffer, ref pos);
            ulong blobSize = pos + size > blobStream.Span.Span.End ? 0 : (ulong)size + (pos - start).ToUInt64();

            return(new HexSpan(start, blobSize));
        }
Beispiel #15
0
        static HexSpan?TryGetTokenSpan(HexBufferFile file, uint token)
        {
            var tablesStream = file.GetHeaders <DotNetHeaders>()?.MetadataHeaders?.TablesStream;

            if (tablesStream == null)
            {
                return(null);
            }
            var mdToken = new MDToken(token);

            if ((uint)mdToken.Table >= tablesStream.MDTables.Count)
            {
                return(null);
            }
            var mdTable = tablesStream.MDTables[(int)mdToken.Table];

            if (!mdTable.IsValidRID(mdToken.Rid))
            {
                return(null);
            }
            return(new HexSpan(mdTable.Span.Start + (mdToken.Rid - 1) * mdTable.RowSize, mdTable.RowSize));
        }
Beispiel #16
0
        public PEStructureProviderImpl(HexBufferFile file, PeHeaders peHeaders)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (peHeaders == null)
            {
                throw new ArgumentNullException(nameof(peHeaders));
            }
            if (peHeaders != file.GetHeaders <PeHeaders>())
            {
                throw new ArgumentException();
            }
            this.file      = file;
            this.peHeaders = peHeaders;
            var buffer = file.Buffer;

            imageDosHeader  = new ImageDosHeaderVM(buffer, peHeaders.DosHeader);
            imageFileHeader = new ImageFileHeaderVM(buffer, peHeaders.FileHeader);
            if (peHeaders.OptionalHeader.Is32Bit)
            {
                imageOptionalHeader = new ImageOptionalHeader32VM(buffer, (PeOptionalHeader32Data)peHeaders.OptionalHeader);
            }
            else
            {
                imageOptionalHeader = new ImageOptionalHeader64VM(buffer, (PeOptionalHeader64Data)peHeaders.OptionalHeader);
            }
            sections = new ImageSectionHeaderVM[peHeaders.Sections.FieldCount];
            for (int i = 0; i < sections.Length; i++)
            {
                sections[i] = new ImageSectionHeaderVM(buffer, peHeaders.Sections[i].Data);
            }
            var dnHeaders = file.GetHeaders <DotNetHeaders>();

            storageStreams = Array.Empty <StorageStreamVM>();
            if (dnHeaders != null)
            {
                imageCor20Header = new ImageCor20HeaderVM(buffer, dnHeaders.Cor20);
                var mdHeaders = dnHeaders.MetadataHeaders;
                if (mdHeaders != null)
                {
                    storageSignature = new StorageSignatureVM(buffer, mdHeaders.MetadataHeader);
                    storageHeader    = new StorageHeaderVM(buffer, mdHeaders.MetadataHeader);
                    storageStreams   = new StorageStreamVM[mdHeaders.Streams.Count];
                    for (int i = 0; i < storageStreams.Length; i++)
                    {
                        var ssh  = mdHeaders.MetadataHeader.StreamHeaders.Data[i].Data;
                        var heap = mdHeaders.Streams[i];
                        storageStreams[i] = new StorageStreamVM(buffer, heap, ssh, i);
                    }

                    var metaDataTables = new MetaDataTableVM[0x40];
                    if (mdHeaders.TablesStream != null)
                    {
                        tablesStream = new TablesStreamVM(buffer, mdHeaders.TablesStream, metaDataTables);
                        var stringsHeapSpan = GetSpan(mdHeaders.StringsStream);
                        var guidHeapSpan    = GetSpan(mdHeaders.GUIDStream);
                        foreach (var mdTable in mdHeaders.TablesStream.MDTables)
                        {
                            if (mdTable.Rows != 0)
                            {
                                metaDataTables[(int)mdTable.Table] = MetaDataTableVM.Create(buffer, tablesStream, mdTable, stringsHeapSpan, guidHeapSpan);
                            }
                        }
                    }
                }
            }
        }