Class: PEdump::PE
Instance Attribute Summary collapse
-
#image_file_header ⇒ Object
(also: #ifh)
Returns the value of attribute image_file_header.
-
#image_optional_header ⇒ Object
(also: #ioh)
Returns the value of attribute image_optional_header.
-
#ioh_offset ⇒ Object
Returns the value of attribute ioh_offset.
-
#section_table ⇒ Object
(also: #sections)
Returns the value of attribute section_table.
-
#signature ⇒ Object
Returns the value of attribute signature.
Class Method Summary collapse
Instance Method Summary collapse
Instance Attribute Details
#image_file_header ⇒ Object Also known as: ifh
Returns the value of attribute image_file_header
4 5 6 |
# File 'lib/pedump/pe.rb', line 4 def image_file_header @image_file_header end |
#image_optional_header ⇒ Object Also known as: ioh
Returns the value of attribute image_optional_header
4 5 6 |
# File 'lib/pedump/pe.rb', line 4 def image_optional_header @image_optional_header end |
#ioh_offset ⇒ Object
Returns the value of attribute ioh_offset.
10 11 12 |
# File 'lib/pedump/pe.rb', line 10 def ioh_offset @ioh_offset end |
#section_table ⇒ Object Also known as: sections
Returns the value of attribute section_table
4 5 6 |
# File 'lib/pedump/pe.rb', line 4 def section_table @section_table end |
#signature ⇒ Object
Returns the value of attribute signature
4 5 6 |
# File 'lib/pedump/pe.rb', line 4 def signature @signature end |
Class Method Details
.logger ⇒ Object
112 |
# File 'lib/pedump/pe.rb', line 112 def self.logger; PEdump.logger; end |
.read(f, args = {}) ⇒ Object
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/pedump/pe.rb', line 59 def self.read f, args = {} 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 args[: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 = PE.new(pe_sig) pe.image_file_header = IMAGE_FILE_HEADER.read(f) pe.ioh_offset = f.tell # offset to IMAGE_OPTIONAL_HEADER if pe.ifh.SizeOfOptionalHeader.to_i > 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 nToRead=pe.ifh.NumberOfSections.to_i # The Windows loader expects to find the PE section headers after the optional header. It calculates the address of the first section header by adding SizeOfOptionalHeader to the beginning of the optional header. # // http://www.phreedom.org/research/tinype/ f.seek( pe.ioh_offset + pe.ifh.SizeOfOptionalHeader.to_i ) pe.sections = read_sections(f, nToRead, args) pe_end = f.tell if s=pe.sections.find{ |s| (pe_offset...pe_end).include?(s.va) } if args[:pass2] # already called with CompositeIO ? PEdump.logger.error "[!] section with va=0x#{s.va.to_s(16)} overwrites PE header! 2nd time?!" elsif pe_end-pe_offset < 0x100_000 PEdump.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) args1 = args.dup args1[:pass2] = true return PE.read(io, args1) else PEdump.logger.error "[!] section with va=0x#{s.va.to_s(16)} overwrites PE header! too big to rebuild!" end end pe end |
.read_sections(f, nToRead, args = {}) ⇒ Object
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 |
# File 'lib/pedump/pe.rb', line 29 def self.read_sections f, nToRead, args = {} force = args[:force] if nToRead > 0xffff if force.is_a?(Numeric) && force > 1 PEdump.logger.warn "[!] too many sections (#{nToRead}). forced. reading all" else PEdump.logger.warn "[!] too many sections (#{nToRead}). not forced, reading first 65535" nToRead = 65535 end end sections = [] nToRead.times do break if f.eof? sections << IMAGE_SECTION_HEADER.read(f) end if sections.any? # zero all missing values of last section sections.last.tap do |last_section| last_section.each_pair do |k,v| last_section[k] = 0 if v.nil? end end end sections end |
Instance Method Details
#dll? ⇒ Boolean
21 22 23 |
# File 'lib/pedump/pe.rb', line 21 def dll? ifh && ifh.flags.include?('DLL') end |
#pack ⇒ Object
25 26 27 |
# File 'lib/pedump/pe.rb', line 25 def pack signature + ifh.pack + ioh.pack end |
#x64? ⇒ Boolean
18 19 20 |
# File 'lib/pedump/pe.rb', line 18 def x64? ifh && ifh.Machine == 0x8664 end |