/// <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); }
/// <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(); }
/// <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); }