public sealed class SectionHeaderParser
{
    public IReadOnlyList<SectionInfo> Parse(BinaryReader reader, NtHeaders ntHeaders, SafetyLimits limits, byte[] rawBytes)
    {
        var count = ntHeaders.FileHeader.NumberOfSections;
        BoundsChecker.EnsureCount(count, limits.MaxSectionsCount, "Section count");

        var sections = new List<SectionInfo>(count);

        for (var i = 0; i < count; i++)
        {
            var name = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(8)).TrimEnd('\0');
            var virtualSize = reader.ReadUInt32();
            var virtualAddress = reader.ReadUInt32();
            var sizeOfRawData = reader.ReadUInt32();
            var pointerToRawData = reader.ReadUInt32();
            var pointerToRelocations = reader.ReadUInt32();
            var pointerToLinenumbers = reader.ReadUInt32();
            var numberOfRelocations = reader.ReadUInt16();
            var numberOfLinenumbers = reader.ReadUInt16();
            var characteristics = reader.ReadUInt32();

            var entropy = CalculateEntropy(rawBytes, pointerToRawData, sizeOfRawData);

            sections.Add(new SectionInfo(
                name,
                virtualSize,
                virtualAddress,
                sizeOfRawData,
                pointerToRawData,
                pointerToRelocations,
                pointerToLinenumbers,
                numberOfRelocations,
                numberOfLinenumbers,
                characteristics,
                entropy));
        }

        return sections;
    }

    private static double CalculateEntropy(byte[] data, uint offset, uint size)
    {
        if (size == 0 || offset >= data.Length)
        {
            return 0d;
        }

        var maxSize = Math.Min((int)size, data.Length - (int)offset);
        if (maxSize <= 0)
        {
            return 0d;
        }

        Span<int> frequencies = stackalloc int[256];
        for (var i = 0; i < maxSize; i++)
        {
            frequencies[data[offset + i]]++;
        }

        double entropy = 0;
        for (var i = 0; i < 256; i++)
        {
            if (frequencies[i] == 0)
            {
                continue;
            }

            var p = frequencies[i] / (double)maxSize;
            entropy -= p * Math.Log2(p);
        }

        return entropy;
    }
}