Exemplo n.º 1
0
        private IEnumerable <ELFProgramSegment> ReadSegments()
        {
            Header.IsProgramHeaderCountReasonable.CheckThrowing();
            IsHeaderProgramHeaderOffsetValid.CheckThrowing();
            IsHeaderProgramHeaderEntrySizeValid.CheckThrowing();

            // Calculate the loadBias. It is usually just the base address except for some executable modules.
            ulong loadBias = _position;

            if (loadBias > 0)
            {
                for (uint i = 0; i < Header.ProgramHeaderCount; i++)
                {
                    ulong            programHeaderOffset = _position + Header.ProgramHeaderOffset + i * Header.ProgramHeaderEntrySize;
                    ELFProgramHeader header = DataSourceReader.Read <ELFProgramHeader>(programHeaderOffset);
                    if (header.Type == ELFProgramHeaderType.Load && header.FileOffset == 0)
                    {
                        loadBias -= header.VirtualAddress;
                    }
                }
            }

            // Build the program segments
            List <ELFProgramSegment> segments = new List <ELFProgramSegment>();

            for (uint i = 0; i < Header.ProgramHeaderCount; i++)
            {
                ulong programHeaderOffset = _position + Header.ProgramHeaderOffset + i * Header.ProgramHeaderEntrySize;
                segments.Add(new ELFProgramSegment(DataSourceReader, loadBias, programHeaderOffset, _isDataSourceVirtualAddressSpace));
            }
            return(segments);
        }
Exemplo n.º 2
0
        public uint Read(ulong position, byte[] buffer, uint bufferOffset, uint count)
        {
            uint bytesRead = 0;

            while (bytesRead != count)
            {
                int i = 0;
                for (; i < _segments.Length; i++)
                {
                    ELFProgramHeader header = _segments[i].Header;

                    ulong upperAddress = header.VirtualAddress + header.VirtualSize;
                    if (header.VirtualAddress <= position && position < upperAddress)
                    {
                        uint  bytesToReadRange = (uint)Math.Min(count - bytesRead, upperAddress - position);
                        ulong segmentOffset    = position - header.VirtualAddress;
                        uint  bytesReadRange   = _segments[i].Contents.Read(segmentOffset, buffer, bufferOffset, bytesToReadRange);
                        if (bytesReadRange == 0)
                        {
                            goto done;
                        }
                        position     += bytesReadRange;
                        bufferOffset += bytesReadRange;
                        bytesRead    += bytesReadRange;
                        break;
                    }
                }
                if (i == _segments.Length)
                {
                    break;
                }
            }
done:
            if (bytesRead == 0)
            {
                throw new InvalidVirtualAddressException(string.Format("Virtual address range is not mapped {0:X16} {1}", position, count));
            }
            // Zero the rest of the buffer if read less than requested
            Array.Clear(buffer, (int)bufferOffset, (int)(count - bytesRead));
            return(bytesRead);
        }
Exemplo n.º 3
0
        public uint Read(ulong position, byte[] buffer, uint bufferOffset, uint count)
        {
            for (int i = 0; i < _segments.Length; i++)
            {
                ELFProgramHeader header = _segments[i].Header;
                // FileSize == 0 means the segment isn't backed by any data
                if (header.FileSize > 0 && header.VirtualAddress <= position && position + count <= header.VirtualAddress + header.VirtualSize)
                {
                    ulong segmentOffset = position - header.VirtualAddress;
                    uint  fileBytes     = (uint)Math.Min(count, header.FileSize);
                    uint  bytesRead     = _segments[i].Contents.Read(segmentOffset, buffer, bufferOffset, fileBytes);

                    //zero the rest of the buffer if it is in the virtual address space but not the physical address space
                    if (bytesRead == fileBytes && fileBytes != count)
                    {
                        Array.Clear(buffer, (int)(bufferOffset + fileBytes), (int)(count - fileBytes));
                        bytesRead = count;
                    }
                    return(bytesRead);
                }
            }

            throw new InvalidVirtualAddressException(string.Format("Virtual address range is not mapped {0:X16} {1}", position, count));
        }