Class: ELFTools::ELFFile
- Inherits:
-
Object
- Object
- ELFTools::ELFFile
- Defined in:
- lib/elftools/elf_file.rb
Overview
The main class for using elftools.
Instance Attribute Summary collapse
-
#elf_class ⇒ Integer
readonly
32 or 64.
-
#endian ⇒ Symbol
readonly
:little
or:big
. -
#stream ⇒ #pos=, #read
readonly
The
File
object.
Instance Method Summary collapse
-
#build_id ⇒ String?
Return the BuildID of ELF.
-
#each_sections {|section| ... } ⇒ Enumerator<ELFTools::Sections::Section>, Array<ELFTools::Sections::Section>
Iterate all sections.
-
#each_segments {|segment| ... } ⇒ Array<ELFTools::Segments::Segment>
Iterate all segments.
-
#elf_type ⇒ String
Return the ELF type according to
e_type
. -
#header ⇒ ELFTools::Structs::ELF_Ehdr
Return the file header.
-
#initialize(stream) ⇒ ELFFile
constructor
Instantiate an ELFFile object.
-
#machine ⇒ String
Get machine architecture.
-
#num_sections ⇒ Integer
Number of sections in this file.
-
#num_segments ⇒ Integer
Number of segments in this file.
-
#offset_from_vma(vma, size = 1) ⇒ Integer
Get the offset related to file, given virtual memory address.
-
#patches ⇒ Hash{Integer => String}
The patch status.
-
#save(filename) ⇒ void
Apply patches and save as
filename
. -
#section_at(n) ⇒ ELFTools::Sections::Section?
Acquire the
n
-th section, 0-based. -
#section_by_name(name) ⇒ ELFTools::Sections::Section?
Acquire the section named as
name
. -
#sections ⇒ Array<ELFTools::Sections::Section>
Simply use #sections to get all sections.
-
#sections_by_type(type) {|section| ... } ⇒ Array<ELFTools::Sections::section>
Fetch all sections with specific type.
-
#segment_at(n) ⇒ ELFTools::Segments::Segment?
Acquire the
n
-th segment, 0-based. -
#segment_by_type(type) ⇒ ELFTools::Segments::Segment
Get the first segment with p_type=type.
-
#segments ⇒ Array<ELFTools::Segments::Segment>
Simply use #segments to get all segments.
-
#segments_by_type(type) {|segment| ... } ⇒ Array<ELFTools::Segments::Segment>
Fetch all segments with specific type.
-
#strtab_section ⇒ ELFTools::Sections::StrTabSection
Get the string table section.
Constructor Details
#initialize(stream) ⇒ ELFFile
Instantiate an ELFTools::ELFFile object.
24 25 26 27 28 29 |
# File 'lib/elftools/elf_file.rb', line 24 def initialize(stream) @stream = stream # always set binmode if stream is an IO object. @stream.binmode if @stream.respond_to?(:binmode) identify # fetch the most basic information end |
Instance Attribute Details
#elf_class ⇒ Integer (readonly)
Returns 32 or 64.
14 15 16 |
# File 'lib/elftools/elf_file.rb', line 14 def elf_class @elf_class end |
#endian ⇒ Symbol (readonly)
Returns :little
or :big
.
15 16 17 |
# File 'lib/elftools/elf_file.rb', line 15 def endian @endian end |
#stream ⇒ #pos=, #read (readonly)
Returns The File
object.
13 14 15 |
# File 'lib/elftools/elf_file.rb', line 13 def stream @stream end |
Instance Method Details
#build_id ⇒ String?
Return the BuildID of ELF.
52 53 54 55 56 57 58 59 60 |
# File 'lib/elftools/elf_file.rb', line 52 def build_id section = section_by_name('.note.gnu.build-id') return nil if section.nil? note = section.notes.first return nil if note.nil? note.desc.unpack1('H*') end |
#each_sections {|section| ... } ⇒ Enumerator<ELFTools::Sections::Section>, Array<ELFTools::Sections::Section>
Iterate all sections.
All sections are lazy loading, the section only be created whenever accessing it. This method is useful for #section_by_name since not all sections need to be created.
122 123 124 125 126 127 128 |
# File 'lib/elftools/elf_file.rb', line 122 def each_sections(&block) return enum_for(:each_sections) unless block_given? Array.new(num_sections) do |i| section_at(i).tap(&block) end end |
#each_segments {|segment| ... } ⇒ Array<ELFTools::Segments::Segment>
Iterate all segments.
All segments are lazy loading, the segment only be created whenever accessing it. This method is useful for #segment_by_type since not all segments need to be created.
195 196 197 198 199 200 201 |
# File 'lib/elftools/elf_file.rb', line 195 def each_segments(&block) return enum_for(:each_segments) unless block_given? Array.new(num_segments) do |i| segment_at(i).tap(&block) end end |
#elf_type ⇒ String
Return the ELF type according to e_type
.
82 83 84 |
# File 'lib/elftools/elf_file.rb', line 82 def elf_type ELFTools::Constants::ET.mapping(header.e_type) end |
#header ⇒ ELFTools::Structs::ELF_Ehdr
Return the file header.
Lazy loading.
35 36 37 38 39 40 41 42 |
# File 'lib/elftools/elf_file.rb', line 35 def header return @header if defined?(@header) stream.pos = 0 @header = Structs::ELF_Ehdr.new(endian:, offset: stream.pos) @header.elf_class = elf_class @header.read(stream) end |
#machine ⇒ String
Get machine architecture.
Mappings of architecture can be found in Constants::EM.mapping.
71 72 73 |
# File 'lib/elftools/elf_file.rb', line 71 def machine ELFTools::Constants::EM.mapping(header.e_machine) end |
#num_sections ⇒ Integer
Number of sections in this file.
93 94 95 |
# File 'lib/elftools/elf_file.rb', line 93 def num_sections header.e_shnum end |
#num_segments ⇒ Integer
Number of segments in this file.
181 182 183 |
# File 'lib/elftools/elf_file.rb', line 181 def num_segments header.e_phnum end |
#offset_from_vma(vma, size = 1) ⇒ Integer
Get the offset related to file, given virtual memory address.
This method should work no matter ELF is a PIE or not. This method refers from (actually equals to) binutils/readelf.c#offset_from_vma.
293 294 295 296 297 |
# File 'lib/elftools/elf_file.rb', line 293 def offset_from_vma(vma, size = 1) segments_by_type(:load) do |seg| return seg.vma_to_offset(vma) if seg.vma_in?(vma, size) end end |
#patches ⇒ Hash{Integer => String}
The patch status.
301 302 303 304 305 306 307 308 309 |
# File 'lib/elftools/elf_file.rb', line 301 def patches patch = {} loaded_headers.each do |header| header.patches.each do |key, val| patch[key + header.offset] = val end end patch end |
#save(filename) ⇒ void
This method returns an undefined value.
Apply patches and save as filename
.
315 316 317 318 319 320 321 322 |
# File 'lib/elftools/elf_file.rb', line 315 def save(filename) stream.pos = 0 all = stream.read.force_encoding('ascii-8bit') patches.each do |pos, val| all[pos, val.size] = val end File.binwrite(filename, all) end |
#section_at(n) ⇒ ELFTools::Sections::Section?
Acquire the n
-th section, 0-based.
Sections are lazy loaded.
144 145 146 147 |
# File 'lib/elftools/elf_file.rb', line 144 def section_at(n) @sections ||= LazyArray.new(num_sections, &method(:create_section)) @sections[n] end |
#section_by_name(name) ⇒ ELFTools::Sections::Section?
Acquire the section named as name
.
107 108 109 |
# File 'lib/elftools/elf_file.rb', line 107 def section_by_name(name) each_sections.find { |sec| sec.name == name } end |
#sections ⇒ Array<ELFTools::Sections::Section>
Simply use #sections to get all sections.
133 134 135 |
# File 'lib/elftools/elf_file.rb', line 133 def sections each_sections.to_a end |
#sections_by_type(type) {|section| ... } ⇒ Array<ELFTools::Sections::section>
Fetch all sections with specific type.
The available types are listed in Constants::PT. This method accept giving block.
163 164 165 166 |
# File 'lib/elftools/elf_file.rb', line 163 def sections_by_type(type, &block) type = Util.to_constant(Constants::SHT, type) Util.select_by_type(each_sections, type, &block) end |
#segment_at(n) ⇒ ELFTools::Segments::Segment?
Acquire the n
-th segment, 0-based.
Segments are lazy loaded.
278 279 280 281 |
# File 'lib/elftools/elf_file.rb', line 278 def segment_at(n) @segments ||= LazyArray.new(num_segments, &method(:create_segment)) @segments[n] end |
#segment_by_type(type) ⇒ ELFTools::Segments::Segment
This method will return the first segment found, to found all segments with specific type you can use #segments_by_type.
Get the first segment with p_type=type. The available types are listed in Constants::PT.
251 252 253 254 |
# File 'lib/elftools/elf_file.rb', line 251 def segment_by_type(type) type = Util.to_constant(Constants::PT, type) each_segments.find { |seg| seg.header.p_type == type } end |
#segments ⇒ Array<ELFTools::Segments::Segment>
Simply use #segments to get all segments.
206 207 208 |
# File 'lib/elftools/elf_file.rb', line 206 def segments each_segments.to_a end |
#segments_by_type(type) {|segment| ... } ⇒ Array<ELFTools::Segments::Segment>
Fetch all segments with specific type.
If you want to find only one segment, use #segment_by_type instead. This method accept giving block.
266 267 268 269 |
# File 'lib/elftools/elf_file.rb', line 266 def segments_by_type(type, &block) type = Util.to_constant(Constants::PT, type) Util.select_by_type(each_segments, type, &block) end |
#strtab_section ⇒ ELFTools::Sections::StrTabSection
Get the string table section.
This section is acquired by using the e_shstrndx
in ELF header.
173 174 175 |
# File 'lib/elftools/elf_file.rb', line 173 def strtab_section section_at(header.e_shstrndx) end |