class Rex::PeParsey::Pe
Public Class Methods
new(isource)
click to toggle source
# File lib/rex/peparsey/pe.rb, line 12 def initialize(isource) # # DOS Header # # Parse the initial dos header, starting at the file beginning # offset = 0 dos_header = self.class._parse_dos_header(isource.read(offset, IMAGE_DOS_HEADER_SIZE)) # # File Header # # If there is going to be a PE, the dos header tells us where to find it # So now we try to parse the file (pe) header # offset += dos_header.e_lfanew # most likely an invalid e_lfanew... if offset > isource.size raise FileHeaderError, "e_lfanew looks invalid", caller end file_header = self.class._parse_file_header(isource.read(offset, IMAGE_FILE_HEADER_SIZE)) # # Optional Header # # After the file header, we find the optional header. Right now # we require a optional header. Despite it's name, all binaries # that we are interested in should have one. We need this # header for a lot of stuff, so we die without it... # offset += IMAGE_FILE_HEADER_SIZE optional_header = self.class._parse_optional_header( isource.read(offset, file_header.SizeOfOptionalHeader) ) if !optional_header raise OptionalHeaderError, "No optional header!", caller end base = optional_header.ImageBase # # Section Headers # # After the optional header should be the section headers. # We know how many there should be from the file header... # offset += file_header.SizeOfOptionalHeader num_sections = file_header.NumberOfSections section_headers = self.class._parse_section_headers( isource.read(offset, IMAGE_SIZEOF_SECTION_HEADER * num_sections) ) # # End of Headers # # After the section headers (which are padded to FileAlignment) # we should find the section data, described by the section # headers... # # So this is the end of our header data, lets store this # in an image source for possible access later... # offset += IMAGE_SIZEOF_SECTION_HEADER * num_sections offset = self.class._align_offset(offset, optional_header.FileAlignment) header_section = Section.new(isource.subsource(0, offset), 0, nil) # # Sections # # So from here on out should be section data, and then any # trailing data (like authenticode and stuff I think) # sections = [ ] section_headers.each do |section_header| rva = section_header.VirtualAddress size = section_header.SizeOfRawData file_offset = section_header.PointerToRawData sections << Section.new( isource.subsource(file_offset, size), rva, section_header ) end # # Save the stuffs! # # We have parsed enough to load the file up here, now we just # save off all of the structures and data... We will # save our fake header section, the real sections, etc. # # # These should not be accessed directly # self._isource = isource self._dos_header = dos_header self._file_header = file_header self._optional_header = optional_header self._section_headers = section_headers self.image_base = base self.sections = sections self.header_section = header_section self._config_header = _parse_config_header() self._tls_header = _parse_tls_header() # These can be accessed directly self.hdr = HeaderAccessor.new self.hdr.dos = self._dos_header self.hdr.file = self._file_header self.hdr.opt = self._optional_header self.hdr.sections = self._section_headers self.hdr.config = self._config_header self.hdr.tls = self._tls_header self.hdr.exceptions = self._exception_header # We load the exception directory last as it relies on hdr.file to be created above. self._exception_header = _load_exception_directory() end
Public Instance Methods
all_sections()
click to toggle source
Return everything that's going to be mapped in the process and accessable. This should include all of the sections and our “fake” section for the header data…
# File lib/rex/peparsey/pe.rb, line 153 def all_sections [ header_section ] + sections end
file_offset_to_va(offset)
click to toggle source
Converts a file offset into a virtual address
# File lib/rex/peparsey/pe.rb, line 187 def file_offset_to_va(offset) image_base + file_offset_to_rva(offset) end
length()
click to toggle source
# File lib/rex/peparsey/pe.rb, line 205 def length _isource.size end
ptr_32?()
click to toggle source
Returns true if this binary is for a 32-bit architecture. This check does not take into account 16-bit binaries at the moment.
# File lib/rex/peparsey/pe.rb, line 172 def ptr_32? ptr_64? == false end
ptr_64?()
click to toggle source
Returns true if this binary is for a 64-bit architecture.
# File lib/rex/peparsey/pe.rb, line 160 def ptr_64? [ IMAGE_FILE_MACHINE_IA64, IMAGE_FILE_MACHINE_ALPHA64, IMAGE_FILE_MACHINE_AMD64 ].include?(self._file_header.Machine) end
ptr_s(va)
click to toggle source
Converts a virtual address to a string representation based on the underlying architecture.
# File lib/rex/peparsey/pe.rb, line 180 def ptr_s(va) (ptr_32?) ? ("0x%.8x" % va) : ("0x%.16x" % va) end
read(offset, len)
click to toggle source
Read raw bytes from the specified offset in the underlying file
NOTE: You should pass raw file offsets into this, not offsets from the beginning of the section. If you need to read from within a section, add section.file_offset prior to passing the offset in.
# File lib/rex/peparsey/pe.rb, line 198 def read(offset, len) _isource.read(offset, len) end
size()
click to toggle source
# File lib/rex/peparsey/pe.rb, line 202 def size _isource.size end