module PEdump::IMAGE_OPTIONAL_HEADER::ClassMethods

Constants

DataDirectory

Public Instance Methods

read(file, size = nil) click to toggle source
# File lib/pedump.rb, line 147
def read file, size = nil
  usual_size = self.const_get('USUAL_SIZE')
  cSIZE   = self.const_get 'SIZE'
  cFORMAT = self.const_get 'FORMAT'
  size ||= cSIZE
  PEdump.logger.warn "[?] unusual size of IMAGE_OPTIONAL_HEADER = #{size} (must be #{usual_size})" if size != usual_size
  PEdump.logger.warn "[?] #{size-usual_size} spare bytes after IMAGE_OPTIONAL_HEADER" if size > usual_size
  new(*file.read([size,cSIZE].min).to_s.unpack(cFORMAT)).tap do |ioh|
    ioh.DataDirectory = []

    # check if "...this address is outside the memory mapped file and is zeroed by the OS"
    # see http://www.phreedom.org/solar/code/tinype/, section "Removing the data directories"
    ioh.each_pair{ |k,v| ioh[k] = 0 if v.nil? }

    # http://opcode0x90.wordpress.com/2007/04/22/windows-loader-does-it-differently/
    # maximum of 0x10 entries, even if bigger
    [0x10,ioh.NumberOfRvaAndSizes].min.times do |idx|
      ioh.DataDirectory << IMAGE_DATA_DIRECTORY.read(file)
      ioh.DataDirectory.last.type = IMAGE_DATA_DIRECTORY::TYPES[idx]
    end
    #ioh.DataDirectory.pop while ioh.DataDirectory.last.empty?

    # skip spare bytes, if any. XXX may contain suspicious data
    file.seek(size-usual_size, IO::SEEK_CUR) if size > usual_size
  end
end