Module: ElfStructs

Defined in:
lib/mithril/elf_structs.rb

Defined Under Namespace

Classes: ElfIdentification

Constant Summary collapse

ELF_OBJECTS =
[:sym, :rela, :rel, :dyn, :phdr, :shdr, :hdr, :note, :vernaux, :verneed, :verdef, :verdaux, :versym, :elfp_state, :elfp_call, :elfp_data, :elfp_tag, :elfp_header]
Split =
{
  phdr: {
    32 => :phdr32,
    64 => :phdr64
  },
  sym: {
    32 => :sym32,
    64 => :sym64
  }
}

Instance Method Summary collapse

Instance Method Details

#alias_recordtype(from, to) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/mithril/elf_structs.rb', line 14

def alias_recordtype(from,to)
  self.class.class_eval do
    define_method from do  |*args|
      send(to,*args)
    end
  end
end

#bitness(bits) ⇒ Object



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/mithril/elf_structs.rb', line 262

def bitness(bits)    
  @bits = bits
  alias_recordtype :char, :uint8
  case bits
  when 32
    alias_recordtype :word, :uint32
    alias_recordtype :sword, :int32
    alias_recordtype :half, :uint16
    alias_recordtype :off, :uint32
    alias_recordtype :addr, :uint32
    alias_recordtype :xword, :uint32
    alias_recordtype :sxword, :uint32
  when 64
    alias_recordtype :addr, :uint64
    alias_recordtype :off, :uint64
    alias_recordtype :half, :uint16
    alias_recordtype :word, :uint32
    alias_recordtype :sword, :int32
    alias_recordtype :xword, :uint64
    alias_recordtype :sxword, :int64
  else
    raise RuntimeError.new "We only know about 32-bit or 64-bit ELF formats, not about #{bits}"
  end
end

#dynObject

Dynamic structure. The “.dynamic” section contains an array of them.



84
85
86
87
# File 'lib/mithril/elf_structs.rb', line 84

def dyn
  sxword :tag #Entry type.
  addr :val #Address value or raw value
end

#elfp_callObject



230
231
232
233
234
235
236
237
# File 'lib/mithril/elf_structs.rb', line 230

def elfp_call
  uint32 :chunktype, value: 2
  uint32 :from
  uint32 :to
  uint64 :off
  uint16 :parambytes
  uint16 :returnbytes
end

#elfp_dataObject



238
239
240
241
242
243
244
# File 'lib/mithril/elf_structs.rb', line 238

def elfp_data
  uint32 :chunktype, value: 3
  uint32 :from
  uint32 :to
  uint64 :tag
  uint32 :type
end

#elfp_headerObject

ELFP old



218
219
220
221
222
223
224
# File 'lib/mithril/elf_structs.rb', line 218

def elfp_header
  uint32 :chunkcount, value: lambda {states.size + tags.size+ calls.size + data.size}
  array :states, type: @factory.elfp_state
  array :tags, type: @factory.elfp_tag
  array :calls, type: @factory.elfp_call
  array :data, type: @factory.elfp_data
end

#elfp_stateObject



225
226
227
228
229
# File 'lib/mithril/elf_structs.rb', line 225

def elfp_state
  uint32 :chunkid , value: 1 
  uint32 :id
  uint32 :stackid, default_value: 0
end

#elfp_tagObject



245
246
247
248
249
250
# File 'lib/mithril/elf_structs.rb', line 245

def elfp_tag
  uint32 :chunktype, value:4
  uint64 :tag
  uint64 :addr
  uint64 :siz
end

#hdrObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/mithril/elf_structs.rb', line 21

def hdr
   elf_identification :ident
   #end of identification
   half :type #File type.
   half :machine #Machine architecture.
   word :version #ELF format version.
   addr :entry #Entry point.
   off :phoff #Program header file offset.
   off :shoff #Section header file offset.
   word :flags #Architecture-specific flags.
   half :ehsize #Size of ELF header in bytes.
   half :phentsize #Size of program header entry.
   half :phnum #Number of program header entries.
   half :shentsize #Size of section header entry.
   half :shnum #Number of section header entries.
   half :shstrndx #Section name strings section.
end

#noteObject



39
40
41
42
43
44
45
46
# File 'lib/mithril/elf_structs.rb', line 39

def note
  uint32	:namesz, :value => lambda{name.num_bytes}	#Length of name.
  uint32	:descsz, :value => lambda{desc.num_bytes}	# Length of descriptor.
  uint32	:type		# Type of this note.
  string      :name, :read_length => lambda{ (namesz.to_i  * 4 + 3)/4 } # Round up
  string      :desc, :read_length => lambda{ (descsz.to_i  * 4 + 3)/4 }
  attr_accessor :section_name
end

#phdr32Object

FAIL different layout with 32 and 64



63
64
65
66
67
68
69
70
71
72
# File 'lib/mithril/elf_structs.rb', line 63

def phdr32  # FAIL  different layout with 32 and 64
  word :type #Entry type.
  off :off #File offset of contents.
  addr :vaddr #Virtual address in memory image.
  addr :paddr #Physical address (not used).
  xword :filesz #Size of contents in file.
  xword :memsz #Size of contents in memory.
  word :flags #Access permission flags.
  xword :align #Alignment in memory and file.
end

#phdr64Object



73
74
75
76
77
78
79
80
81
82
# File 'lib/mithril/elf_structs.rb', line 73

def phdr64 
  word :type
  word :flags 
  off  :off
  addr :vaddr
  addr :paddr
  xword :filesz
  xword :memsz
  xword :align
end

#relObject



120
121
122
123
124
125
126
127
# File 'lib/mithril/elf_structs.rb', line 120

def rel
  addr :off #Location to be relocated.
  xword :info #Relocation type and symbol index.
  define_method :addend do
    nil
  end
  rel_common
end

#rel_commonObject

Relocations that don’t need an addend field. */



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/mithril/elf_structs.rb', line 90

def rel_common
  case @bits
  when 32
    define_method :sym do 
       info.to_i >> 8
    end
    define_method :type do
      info.to_i & 0xff
    end
    define_method :sym= do |val|
      self.info = type | (val << 8)
    end
    define_method :type= do |val|
      self.info = (val &0xff) | (sym << 8)
    end
  when 64
    define_method :sym do 
       info.to_i >> 32
    end
    define_method :type do
      info.to_i & 0xffffffff
    end
    define_method :sym= do |val|
      self.info = type | (val << 32)
    end
    define_method :type= do |val|
      self.info = (val &0xffffffff) | (sym << 32)
    end      
  end
end

#relaObject

Relocations that need an addend field. */



130
131
132
133
134
135
# File 'lib/mithril/elf_structs.rb', line 130

def rela
  addr :off #Location to be relocated.
  xword :info #Relocation type and symbol index.
  sxword :addend #Addend.
  rel_common
end

#shdrObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/mithril/elf_structs.rb', line 48

def shdr
  word :name #Section name (index into section header string table
  word :type #Section type.
  xword :flags #Section flags.
  addr :vaddr #Address in memory image.
  off :off #Offset in file.
  xword :siz#Size in bytes. Patch: Had to change to siz
  word :link #Index of a related section.
  word :info #Depends on section type.
  xword :addralign #Alignment in bytes.
  xword :entsize #Size of each entry in section.


  attr_accessor :index # So we retain the index after parsing
end

#stringtableObject



202
203
204
# File 'lib/mithril/elf_structs.rb', line 202

def stringtable
  array :strings, :type => :stringz, :initial_length=> 0 
end

#sym32Object



154
155
156
157
158
159
160
161
162
# File 'lib/mithril/elf_structs.rb', line 154

def sym32
  word :name #String table index of name.
  addr :val #Symbol value. PATCH: change to val so as to avoid name conflict
  word :siz #Size of associated object. PATCH: Change to val
  char :info #Type and binding information.
  char :other #Reserved (not used).
  half :shndx #Section index of symbol.
  sym_common
end

#sym64Object



163
164
165
166
167
168
169
170
171
# File 'lib/mithril/elf_structs.rb', line 163

def sym64
  word  :name
  uint8 :info
  uint8 :other
  half  :shndx
  addr  :val
  xword :siz
  sym_common
end

#sym_commonObject

Elf Symbol



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/mithril/elf_structs.rb', line 138

def sym_common
  define_method :type do 
    info & 0xf
  end
  define_method :binding do 
    info >> 4 
  end
  define_method :type= do |val|
    raise RuntimeError.new "Invalid param" unless val & 0xf == val
    self.info = (info&0xf0) | val 
  end 
  define_method :binding= do |val|
    raise RuntimeError.new "Invalid param" unless val & 0xf == val
    self.info = (info&0xf) | (val << 4)
  end
end

#verdauxObject



175
176
177
178
# File 'lib/mithril/elf_structs.rb', line 175

def verdaux
  word :name
  word :nextoff
end

#verdefObject



179
180
181
182
183
184
185
186
187
# File 'lib/mithril/elf_structs.rb', line 179

def verdef
  half :version
  half :flags
  half :ndx
  half :cnt
  word :hsh
  word :aux
  word :nextoff
end

#vernauxObject



195
196
197
198
199
200
201
# File 'lib/mithril/elf_structs.rb', line 195

def vernaux
  word :hsh
  half :flags
  half :other
  word :name
  word :nextoff
end

#verneedObject



188
189
190
191
192
193
194
# File 'lib/mithril/elf_structs.rb', line 188

def verneed
  half :version
  half :cnt
  word :file
  word :aux
  word :nextoff
end

#versymObject



172
173
174
# File 'lib/mithril/elf_structs.rb', line 172

def versym
  half :veridx
end