Exemple #1
0
        /// <summary>
        /// Constructs a PEImage class for a given PE image (dll/exe) in memory.
        /// </summary>
        /// <param name="stream">A Stream that contains a PE image at its 0th offset.  This stream must be seekable.</param>
        /// <param name="leaveOpen">Whether or not to leave the stream open, if this is set to false stream will be
        /// disposed when this object is.</param>
        /// <param name="isVirtual">Whether stream points to a PE image mapped into an address space (such as in a live process or crash dump).</param>
        private PEImage(Stream stream, bool leaveOpen, bool isVirtual)
        {
            _isVirtual = isVirtual;
            _stream    = stream ?? throw new ArgumentNullException(nameof(stream));
            _leaveOpen = leaveOpen;

            if (!stream.CanSeek)
            {
                throw new ArgumentException($"{nameof(stream)} is not seekable.");
            }

            ushort dosHeaderMagic = Read <ushort>(0);

            if (dosHeaderMagic != ExpectedDosHeaderMagic)
            {
                IsValid = false;
                return;
            }

            _peHeaderOffset = Read <int>(PESignatureOffsetLocation);
            if (_peHeaderOffset == 0)
            {
                IsValid = false;
                return;
            }

            uint peSignature = Read <uint>(_peHeaderOffset);

            if (peSignature != ExpectedPESignature)
            {
                IsValid = false;
                return;
            }

            // Read image_file_header
            ImageFileHeader header = Read <ImageFileHeader>(HeaderOffset);

            _sectionCount  = header.NumberOfSections;
            IndexTimeStamp = header.TimeDateStamp;

            if (TryRead(OptionalHeaderOffset, out ImageOptionalHeader optional))
            {
                IsPE64        = optional.Magic != OptionalMagic32;
                IndexFileSize = optional.SizeOfImage;

                // Read directories.  In order for us to read directories, we need to know if
                // this is a x64 image or not, hence why this is wrapped in the above TryRead
                SeekTo(DataDirectoryOffset);
                for (int i = 0; i < _directories.Length; i++)
                {
                    if (!TryRead(out _directories[i]))
                    {
                        break;
                    }
                }
            }
        }
Exemple #2
0
        private List <SectionHeader> ReadSections()
        {
            List <SectionHeader> sections = new List <SectionHeader>();

            if (!IsValid)
            {
                return(sections);
            }

            ImageFileHeader header = Header;

            if (header == null)
            {
                return(sections);
            }

            SeekTo(ImageDataDirectoryOffset);

            // Sanity check, there's a null row at the end of the data directory table
            ulong?zero = Read <ulong>();

            if (zero != 0)
            {
                return(sections);
            }

            for (int i = 0; i < header.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER?sectionHdr = Read <IMAGE_SECTION_HEADER>();
                if (sectionHdr.HasValue)
                {
                    sections.Add(new SectionHeader(sectionHdr.Value));
                }
            }

            return(sections);
        }