Class: PEdump::PE

Inherits:
Struct show all
Defined in:
lib/pedump/pe.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#image_file_headerObject Also known as: ifh

Returns the value of attribute image_file_header

Returns:

  • (Object)

    the current value of image_file_header



4
5
6
# File 'lib/pedump/pe.rb', line 4

def image_file_header
  @image_file_header
end

#image_optional_headerObject Also known as: ioh

Returns the value of attribute image_optional_header

Returns:

  • (Object)

    the current value of image_optional_header



4
5
6
# File 'lib/pedump/pe.rb', line 4

def image_optional_header
  @image_optional_header
end

#section_tableObject Also known as: sections

Returns the value of attribute section_table

Returns:

  • (Object)

    the current value of section_table



4
5
6
# File 'lib/pedump/pe.rb', line 4

def section_table
  @section_table
end

#signatureObject

Returns the value of attribute signature

Returns:

  • (Object)

    the current value of signature



4
5
6
# File 'lib/pedump/pe.rb', line 4

def signature
  @signature
end

Class Method Details

.loggerObject



92
# File 'lib/pedump/pe.rb', line 92

def self.logger; PEdump.logger; end

.read(f, args = nil) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/pedump/pe.rb', line 25

def self.read f, args = nil
  force = args.is_a?(Hash) && args[:force]

  pe_offset = f.tell
  pe_sig = f.read 4
  #logger.error "[!] 'NE' format is not supported!" if pe_sig == "NE\x00\x00"
  if pe_sig != "PE\x00\x00"
    if force
      logger.warn  "[?] no PE signature (want: 'PE\\x00\\x00', got: #{pe_sig.inspect})"
    else
      logger.debug "[?] no PE signature (want: 'PE\\x00\\x00', got: #{pe_sig.inspect}). (not forced)"
      return nil
    end
  end
  PE.new(pe_sig).tap do |pe|
    pe.image_file_header = IMAGE_FILE_HEADER.read(f)
    if pe.ifh.SizeOfOptionalHeader > 0
      if pe.x64?
        pe.image_optional_header = IMAGE_OPTIONAL_HEADER64.read(f, pe.ifh.SizeOfOptionalHeader)
      else
        pe.image_optional_header = IMAGE_OPTIONAL_HEADER32.read(f, pe.ifh.SizeOfOptionalHeader)
      end
    end

    if (nToRead=pe.ifh.NumberOfSections) > 0xffff
      if force.is_a?(Numeric) && force > 1
        logger.warn "[!] too many sections (#{pe.ifh.NumberOfSections}). forced. reading all"
      else
        logger.warn "[!] too many sections (#{pe.ifh.NumberOfSections}). not forced, reading first 65535"
        nToRead = 65535
      end
    end
    pe.sections = []
    nToRead.times do
      break if f.eof?
      pe.sections << IMAGE_SECTION_HEADER.read(f)
    end

    if pe.sections.any?
      # zero all missing values of last section
      pe.sections.last.tap do |last_section|
        last_section.each_pair do |k,v|
          last_section[k] = 0 if v.nil?
        end
      end
    end

    pe_end = f.tell
    if s=pe.sections.find{ |s| (pe_offset...pe_end).include?(s.va) }
      if !f.respond_to?(:seek)
        # already called with CompositeIO ?
        logger.error "[!] section with va=0x#{s.va.to_s(16)} overwrites PE header! 2nd time?!"

      elsif pe_end-pe_offset < 0x100_000
        logger.warn "[!] section with va=0x#{s.va.to_s(16)} overwrites PE header! trying to rebuild..."
        f.seek pe_offset
        data = f.read(s.va-pe_offset)
        f.seek s.PointerToRawData
        io = CompositeIO.new(StringIO.new(data), f)
        return PE.read(io, args)
      else
        logger.error "[!] section with va=0x#{s.va.to_s(16)} overwrites PE header! too big to rebuild!"
      end
    end
  end
end

Instance Method Details

#dll?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/pedump/pe.rb', line 17

def dll?
  ifh && ifh.flags.include?('DLL')
end

#packObject



21
22
23
# File 'lib/pedump/pe.rb', line 21

def pack
  signature + ifh.pack + ioh.pack
end

#x64?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/pedump/pe.rb', line 14

def x64?
  ifh && ifh.Machine == 0x8664
end