Parent

Class/Module Index [+]

Quicksearch

Rex::PeParsey::Pe

Public Class Methods

new(isource) click to toggle source
# File lib/rex/peparsey/pe.rb, line 14
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 155
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 189
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 207
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 174
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 162
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 182
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 200
def read(offset, len)
        _isource.read(offset, len)
end
size() click to toggle source
# File lib/rex/peparsey/pe.rb, line 204
def size
        _isource.size
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.