コード例 #1
0
        /// <inheritdoc />
        protected override IList <IResourceEntry> GetEntries()
        {
            var result = new OwnedCollection <IResourceDirectory, IResourceEntry>(this);

            // Optimisation, check for invalid resource directory offset, and prevention of self loop:
            if (_namedEntries + _idEntries == 0 || _depth >= MaxDepth)
            {
                return(result);
            }

            uint baseRva = _peFile.OptionalHeader.DataDirectories[OptionalHeader.ResourceDirectoryIndex].VirtualAddress;

            // Create entries reader.
            uint entryListSize = (uint)((_namedEntries + _idEntries) * ResourceDirectoryEntry.EntrySize);
            var  entriesReader = _peFile.CreateReaderAtFileOffset(_entriesOffset, entryListSize);

            for (int i = 0; i < _namedEntries + _idEntries; i++)
            {
                var rawEntry = new ResourceDirectoryEntry(_peFile, entriesReader);

                // Note: Even if creating the directory reader fails, we still want to include the directory entry
                //       itself. In such a case, we expose the directory as an empty directory. This is why the
                //       following statement is not used as a condition for an if statement.

                _peFile.TryCreateReaderAtRva(baseRva + rawEntry.DataOrSubDirOffset, out var entryReader);

                result.Add(rawEntry.IsSubDirectory
                    ? (IResourceEntry) new SerializedResourceDirectory(_peFile, rawEntry, entryReader, _depth + 1)
                    : new SerializedResourceData(_peFile, rawEntry, entryReader));
            }

            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Reads a resource data entry from the provided input stream.
        /// </summary>
        /// <param name="context">The PE reader context.</param>
        /// <param name="entry">The entry to read.</param>
        /// <param name="entryReader">The input stream to read the data from.</param>
        public SerializedResourceData(PEReaderContext context, ResourceDirectoryEntry entry, ref BinaryStreamReader entryReader)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));

            if (entry.IsByName)
            {
                Name = entry.Name;
            }
            else
            {
                Id = entry.IdOrNameOffset;
            }

            _contentsRva  = entryReader.ReadUInt32();
            _contentsSize = entryReader.ReadUInt32();
            CodePage      = entryReader.ReadUInt32();
        }
        /// <summary>
        /// Reads a resource data entry from the provided input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the resource.</param>
        /// <param name="entry">The entry to read.</param>
        /// <param name="entryReader">The input stream to read the data from.</param>
        public SerializedResourceData(IPEFile peFile, ResourceDirectoryEntry entry, IBinaryStreamReader entryReader)
        {
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            if (entry.IsByName)
            {
                Name = entry.Name;
            }
            else
            {
                Id = entry.IdOrNameOffset;
            }

            _contentsRva  = entryReader.ReadUInt32();
            _contentsSize = entryReader.ReadUInt32();
            CodePage      = entryReader.ReadUInt32();
        }
コード例 #4
0
        /// <inheritdoc />
        protected override IList <IResourceEntry> GetEntries()
        {
            var result = new OwnedCollection <IResourceDirectory, IResourceEntry>(this);

            // Optimisation, check for invalid resource directory offset, and prevention of self loop:
            if (_namedEntries + _idEntries == 0 || _depth >= MaxDepth)
            {
                _context.BadImage($"Reached maximum recursion depth of {_depth} sub resource directories.");
                return(result);
            }

            uint baseRva = _context.File.OptionalHeader
                           .GetDataDirectory(DataDirectoryIndex.ResourceDirectory)
                           .VirtualAddress;

            // Create entries reader.
            uint entryListSize = (uint)((_namedEntries + _idEntries) * ResourceDirectoryEntry.EntrySize);

            if (!_context.File.TryCreateReaderAtRva(_entriesRva, entryListSize, out var entriesReader))
            {
                _context.BadImage("Resource directory contains an invalid entry table RVA and/or entry count.");
                return(result);
            }

            for (int i = 0; i < _namedEntries + _idEntries; i++)
            {
                var rawEntry = new ResourceDirectoryEntry(_context, entriesReader);

                // Note: Even if creating the directory reader fails, we still want to include the directory entry
                //       itself. In such a case, we expose the directory as an empty directory. This is why the
                //       following if statement does not dictate the creation of the data entry or not.

                if (!_context.File.TryCreateReaderAtRva(baseRva + rawEntry.DataOrSubDirOffset, out var entryReader))
                {
                    _context.BadImage($"Resource directory entry {i.ToString()} has an invalid data offset.");
                }

                result.Add(rawEntry.IsSubDirectory
                    ? (IResourceEntry) new SerializedResourceDirectory(_context, rawEntry, entryReader, _depth + 1)
                    : new SerializedResourceData(_context, rawEntry, entryReader));
            }

            return(result);
        }