137 lines
2.7 KiB
Ruby
137 lines
2.7 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
# $Id$
|
|
|
|
require 'rex/peparsey/exceptions'
|
|
require 'rex/peparsey/pebase'
|
|
require 'rex/struct2'
|
|
|
|
module Rex
|
|
module PeParsey
|
|
class Section
|
|
attr_accessor :_section_header, :_isource
|
|
attr_accessor :base_rva
|
|
|
|
#
|
|
# Initialize a section.
|
|
#
|
|
# isource - The ImageSource class backing the image
|
|
# base_vma - The address of this section base
|
|
# section_header - The section header (struct2) although this is not
|
|
# required, which is why there is a base_vma. This can be nil.
|
|
#
|
|
def initialize(isource, base_rva, section_header = nil)
|
|
self._isource = isource
|
|
self.base_rva = base_rva
|
|
self._section_header = section_header
|
|
end
|
|
|
|
def file_offset
|
|
_isource.file_offset
|
|
end
|
|
|
|
def size
|
|
_isource.size
|
|
end
|
|
|
|
def name
|
|
# a section header is not required
|
|
return nil if !_section_header
|
|
|
|
# FIXME make this better...
|
|
_section_header.v['Name'].gsub(/\x00+$/, '')
|
|
end
|
|
|
|
def flags
|
|
# a section header is not required
|
|
return nil if !_section_header
|
|
_section_header.v['Characteristics']
|
|
end
|
|
|
|
def vma
|
|
# a section header is not required
|
|
return nil if !_section_header
|
|
_section_header.v['VirtualAddress']
|
|
end
|
|
|
|
def raw_size
|
|
# a section header is not required
|
|
return nil if !_section_header
|
|
_section_header.v['SizeOfRawData']
|
|
end
|
|
|
|
def _check_offset(offset, len = 1)
|
|
if offset < 0 || offset+len > size
|
|
raise BoundsError, "Offset #{offset} outside of section", caller
|
|
end
|
|
end
|
|
|
|
def read(offset, len)
|
|
_check_offset(offset, len)
|
|
return _isource.read(offset, len)
|
|
end
|
|
|
|
def read_rva(rva, len)
|
|
return read(rva_to_offset(rva), len)
|
|
end
|
|
|
|
def read_asciiz(offset)
|
|
_check_offset(offset)
|
|
return _isource.read_asciiz(offset)
|
|
end
|
|
|
|
def read_asciiz_rva(rva)
|
|
return read_asciiz(rva_to_offset(rva))
|
|
end
|
|
|
|
def index(*args)
|
|
_isource.index(*args)
|
|
end
|
|
|
|
def offset_to_rva(offset)
|
|
if !contains_offset?(offset)
|
|
raise BoundsError, "Offset #{offset} outside of section", caller
|
|
end
|
|
|
|
return offset + base_rva
|
|
end
|
|
|
|
def file_offset_to_rva(foffset)
|
|
return offset_to_rva(foffset - file_offset)
|
|
end
|
|
# if offset < 0 || offset < file_offset || offset >= file_offset+size
|
|
# raise BoundsError, "File offset #{offset} outside of section", caller
|
|
# end
|
|
#
|
|
# return (offset - file_offset) + base_rva
|
|
# end
|
|
|
|
def rva_to_offset(rva)
|
|
offset = rva - base_rva
|
|
if !contains_offset?(offset)
|
|
raise BoundsError, "RVA #{rva} outside of section", caller
|
|
end
|
|
|
|
return offset
|
|
end
|
|
|
|
def rva_to_file_offset(rva)
|
|
return rva_to_offset(rva) + file_offset
|
|
end
|
|
|
|
def contains_offset?(offset)
|
|
offset >= 0 && offset < size
|
|
end
|
|
|
|
def contains_file_offset?(foffset)
|
|
contains_offset?(foffset - file_offset)
|
|
end
|
|
|
|
def contains_rva?(rva)
|
|
contains_offset?(rva - base_rva)
|
|
end
|
|
|
|
end
|
|
|
|
end end
|