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