class Metasm::COFF::OptionalHeader
present in linked files (exe/dll/kmod)
Public Instance Methods
decode(coff)
click to toggle source
decodes a COFF
optional header from coff.cursection also decodes directories in coff.directory
Calls superclass method
Metasm::SerialStruct#decode
# File metasm/exe_format/coff_decode.rb, line 19 def decode(coff) return set_default_values(coff) if coff.header.size_opthdr == 0 and not coff.header.characteristics.include?('EXECUTABLE_IMAGE') off = coff.curencoded.ptr super(coff) nrva = (coff.header.size_opthdr - (coff.curencoded.ptr - off)) / 8 nrva = @numrva if nrva < 0 if nrva > DIRECTORIES.length or nrva != @numrva puts "W: COFF: Weird directories count #{@numrva}" if $VERBOSE nrva = DIRECTORIES.length if nrva > DIRECTORIES.length end coff.directory = {} DIRECTORIES[0, nrva].each { |dir| rva = coff.decode_word sz = coff.decode_word if rva != 0 or sz != 0 coff.directory[dir] = [rva, sz] end } end
encode(coff)
click to toggle source
encodes an Optional header and the directories
Calls superclass method
Metasm::SerialStruct#encode
# File metasm/exe_format/coff_encode.rb, line 14 def encode(coff) opth = super(coff) DIRECTORIES[0, @numrva].each { |d| if d = coff.directory[d] d = d.dup d[0] = Expression[d[0], :-, coff.label_at(coff.encoded, 0)] if d[0].kind_of?(::String) else d = [0, 0] end opth << coff.encode_word(d[0]) << coff.encode_word(d[1]) } opth end
set_default_values(coff)
click to toggle source
find good default values for optheader members, based on coff.sections
Calls superclass method
Metasm::SerialStruct#set_default_values
# File metasm/exe_format/coff_encode.rb, line 31 def set_default_values(coff) @signature ||= (coff.bitsize == 64 ? 'PE+' : 'PE') @link_ver_maj ||= 1 @link_ver_min ||= 0 @sect_align ||= 0x1000 align = lambda { |sz| EncodedData.align_size(sz, @sect_align) } @code_size ||= coff.sections.find_all { |s| s.characteristics.include? 'CONTAINS_CODE' }.inject(0) { |sum, s| sum + align[s.virtsize] } @data_size ||= coff.sections.find_all { |s| s.characteristics.include? 'CONTAINS_DATA' }.inject(0) { |sum, s| sum + align[s.virtsize] } @udata_size ||= coff.sections.find_all { |s| s.characteristics.include? 'CONTAINS_UDATA' }.inject(0) { |sum, s| sum + align[s.virtsize] } @entrypoint = Expression[@entrypoint, :-, coff.label_at(coff.encoded, 0)] if entrypoint and not @entrypoint.kind_of?(::Integer) tmp = coff.sections.find { |s| s.characteristics.include? 'CONTAINS_CODE' } @base_of_code ||= (tmp ? Expression[coff.label_at(tmp.encoded, 0), :-, coff.label_at(coff.encoded, 0)] : 0) tmp = coff.sections.find { |s| s.characteristics.include? 'CONTAINS_DATA' } @base_of_data ||= (tmp ? Expression[coff.label_at(tmp.encoded, 0), :-, coff.label_at(coff.encoded, 0)] : 0) @file_align ||= 0x200 @os_ver_maj ||= 4 @subsys_maj ||= 4 @stack_reserve||= 0x100000 @stack_commit ||= 0x1000 @heap_reserve ||= 0x100000 @heap_commit ||= 0x1000 @numrva ||= DIRECTORIES.length super(coff) end