Class: ELFTools::Structs::ELFStruct
- Inherits:
-
BinData::Record
- Object
- BinData::Record
- ELFTools::Structs::ELFStruct
- Defined in:
- lib/elftools/structs.rb
Overview
The base structure to define common methods.
Direct Known Subclasses
ELF32_Phdr, ELF32_sym, ELF64_Phdr, ELF64_sym, ELF_Dyn, ELF_Ehdr, ELF_Nhdr, ELF_Rel, ELF_Rela, ELF_Shdr
Constant Summary collapse
- CHOICE_SIZE_T =
DRY. Many fields have different type in different arch.
proc do |t = 'uint'| { selection: :elf_class, choices: { 32 => :"#{t}32", 64 => :"#{t}64" }, copy_on_change: true } end
Instance Attribute Summary collapse
-
#elf_class ⇒ Integer
32 or 64.
-
#offset ⇒ Integer
The file offset of this header.
Class Method Summary collapse
-
.new(*args) ⇒ Object
Hooks the constructor.
-
.pack(val, bytes) ⇒ String
Packs an integer to string.
-
.self_endian ⇒ :little, :big
Gets the endianness of current class.
Instance Method Summary collapse
-
#patches ⇒ Hash{Integer => Integer}
Records which fields have been patched.
Instance Attribute Details
#elf_class ⇒ Integer
Returns 32 or 64.
18 19 20 |
# File 'lib/elftools/structs.rb', line 18 def elf_class @elf_class end |
#offset ⇒ Integer
Returns The file offset of this header.
19 20 21 |
# File 'lib/elftools/structs.rb', line 19 def offset @offset end |
Class Method Details
.new(*args) ⇒ Object
Hooks the constructor.
BinData::Record
doesn’t allow us to override #initialize
, so we hack new
here.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/elftools/structs.rb', line 34 def new(*args) # XXX: The better implementation is +new(*args, **kwargs)+, but we can't do this unless bindata changed # lib/bindata/dsl.rb#override_new_in_class to invoke +new+ with both +args+ and +kwargs+. kwargs = args.last.is_a?(Hash) ? args.last : {} offset = kwargs.delete(:offset) super.tap do |obj| obj.offset = offset obj.field_names.each do |f| m = "#{f}=".to_sym old_method = obj.singleton_method(m) obj.singleton_class.send(:undef_method, m) obj.define_singleton_method(m) do |val| org = obj.send(f) obj.patches[org.abs_offset] = ELFStruct.pack(val, org.num_bytes) old_method.call(val) end end end end |
.pack(val, bytes) ⇒ String
Packs an integer to string.
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/elftools/structs.rb', line 64 def pack(val, bytes) raise ArgumentError, "Not supported assign type #{val.class}" unless val.is_a?(Integer) number = val & ((1 << (8 * bytes)) - 1) out = [] bytes.times do out << (number & 0xff) number >>= 8 end out = out.pack('C*') self_endian == :little ? out : out.reverse end |
.self_endian ⇒ :little, :big
Gets the endianness of current class.
56 57 58 |
# File 'lib/elftools/structs.rb', line 56 def self_endian bindata_name[-2..] == 'be' ? :big : :little end |
Instance Method Details
#patches ⇒ Hash{Integer => Integer}
Records which fields have been patched.
23 24 25 |
# File 'lib/elftools/structs.rb', line 23 def patches @patches ||= {} end |