elftools 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -15
- data/lib/elftools/constants.rb +91 -84
- data/lib/elftools/dynamic.rb +23 -24
- data/lib/elftools/elf_file.rb +25 -30
- data/lib/elftools/exceptions.rb +1 -0
- data/lib/elftools/lazy_array.rb +4 -3
- data/lib/elftools/note.rb +28 -20
- data/lib/elftools/sections/relocation_section.rb +6 -8
- data/lib/elftools/sections/section.rb +2 -2
- data/lib/elftools/sections/sections.rb +1 -1
- data/lib/elftools/sections/sym_tab_section.rb +23 -23
- data/lib/elftools/segments/segment.rb +2 -2
- data/lib/elftools/segments/segments.rb +1 -1
- data/lib/elftools/structs.rb +4 -1
- data/lib/elftools/util.rb +4 -4
- data/lib/elftools/version.rb +2 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b27e4fd08cf348de961dde3f2c606719558c031
|
4
|
+
data.tar.gz: b7822186925f38be8a76aeb9961a0484ee0cc2bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a0d0993f509e82c87c97776282057fe61ff8076018714da50ecc9c928e8b3863e7481a2ababf7ae56cb02d75dc03d5783f8d2bdf4b890b535075bed00f53bac
|
7
|
+
data.tar.gz: 591568c22193ada4c48874c276bde8cdb5c5587268f67e440c48b8968db395d9730888bd5d452e6f002e383e65e0a0dfb9bc7b6682b6e960bc84daa80f1cab15
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
[](https://travis-ci.org/david942j/rbelftools)
|
2
|
+
[](https://ci.appveyor.com/project/david942j/rbelftools)
|
2
3
|
[](https://codeclimate.com/github/david942j/rbelftools)
|
3
4
|
[](https://codeclimate.com/github/david942j/rbelftools)
|
4
5
|
[](https://codeclimate.com/github/david942j/rbelftools/coverage)
|
@@ -11,7 +12,7 @@ ELF parser in pure ruby implementation. This work is inspired by [pyelftools](ht
|
|
11
12
|
|
12
13
|
The motivation to create this repository is want to be a dependency of [pwntools-ruby](https://github.com/peter50216/pwntools-ruby). Since ELF parser is a big work, it should not be implemented directly in pwntools.
|
13
14
|
|
14
|
-
**rbelftools**'s target is to create a nice ELF parser library in ruby. More features
|
15
|
+
**rbelftools**'s target is to create a nice ELF parser library in ruby. More features remain a work in progress.
|
15
16
|
|
16
17
|
# Install
|
17
18
|
|
@@ -70,7 +71,7 @@ symtab_section.num_symbols
|
|
70
71
|
|
71
72
|
symtab_section.symbol_by_name('puts@@GLIBC_2.2.5')
|
72
73
|
#=>
|
73
|
-
# #<ELFTools::Symbol:0x00560b14af67a0
|
74
|
+
# #<ELFTools::Sections::Symbol:0x00560b14af67a0
|
74
75
|
# @header={:st_name=>348, :st_info=>18, :st_other=>0, :st_shndx=>0, :st_value=>0, :st_size=>0},
|
75
76
|
# @name="puts@@GLIBC_2.2.5">
|
76
77
|
|
@@ -115,26 +116,21 @@ relocations.map { |r| symtab.symbol_at(r.symbol_index).name }
|
|
115
116
|
|
116
117
|
# Why rbelftools
|
117
118
|
|
118
|
-
1. Fully documented
|
119
|
-
|
119
|
+
1. Fully documented
|
120
120
|
Always important for an Open-Source project. Online document is [here](http://www.rubydoc.info/github/david942j/rbelftools/master/frames)
|
121
|
-
2. Fully tested
|
122
|
-
|
121
|
+
2. Fully tested
|
123
122
|
Of course.
|
124
|
-
3. Lazy loading on everything
|
125
|
-
|
123
|
+
3. Lazy loading on everything
|
126
124
|
To use **rbelftools**, only need to pass the stream object of ELF file.
|
127
125
|
**rbelftools** will read the stream object **as least times as possible** when parsing
|
128
126
|
the file. Most information will not be fetched until you need it, which makes
|
129
127
|
**rbelftools** efficient.
|
130
|
-
4. To be a library
|
131
|
-
|
132
|
-
**rbelftools** is designed to be a library for furthur usage.
|
128
|
+
4. To be a library
|
129
|
+
**rbelftools** is designed to be a library for further usage.
|
133
130
|
It will _not_ add any too trivial features.
|
134
131
|
For example, to check if NX disabled, you can use
|
135
132
|
`!elf.segment_by_type(:gnu_stack).executable?` but not `elf.nx?`
|
136
|
-
5. Section and segment parser
|
137
|
-
|
133
|
+
5. Section and segment parser
|
138
134
|
Providing common sections and segments parser. For example, .symtab, .shstrtab
|
139
135
|
.dynamic sections and INTERP, DYNAMIC segments, etc.
|
140
136
|
|
@@ -143,12 +139,12 @@ relocations.map { |r| symtab.symbol_at(r.symbol_index).name }
|
|
143
139
|
git clone https://github.com/david942j/rbelftools.git
|
144
140
|
cd rbelftools
|
145
141
|
bundle
|
146
|
-
rake
|
142
|
+
bundle exec rake
|
147
143
|
```
|
148
144
|
Any comments or suggestions are welcome!
|
149
145
|
|
150
146
|
# Cross Platform
|
151
|
-
**rbelftools** can be used
|
147
|
+
**rbelftools** can be used and has been fully tested on all platforms include Linux, OSX, and Windows!
|
152
148
|
|
153
149
|
# License
|
154
150
|
MIT License
|
data/lib/elftools/constants.rb
CHANGED
@@ -8,110 +8,117 @@ module ELFTools
|
|
8
8
|
|
9
9
|
# Section header types, records in +sh_type+.
|
10
10
|
module SHT
|
11
|
-
SHT_NULL = 0
|
12
|
-
SHT_PROGBITS = 1
|
13
|
-
SHT_SYMTAB = 2
|
14
|
-
SHT_STRTAB = 3
|
15
|
-
SHT_RELA = 4
|
16
|
-
SHT_HASH = 5
|
17
|
-
SHT_DYNAMIC = 6
|
18
|
-
SHT_NOTE = 7
|
19
|
-
SHT_NOBITS = 8
|
20
|
-
SHT_REL = 9
|
21
|
-
SHT_SHLIB = 10
|
22
|
-
SHT_DYNSYM = 11
|
23
|
-
|
11
|
+
SHT_NULL = 0 # null section
|
12
|
+
SHT_PROGBITS = 1 # information defined by program itself
|
13
|
+
SHT_SYMTAB = 2 # symbol table section
|
14
|
+
SHT_STRTAB = 3 # string table section
|
15
|
+
SHT_RELA = 4 # relocation with addends
|
16
|
+
SHT_HASH = 5 # symbol hash table
|
17
|
+
SHT_DYNAMIC = 6 # information of dynamic linking
|
18
|
+
SHT_NOTE = 7 # note section
|
19
|
+
SHT_NOBITS = 8 # section occupies no space
|
20
|
+
SHT_REL = 9 # relocation
|
21
|
+
SHT_SHLIB = 10 # reserved
|
22
|
+
SHT_DYNSYM = 11 # symbols for dynamic
|
23
|
+
# Values between {SHT_LOPROC} and {SHT_HIPROC} are reserved for processor-specific semantics.
|
24
24
|
SHT_LOPROC = 0x70000000
|
25
|
-
SHT_HIPROC = 0x7fffffff
|
25
|
+
SHT_HIPROC = 0x7fffffff # see {SHT_LOPROC}
|
26
|
+
# Values between {SHT_LOUSER} and {SHT_HIUSER} are reserved for application programs.
|
26
27
|
SHT_LOUSER = 0x80000000
|
27
|
-
SHT_HIUSER = 0xffffffff
|
28
|
+
SHT_HIUSER = 0xffffffff # see {SHT_LOUSER}
|
28
29
|
end
|
29
30
|
include SHT
|
30
31
|
|
31
32
|
# Program header types, records in +p_type+.
|
32
33
|
module PT
|
33
|
-
PT_NULL = 0
|
34
|
-
PT_LOAD = 1
|
35
|
-
PT_DYNAMIC = 2
|
36
|
-
PT_INTERP = 3
|
37
|
-
PT_NOTE = 4
|
38
|
-
PT_SHLIB = 5
|
39
|
-
PT_PHDR = 6
|
40
|
-
PT_TLS = 7 #
|
34
|
+
PT_NULL = 0 # null segment
|
35
|
+
PT_LOAD = 1 # segment to be load
|
36
|
+
PT_DYNAMIC = 2 # dynamic tags
|
37
|
+
PT_INTERP = 3 # interpreter, same as .interp section
|
38
|
+
PT_NOTE = 4 # same as .note* section
|
39
|
+
PT_SHLIB = 5 # reserved
|
40
|
+
PT_PHDR = 6 # where program header starts
|
41
|
+
PT_TLS = 7 # thread local storage segment
|
41
42
|
PT_LOOS = 0x60000000 # OS-specific
|
42
43
|
PT_HIOS = 0x6fffffff # OS-specific
|
44
|
+
# Values between {PT_LOPROC} and {PT_HIPROC} are reserved for processor-specific semantics.
|
43
45
|
PT_LOPROC = 0x70000000
|
44
|
-
PT_HIPROC = 0x7fffffff
|
45
|
-
PT_GNU_EH_FRAME = 0x6474e550
|
46
|
-
PT_GNU_STACK = 0x6474e551
|
47
|
-
PT_GNU_RELRO = 0x6474e552 #
|
46
|
+
PT_HIPROC = 0x7fffffff # see {PT_LOPROC}
|
47
|
+
PT_GNU_EH_FRAME = 0x6474e550 # for exception handler
|
48
|
+
PT_GNU_STACK = 0x6474e551 # permission of stack
|
49
|
+
PT_GNU_RELRO = 0x6474e552 # read only after relocation
|
48
50
|
end
|
49
51
|
include PT
|
50
52
|
|
51
53
|
# Dynamic table types, records in +d_tag+.
|
52
54
|
module DT
|
53
|
-
DT_NULL = 0
|
54
|
-
DT_NEEDED = 1
|
55
|
-
DT_PLTRELSZ = 2
|
56
|
-
DT_PLTGOT = 3
|
57
|
-
DT_HASH = 4
|
58
|
-
DT_STRTAB = 5
|
59
|
-
DT_SYMTAB = 6
|
60
|
-
DT_RELA = 7
|
61
|
-
DT_RELASZ = 8
|
62
|
-
DT_RELAENT = 9
|
63
|
-
DT_STRSZ = 10
|
64
|
-
DT_SYMENT = 11
|
65
|
-
DT_INIT = 12
|
66
|
-
DT_FINI = 13
|
67
|
-
DT_SONAME = 14
|
68
|
-
DT_RPATH = 15
|
69
|
-
DT_SYMBOLIC = 16
|
70
|
-
DT_REL = 17
|
71
|
-
DT_RELSZ = 18
|
72
|
-
DT_RELENT = 19
|
73
|
-
DT_PLTREL = 20
|
74
|
-
DT_DEBUG = 21
|
75
|
-
DT_TEXTREL = 22
|
76
|
-
DT_JMPREL = 23
|
77
|
-
DT_BIND_NOW = 24
|
78
|
-
DT_INIT_ARRAY = 25
|
79
|
-
DT_FINI_ARRAY = 26
|
80
|
-
DT_INIT_ARRAYSZ = 27
|
81
|
-
DT_FINI_ARRAYSZ = 28
|
82
|
-
DT_RUNPATH = 29
|
83
|
-
DT_FLAGS = 30
|
84
|
-
DT_ENCODING = 32
|
55
|
+
DT_NULL = 0 # marks the end of the _DYNAMIC array
|
56
|
+
DT_NEEDED = 1 # libraries need to be linked by loader
|
57
|
+
DT_PLTRELSZ = 2 # total size of relocation entries
|
58
|
+
DT_PLTGOT = 3 # address of procedure linkage table or global offset table
|
59
|
+
DT_HASH = 4 # address of symbol hash table
|
60
|
+
DT_STRTAB = 5 # address of string table
|
61
|
+
DT_SYMTAB = 6 # address of symbol table
|
62
|
+
DT_RELA = 7 # address of a relocation table
|
63
|
+
DT_RELASZ = 8 # total size of the {DT_RELA} table
|
64
|
+
DT_RELAENT = 9 # size of each entry in the {DT_RELA} table
|
65
|
+
DT_STRSZ = 10 # total size of {DT_STRTAB}
|
66
|
+
DT_SYMENT = 11 # size of each entry in {DT_SYMTAB}
|
67
|
+
DT_INIT = 12 # where the initialization function is
|
68
|
+
DT_FINI = 13 # where the termination function is
|
69
|
+
DT_SONAME = 14 # the shared object name
|
70
|
+
DT_RPATH = 15 # has been superseded by {DT_RUNPATH}
|
71
|
+
DT_SYMBOLIC = 16 # has been superseded by the DF_SYMBOLIC flag
|
72
|
+
DT_REL = 17 # similar to {DT_RELA}
|
73
|
+
DT_RELSZ = 18 # total size of the {DT_REL} table
|
74
|
+
DT_RELENT = 19 # size of each entry in the {DT_REL} table
|
75
|
+
DT_PLTREL = 20 # type of relocation entry, either {DT_REL} or {DT_RELA}
|
76
|
+
DT_DEBUG = 21 # for debugging
|
77
|
+
DT_TEXTREL = 22 # has been superseded by the DF_TEXTREL flag
|
78
|
+
DT_JMPREL = 23 # address of relocation entries that are associated solely with the procedure linkage table
|
79
|
+
DT_BIND_NOW = 24 # if the loader needs to do relocate now, superseded by the DF_BIND_NOW flag
|
80
|
+
DT_INIT_ARRAY = 25 # address init array
|
81
|
+
DT_FINI_ARRAY = 26 # address of fini array
|
82
|
+
DT_INIT_ARRAYSZ = 27 # total size of init array
|
83
|
+
DT_FINI_ARRAYSZ = 28 # total size of fini array
|
84
|
+
DT_RUNPATH = 29 # path of libraries for searching
|
85
|
+
DT_FLAGS = 30 # flags
|
86
|
+
DT_ENCODING = 32 # just a lower bound
|
87
|
+
# Values between {DT_LOOS} and {DT_HIOS} are reserved for operating system-specific semantics.
|
85
88
|
DT_LOOS = 0x6000000d
|
86
|
-
DT_HIOS = 0x6ffff000
|
89
|
+
DT_HIOS = 0x6ffff000 # see {DT_LOOS}
|
90
|
+
# Values between {DT_VALRNGLO} and {DT_VALRNGHI} use the +d_un.d_val+ field of the dynamic structure.
|
87
91
|
DT_VALRNGLO = 0x6ffffd00
|
88
|
-
DT_VALRNGHI = 0x6ffffdff
|
92
|
+
DT_VALRNGHI = 0x6ffffdff # see {DT_VALRNGLO}
|
93
|
+
# Values between {DT_ADDRRNGLO} and {DT_ADDRRNGHI} use the +d_un.d_ptr+ field of the dynamic structure.
|
89
94
|
DT_ADDRRNGLO = 0x6ffffe00
|
90
|
-
|
91
|
-
|
92
|
-
DT_RELACOUNT = 0x6ffffff9
|
93
|
-
DT_RELCOUNT = 0x6ffffffa
|
94
|
-
DT_FLAGS_1 = 0x6ffffffb
|
95
|
-
DT_VERDEF = 0x6ffffffc
|
96
|
-
DT_VERDEFNUM = 0x6ffffffd
|
97
|
-
DT_VERNEED = 0x6ffffffe
|
98
|
-
DT_VERNEEDNUM = 0x6fffffff
|
95
|
+
DT_GNU_HASH = 0x6ffffef5 # the gnu hash
|
96
|
+
DT_ADDRRNGHI = 0x6ffffeff # see {DT_ADDRRNGLO}
|
97
|
+
DT_RELACOUNT = 0x6ffffff9 # relative relocation count
|
98
|
+
DT_RELCOUNT = 0x6ffffffa # relative relocation count
|
99
|
+
DT_FLAGS_1 = 0x6ffffffb # flags
|
100
|
+
DT_VERDEF = 0x6ffffffc # address of version definition table
|
101
|
+
DT_VERDEFNUM = 0x6ffffffd # number of entries in {DT_VERDEF}
|
102
|
+
DT_VERNEED = 0x6ffffffe # address of version dependency table
|
103
|
+
DT_VERNEEDNUM = 0x6fffffff # number of entries in {DT_VERNEED}
|
104
|
+
# Values between {DT_LOPROC} and {DT_HIPROC} are reserved for processor-specific semantics.
|
99
105
|
DT_LOPROC = 0x70000000
|
100
|
-
DT_HIPROC = 0x7fffffff
|
106
|
+
DT_HIPROC = 0x7fffffff # see {DT_LOPROC}
|
101
107
|
end
|
102
108
|
include DT
|
103
109
|
|
104
110
|
# These constants define the various ELF target machines.
|
105
111
|
module EM
|
106
|
-
EM_NONE = 0
|
107
|
-
EM_M32 = 1
|
108
|
-
EM_SPARC = 2
|
109
|
-
EM_386 = 3
|
110
|
-
EM_68K = 4
|
111
|
-
EM_88K = 5
|
112
|
-
EM_486 = 6 #
|
113
|
-
EM_860 = 7
|
112
|
+
EM_NONE = 0 # none
|
113
|
+
EM_M32 = 1 # AT&T WE 32100
|
114
|
+
EM_SPARC = 2 # SPARC
|
115
|
+
EM_386 = 3 # Intel 80386
|
116
|
+
EM_68K = 4 # Motorola 68000
|
117
|
+
EM_88K = 5 # Motorola 88000
|
118
|
+
EM_486 = 6 # Intel 80486
|
119
|
+
EM_860 = 7 # Intel 80860
|
114
120
|
EM_MIPS = 8 # MIPS R3000 (officially, big-endian only)
|
121
|
+
|
115
122
|
# Next two are historical and binaries and
|
116
123
|
# modules of these types will be rejected by Linux.
|
117
124
|
EM_MIPS_RS3_LE = 10 # MIPS R3000 little-endian
|
@@ -190,11 +197,11 @@ module ELFTools
|
|
190
197
|
|
191
198
|
# This module defines elf file types.
|
192
199
|
module ET
|
193
|
-
ET_NONE = 0
|
194
|
-
ET_REL = 1
|
195
|
-
ET_EXEC = 2
|
196
|
-
ET_DYN = 3
|
197
|
-
ET_CORE = 4
|
200
|
+
ET_NONE = 0 # no file type
|
201
|
+
ET_REL = 1 # relocatable file
|
202
|
+
ET_EXEC = 2 # executable file
|
203
|
+
ET_DYN = 3 # shared object
|
204
|
+
ET_CORE = 4 # core file
|
198
205
|
# Return the type name according to +e_type+ in ELF file header.
|
199
206
|
# @return [String] Type in string format.
|
200
207
|
def self.mapping(type)
|
data/lib/elftools/dynamic.rb
CHANGED
@@ -1,28 +1,26 @@
|
|
1
1
|
module ELFTools
|
2
|
-
# Define common methods for dynamic sections and
|
3
|
-
# dynamic segments.
|
2
|
+
# Define common methods for dynamic sections and dynamic segments.
|
4
3
|
#
|
5
|
-
#
|
6
|
-
# {ELFTools::Sections::DynamicSection}
|
7
|
-
# {ELFTools::Segments::DynamicSegment} because
|
8
|
-
#
|
4
|
+
# @note
|
5
|
+
# This module can only be included by {ELFTools::Sections::DynamicSection}
|
6
|
+
# and {ELFTools::Segments::DynamicSegment} because methods here assume some
|
7
|
+
# attributes exist.
|
9
8
|
module Dynamic
|
10
9
|
# Iterate all tags.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
# already exist:
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# @
|
11
|
+
# @note
|
12
|
+
# This method assume the following methods already exist:
|
13
|
+
# header
|
14
|
+
# tag_start
|
15
|
+
# @yieldparam [ELFTools::Dynamic::Tag] tag
|
17
16
|
# @return [Enumerator<ELFTools::Dynamic::Tag>, Array<ELFTools::Dynamic::Tag>]
|
18
17
|
# If block is not given, an enumerator will be returned.
|
19
18
|
# Otherwise, return array of tags.
|
20
|
-
def each_tags
|
19
|
+
def each_tags(&block)
|
21
20
|
return enum_for(:each_tags) unless block_given?
|
22
21
|
arr = []
|
23
22
|
0.step do |i|
|
24
|
-
tag = tag_at(i)
|
25
|
-
yield tag
|
23
|
+
tag = tag_at(i).tap(&block)
|
26
24
|
arr << tag
|
27
25
|
break if tag.header.d_tag == ELFTools::Constants::DT_NULL
|
28
26
|
end
|
@@ -68,13 +66,13 @@ module ELFTools
|
|
68
66
|
# Get the +n+-th tag.
|
69
67
|
#
|
70
68
|
# Tags are lazy loaded.
|
71
|
-
#
|
72
|
-
# already exist:
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
69
|
+
# @note
|
70
|
+
# This method assume the following methods already exist:
|
71
|
+
# header
|
72
|
+
# tag_start
|
73
|
+
# @note
|
74
|
+
# We cannot do bound checking of +n+ here since the only way to get size
|
75
|
+
# of tags is calling +tags.size+.
|
78
76
|
# @param [Integer] n The index.
|
79
77
|
# @return [ELFTools::Dynamic::Tag] The desired tag.
|
80
78
|
def tag_at(n)
|
@@ -102,11 +100,11 @@ module ELFTools
|
|
102
100
|
# A tag class.
|
103
101
|
class Tag
|
104
102
|
attr_reader :header # @return [ELFTools::Structs::ELF_Dyn] The dynamic tag header.
|
105
|
-
attr_reader :stream # @return [
|
103
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
106
104
|
|
107
105
|
# Instantiate a {ELFTools::Dynamic::Tag} object.
|
108
106
|
# @param [ELF_Dyn] header The dynamic tag header.
|
109
|
-
# @param [
|
107
|
+
# @param [#pos=, #read] stream Streaming object.
|
110
108
|
# @param [Method] str_offset
|
111
109
|
# Call this method to get the string offset related
|
112
110
|
# to file.
|
@@ -116,6 +114,7 @@ module ELFTools
|
|
116
114
|
@str_offset = str_offset
|
117
115
|
end
|
118
116
|
|
117
|
+
# Some dynamic have name.
|
119
118
|
TYPE_WITH_NAME = [Constants::DT_NEEDED,
|
120
119
|
Constants::DT_SONAME,
|
121
120
|
Constants::DT_RPATH,
|
@@ -150,7 +149,7 @@ module ELFTools
|
|
150
149
|
#
|
151
150
|
# Only tags with name would return a name.
|
152
151
|
# Others would return +nil+.
|
153
|
-
# @return [String,
|
152
|
+
# @return [String, nil] The name.
|
154
153
|
def name
|
155
154
|
return nil unless name?
|
156
155
|
Util.cstring(stream, @str_offset.call + header.d_val.to_i)
|
data/lib/elftools/elf_file.rb
CHANGED
@@ -8,13 +8,13 @@ require 'elftools/structs'
|
|
8
8
|
module ELFTools
|
9
9
|
# The main class for using elftools.
|
10
10
|
class ELFFile
|
11
|
-
attr_reader :stream # @return [
|
11
|
+
attr_reader :stream # @return [#pos=, #read] The +File+ object.
|
12
12
|
attr_reader :elf_class # @return [Integer] 32 or 64.
|
13
13
|
attr_reader :endian # @return [Symbol] +:little+ or +:big+.
|
14
14
|
|
15
15
|
# Instantiate an {ELFFile} object.
|
16
16
|
#
|
17
|
-
# @param [
|
17
|
+
# @param [#pos=, #read] stream
|
18
18
|
# The +File+ object to be fetch information from.
|
19
19
|
# @example
|
20
20
|
# ELFFile.new(File.open('/bin/cat'))
|
@@ -27,7 +27,7 @@ module ELFTools
|
|
27
27
|
# Return the file header.
|
28
28
|
#
|
29
29
|
# Lazy loading.
|
30
|
-
# @
|
30
|
+
# @return [ELFTools::Structs::ELF_Ehdr] The header.
|
31
31
|
def header
|
32
32
|
return @header if defined?(@header)
|
33
33
|
stream.pos = 0
|
@@ -37,7 +37,7 @@ module ELFTools
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# Return the BuildID of ELF.
|
40
|
-
# @return [String,
|
40
|
+
# @return [String, nil]
|
41
41
|
# BuildID in hex form will be returned.
|
42
42
|
# +nil+ is returned if the .note.gnu.build-id section
|
43
43
|
# is not found.
|
@@ -52,7 +52,7 @@ module ELFTools
|
|
52
52
|
note.desc.unpack('H*').first
|
53
53
|
end
|
54
54
|
|
55
|
-
# Get
|
55
|
+
# Get machine architecture.
|
56
56
|
#
|
57
57
|
# Mappings of architecture can be found
|
58
58
|
# in {ELFTools::Constants::EM.mapping}.
|
@@ -89,7 +89,7 @@ module ELFTools
|
|
89
89
|
|
90
90
|
# Acquire the section named as +name+.
|
91
91
|
# @param [String] name The desired section name.
|
92
|
-
# @return [ELFTools::Sections::Section,
|
92
|
+
# @return [ELFTools::Sections::Section, nil] The target section.
|
93
93
|
# @example
|
94
94
|
# elf.section_by_name('.note.gnu.build-id')
|
95
95
|
# #=> #<ELFTools::Sections::Section:0x005647b1282428>
|
@@ -107,17 +107,15 @@ module ELFTools
|
|
107
107
|
# only be created whenever accessing it.
|
108
108
|
# This method is useful for {#section_by_name}
|
109
109
|
# since not all sections need to be created.
|
110
|
-
# @
|
111
|
-
#
|
110
|
+
# @yieldparam [ELFTools::Sections::Section] section A section.
|
111
|
+
# @yieldreturn [void]
|
112
112
|
# @return [Enumerator<ELFTools::Sections::Section>, Array<ELFTools::Sections::Section>]
|
113
113
|
# As +Array#each+, if block is not given, a enumerator will be returned,
|
114
114
|
# otherwise, the whole sections will be returned.
|
115
|
-
def each_sections
|
115
|
+
def each_sections(&block)
|
116
116
|
return enum_for(:each_sections) unless block_given?
|
117
117
|
Array.new(num_sections) do |i|
|
118
|
-
|
119
|
-
yield sec
|
120
|
-
sec
|
118
|
+
section_at(i).tap(&block)
|
121
119
|
end
|
122
120
|
end
|
123
121
|
|
@@ -132,7 +130,7 @@ module ELFTools
|
|
132
130
|
#
|
133
131
|
# Sections are lazy loaded.
|
134
132
|
# @param [Integer] n The index.
|
135
|
-
# @return [ELFTools::Sections::Section,
|
133
|
+
# @return [ELFTools::Sections::Section, nil]
|
136
134
|
# The target section.
|
137
135
|
# If +n+ is out of bound, +nil+ is returned.
|
138
136
|
def section_at(n)
|
@@ -142,13 +140,12 @@ module ELFTools
|
|
142
140
|
|
143
141
|
# Fetch all sections with specific type.
|
144
142
|
#
|
145
|
-
# The available types are listed in {ELFTools::Constants}
|
146
|
-
# start with +SHT_+.
|
143
|
+
# The available types are listed in {ELFTools::Constants::PT}.
|
147
144
|
# This method accept giving block.
|
148
145
|
# @param [Integer, Symbol, String] type
|
149
146
|
# The type needed, similar format as {#segment_by_type}.
|
150
|
-
# @
|
151
|
-
#
|
147
|
+
# @yieldparam [ELFTools::Sections::Section] section A section in specific type.
|
148
|
+
# @yieldreturn [void]
|
152
149
|
# @return [Array<ELFTools::Sections::section>] The target sections.
|
153
150
|
# @example
|
154
151
|
# elf = ELFTools::ELFFile.new(File.open('spec/files/amd64.elf'))
|
@@ -183,16 +180,14 @@ module ELFTools
|
|
183
180
|
# only be created whenever accessing it.
|
184
181
|
# This method is useful for {#segment_by_type}
|
185
182
|
# since not all segments need to be created.
|
186
|
-
# @
|
187
|
-
#
|
183
|
+
# @yieldparam [ELFTools::Segments::Segment] segment A segment.
|
184
|
+
# @yieldreturn [void]
|
188
185
|
# @return [Array<ELFTools::Segments::Segment>]
|
189
186
|
# Whole segments will be returned.
|
190
|
-
def each_segments
|
187
|
+
def each_segments(&block)
|
191
188
|
return enum_for(:each_segments) unless block_given?
|
192
189
|
Array.new(num_segments) do |i|
|
193
|
-
|
194
|
-
yield seg
|
195
|
-
seg
|
190
|
+
segment_at(i).tap(&block)
|
196
191
|
end
|
197
192
|
end
|
198
193
|
|
@@ -204,11 +199,11 @@ module ELFTools
|
|
204
199
|
end
|
205
200
|
|
206
201
|
# Get the first segment with +p_type=type+.
|
207
|
-
# The available types are listed in {ELFTools::Constants}
|
208
|
-
# start with +PT_+.
|
202
|
+
# The available types are listed in {ELFTools::Constants::PT}.
|
209
203
|
#
|
210
|
-
#
|
211
|
-
#
|
204
|
+
# @note
|
205
|
+
# This method will return the first segment found,
|
206
|
+
# to found all segments with specific type you can use {#segments_by_type}.
|
212
207
|
# @param [Integer, Symbol, String] type
|
213
208
|
# See examples for clear usage.
|
214
209
|
# @return [ELFTools::Segments::Segment] The target segment.
|
@@ -256,8 +251,8 @@ module ELFTools
|
|
256
251
|
# This method accept giving block.
|
257
252
|
# @param [Integer, Symbol, String] type
|
258
253
|
# The type needed, same format as {#segment_by_type}.
|
259
|
-
# @
|
260
|
-
#
|
254
|
+
# @yieldparam [ELFTools::Segments::Segment] segment A segment in specific type.
|
255
|
+
# @yieldreturn [void]
|
261
256
|
# @return [Array<ELFTools::Segments::Segment>] The target segments.
|
262
257
|
def segments_by_type(type, &block)
|
263
258
|
type = Util.to_constant(Constants::PT, type)
|
@@ -268,7 +263,7 @@ module ELFTools
|
|
268
263
|
#
|
269
264
|
# Segments are lazy loaded.
|
270
265
|
# @param [Integer] n The index.
|
271
|
-
# @return [ELFTools::Segments::Segment,
|
266
|
+
# @return [ELFTools::Segments::Segment, nil]
|
272
267
|
# The target segment.
|
273
268
|
# If +n+ is out of bound, +nil+ is returned.
|
274
269
|
def segment_at(n)
|
data/lib/elftools/exceptions.rb
CHANGED
data/lib/elftools/lazy_array.rb
CHANGED
@@ -7,9 +7,10 @@ module ELFTools
|
|
7
7
|
# Instantiate a {LazyArray} object.
|
8
8
|
# @param [Integer] size
|
9
9
|
# The size of array.
|
10
|
-
# @
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# @yieldparam [Integer] i
|
11
|
+
# Needs +i+-th element.
|
12
|
+
# @yieldreturn [Object]
|
13
|
+
# Value of the +i+-th element.
|
13
14
|
# @example
|
14
15
|
# arr = LazyArray.new(10) { |i| p i; i * i }
|
15
16
|
# p arr[2]
|
data/lib/elftools/note.rb
CHANGED
@@ -2,17 +2,18 @@ require 'elftools/structs'
|
|
2
2
|
require 'elftools/util'
|
3
3
|
|
4
4
|
module ELFTools
|
5
|
-
# Since both note sections and note segments
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# Since both note sections and note segments refer to notes, this module
|
6
|
+
# defines common methods for {ELFTools::Sections::NoteSection} and
|
7
|
+
# {ELFTools::Segments::NoteSegment}.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# @note
|
10
|
+
# This module can only be included in {ELFTools::Sections::NoteSection} and
|
11
|
+
# {ELFTools::Segments::NoteSegment} since some methods here assume some
|
12
|
+
# attributes already exist.
|
12
13
|
module Note
|
13
|
-
# Since size of {ELFTools::Structs::ELF_Nhdr} will not change no
|
14
|
-
#
|
15
|
-
#
|
14
|
+
# Since size of {ELFTools::Structs::ELF_Nhdr} will not change no matter in
|
15
|
+
# what endian and what arch, we can do this here. This value should equal
|
16
|
+
# to 12.
|
16
17
|
SIZE_OF_NHDR = Structs::ELF_Nhdr.new(endian: :little).num_bytes
|
17
18
|
|
18
19
|
# Iterate all notes in a note section or segment.
|
@@ -30,13 +31,16 @@ module ELFTools
|
|
30
31
|
# | ... |
|
31
32
|
# +---------------+
|
32
33
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
34
|
+
# @note
|
35
|
+
# This method assume following methods exist:
|
36
|
+
# stream
|
37
|
+
# note_start
|
38
|
+
# note_total_size
|
39
|
+
# @return [Enumerator<ELFTools::Note::Note>, Array<ELFTools::Note::Note>]
|
40
|
+
# If block is not given, an enumerator will be returned.
|
41
|
+
# Otherwise, return the array of notes.
|
39
42
|
def each_notes
|
43
|
+
return enum_for(:each_notes) unless block_given?
|
40
44
|
@notes_offset_map ||= {}
|
41
45
|
cur = note_start
|
42
46
|
notes = []
|
@@ -49,19 +53,23 @@ module ELFTools
|
|
49
53
|
desc_size = Util.align(note.header.n_descsz, 2)
|
50
54
|
cur += SIZE_OF_NHDR + name_size + desc_size
|
51
55
|
notes << note
|
52
|
-
yield note
|
56
|
+
yield note
|
53
57
|
end
|
54
58
|
notes
|
55
59
|
end
|
56
60
|
|
57
61
|
# Simply +#notes+ to get all notes.
|
58
|
-
|
62
|
+
# @return [Array<ELFTools::Note::Note>]
|
63
|
+
# Whole notes.
|
64
|
+
def notes
|
65
|
+
each_notes.to_a
|
66
|
+
end
|
59
67
|
|
60
68
|
private
|
61
69
|
|
62
70
|
# Get the endian.
|
63
71
|
#
|
64
|
-
#
|
72
|
+
# @note This method assume method +header+ exists.
|
65
73
|
# @return [Symbol] +:little+ or +:big+.
|
66
74
|
def endian
|
67
75
|
header.class.self_endian
|
@@ -75,12 +83,12 @@ module ELFTools
|
|
75
83
|
# Class of a note.
|
76
84
|
class Note
|
77
85
|
attr_reader :header # @return [ELFTools::Structs::ELF_Nhdr] Note header.
|
78
|
-
attr_reader :stream # @return [
|
86
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
79
87
|
attr_reader :offset # @return [Integer] Address of this note start, includes note header.
|
80
88
|
|
81
89
|
# Instantiate a {ELFTools::Note::Note} object.
|
82
90
|
# @param [ELF_Nhdr] header The note header.
|
83
|
-
# @param [
|
91
|
+
# @param [#pos=, #read] stream Streaming object.
|
84
92
|
# @param [Integer] offset
|
85
93
|
# Start address of this note, includes the header.
|
86
94
|
def initialize(header, stream, offset)
|
@@ -23,7 +23,7 @@ module ELFTools
|
|
23
23
|
#
|
24
24
|
# relocations are lazy loaded.
|
25
25
|
# @param [Integer] n The index.
|
26
|
-
# @return [ELFTools::Relocation,
|
26
|
+
# @return [ELFTools::Relocation, nil]
|
27
27
|
# The target relocation.
|
28
28
|
# If +n+ is out of bound, +nil+ is returned.
|
29
29
|
def relocation_at(n)
|
@@ -35,17 +35,15 @@ module ELFTools
|
|
35
35
|
#
|
36
36
|
# All relocations are lazy loading, the relocation
|
37
37
|
# only be created whenever accessing it.
|
38
|
-
# @
|
39
|
-
#
|
38
|
+
# @yieldparam [ELFTools::Relocation] rel A relocation object.
|
39
|
+
# @yieldreturn [void]
|
40
40
|
# @return [Enumerator<ELFTools::Relocation>, Array<ELFTools::Relocation>]
|
41
41
|
# If block is not given, an enumerator will be returned.
|
42
42
|
# Otherwise, the whole relocations will be returned.
|
43
|
-
def each_relocations
|
43
|
+
def each_relocations(&block)
|
44
44
|
return enum_for(:each_relocations) unless block_given?
|
45
45
|
Array.new(num_relocations) do |i|
|
46
|
-
|
47
|
-
yield rel
|
48
|
-
rel
|
46
|
+
relocation_at(i).tap(&block)
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
@@ -75,7 +73,7 @@ module ELFTools
|
|
75
73
|
# XXX: move this to an independent file?
|
76
74
|
class Relocation
|
77
75
|
attr_reader :header # @return [ELFTools::Structs::ELF_Rel, ELFTools::Structs::ELF_Rela] Rel(a) header.
|
78
|
-
attr_reader :stream # @return [
|
76
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
79
77
|
|
80
78
|
# Instantiate a {Relocation} object.
|
81
79
|
def initialize(header, stream)
|
@@ -4,12 +4,12 @@ module ELFTools
|
|
4
4
|
# Base class of sections.
|
5
5
|
class Section
|
6
6
|
attr_reader :header # @return [ELFTools::Structs::ELF_Shdr] Section header.
|
7
|
-
attr_reader :stream # @return [
|
7
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
8
8
|
|
9
9
|
# Instantiate a {Section} object.
|
10
10
|
# @param [ELFTools::Structs::ELF_Shdr] header
|
11
11
|
# The section header object.
|
12
|
-
# @param [
|
12
|
+
# @param [#pos=, #read] stream
|
13
13
|
# The streaming object for further dump.
|
14
14
|
# @param [ELFTools::Sections::StrTabSection, Proc] strtab
|
15
15
|
# The string table object. For fetching section names.
|
@@ -16,7 +16,7 @@ module ELFTools
|
|
16
16
|
class << Section
|
17
17
|
# Use different class according to +header.sh_type+.
|
18
18
|
# @param [ELFTools::Structs::ELF_Shdr] header Section header.
|
19
|
-
# @param [
|
19
|
+
# @param [#pos=, #read] stream Streaming object.
|
20
20
|
# @return [ELFTools::Sections::Section]
|
21
21
|
# Return object dependes on +header.sh_type+.
|
22
22
|
def create(header, stream, *args)
|
@@ -11,15 +11,14 @@ module ELFTools
|
|
11
11
|
# to easily fetch other sections.
|
12
12
|
# @param [ELFTools::Structs::ELF_Shdr] header
|
13
13
|
# See {Section#initialize} for more information.
|
14
|
-
# @param [
|
14
|
+
# @param [#pos=, #read] stream
|
15
15
|
# See {Section#initialize} for more information.
|
16
16
|
# @param [Proc] section_at
|
17
17
|
# The method for fetching other sections by index.
|
18
18
|
# This lambda should be {ELFTools::ELFFile#section_at}.
|
19
|
-
def initialize(header, stream, section_at: nil, **
|
19
|
+
def initialize(header, stream, section_at: nil, **_kwargs)
|
20
20
|
@section_at = section_at
|
21
21
|
# For faster #symbol_by_name
|
22
|
-
@symbol_name_map = {}
|
23
22
|
super
|
24
23
|
end
|
25
24
|
|
@@ -36,7 +35,7 @@ module ELFTools
|
|
36
35
|
#
|
37
36
|
# Symbols are lazy loaded.
|
38
37
|
# @param [Integer] n The index.
|
39
|
-
# @return [ELFTools::Symbol,
|
38
|
+
# @return [ELFTools::Sections::Symbol, nil]
|
40
39
|
# The target symbol.
|
41
40
|
# If +n+ is out of bound, +nil+ is returned.
|
42
41
|
def symbol_at(n)
|
@@ -50,30 +49,31 @@ module ELFTools
|
|
50
49
|
# only be created whenever accessing it.
|
51
50
|
# This method is useful for {#symbol_by_name}
|
52
51
|
# since not all symbols need to be created.
|
53
|
-
# @
|
54
|
-
#
|
55
|
-
# @return [Array<ELFTools::
|
56
|
-
#
|
57
|
-
|
52
|
+
# @yieldparam [ELFTools::Sections::Symbol] sym A symbol object.
|
53
|
+
# @yieldreturn [void]
|
54
|
+
# @return [Enumerator<ELFTools::Sections::Symbol>, Array<ELFTools::Sections::Symbol>]
|
55
|
+
# If block is not given, an enumerator will be returned.
|
56
|
+
# Otherwise return array of symbols.
|
57
|
+
def each_symbols(&block)
|
58
|
+
return enum_for(:each_symbols) unless block_given?
|
58
59
|
Array.new(num_symbols) do |i|
|
59
|
-
|
60
|
-
block_given? ? yield(sym) : sym
|
60
|
+
symbol_at(i).tap(&block)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
# Simply use {#symbols} to get all symbols.
|
65
|
+
# @return [Array<ELFTools::Sections::Symbol>]
|
66
|
+
# The whole symbols.
|
67
|
+
def symbols
|
68
|
+
each_symbols.to_a
|
69
|
+
end
|
65
70
|
|
66
|
-
# Get symbol by
|
71
|
+
# Get symbol by its name.
|
67
72
|
# @param [String] name
|
68
73
|
# The name of symbol.
|
69
|
-
# @return [ELFTools::Symbol] Desired symbol.
|
74
|
+
# @return [ELFTools::Sections::Symbol] Desired symbol.
|
70
75
|
def symbol_by_name(name)
|
71
|
-
|
72
|
-
each_symbols do |symbol|
|
73
|
-
@symbol_name_map[symbol.name] = symbol
|
74
|
-
return symbol if symbol.name == name
|
75
|
-
end
|
76
|
-
nil
|
76
|
+
each_symbols.find { |symbol| symbol.name == name }
|
77
77
|
end
|
78
78
|
|
79
79
|
# Return the symbol string section.
|
@@ -98,12 +98,12 @@ module ELFTools
|
|
98
98
|
# XXX: Should this class be defined in an independent file?
|
99
99
|
class Symbol
|
100
100
|
attr_reader :header # @return [ELFTools::Structs::ELF32_sym, ELFTools::Structs::ELF64_sym] Section header.
|
101
|
-
attr_reader :stream # @return [
|
101
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
102
102
|
|
103
|
-
# Instantiate a {ELFTools::Symbol} object.
|
103
|
+
# Instantiate a {ELFTools::Sections::Symbol} object.
|
104
104
|
# @param [ELFTools::Structs::ELF32_sym, ELFTools::Structs::ELF64_sym] header
|
105
105
|
# The symbol header.
|
106
|
-
# @param [
|
106
|
+
# @param [#pos=, #read] stream The streaming object.
|
107
107
|
# @param [ELFTools::Sections::StrTabSection, Proc] symstr
|
108
108
|
# The symbol string section.
|
109
109
|
# If +Proc+ is given, it will be called at the first time
|
@@ -3,12 +3,12 @@ module ELFTools
|
|
3
3
|
# Base class of segments.
|
4
4
|
class Segment
|
5
5
|
attr_reader :header # @return [ELFTools::Structs::ELF32_Phdr, ELFTools::Structs::ELF64_Phdr] Program header.
|
6
|
-
attr_reader :stream # @return [
|
6
|
+
attr_reader :stream # @return [#pos=, #read] Streaming object.
|
7
7
|
|
8
8
|
# Instantiate a {Segment} object.
|
9
9
|
# @param [ELFTools::Structs::ELF32_Phdr, ELFTools::Structs::ELF64_Phdr] header
|
10
10
|
# Program header.
|
11
|
-
# @param [
|
11
|
+
# @param [#pos=, #read] stream
|
12
12
|
# Streaming object.
|
13
13
|
# @param [Method] offset_from_vma
|
14
14
|
# The method to get offset of file, given virtual memory address.
|
@@ -13,7 +13,7 @@ module ELFTools
|
|
13
13
|
class << Segment
|
14
14
|
# Use different class according to +header.p_type+.
|
15
15
|
# @param [ELFTools::Structs::ELF32_Phdr, ELFTools::Structs::ELF64_Phdr] header Program header of a segment.
|
16
|
-
# @param [
|
16
|
+
# @param [#pos=, #read] stream Streaming object.
|
17
17
|
# @return [ELFTools::Segments::Segment]
|
18
18
|
# Return object dependes on +header.p_type+.
|
19
19
|
def create(header, stream, *args)
|
data/lib/elftools/structs.rb
CHANGED
@@ -8,6 +8,7 @@ module ELFTools
|
|
8
8
|
module Structs
|
9
9
|
# The base structure to define common methods.
|
10
10
|
class ELFStruct < BinData::Record
|
11
|
+
# DRY. Many fields have different type in different arch.
|
11
12
|
CHOICE_SIZE_T = {
|
12
13
|
selection: :elf_class, choices: { 32 => :uint32, 64 => :uint64 }
|
13
14
|
}.freeze
|
@@ -15,7 +16,7 @@ module ELFTools
|
|
15
16
|
attr_accessor :elf_class # @return [Integer] 32 or 64.
|
16
17
|
|
17
18
|
# Hacking to get endian of current class
|
18
|
-
# @return [Symbol,
|
19
|
+
# @return [Symbol, nil] +:little+ or +:big+.
|
19
20
|
def self.self_endian
|
20
21
|
bindata_name[-2..-1] == 'ge' ? :big : :little
|
21
22
|
end
|
@@ -89,6 +90,7 @@ module ELFTools
|
|
89
90
|
uint64 :p_memsz
|
90
91
|
uint64 :p_align
|
91
92
|
end
|
93
|
+
# Get program header class according to bits.
|
92
94
|
ELF_Phdr = {
|
93
95
|
32 => ELF32_Phdr,
|
94
96
|
64 => ELF64_Phdr
|
@@ -115,6 +117,7 @@ module ELFTools
|
|
115
117
|
uint64 :st_value # Value of the symbol
|
116
118
|
uint64 :st_size # Associated symbol size
|
117
119
|
end
|
120
|
+
# Get symbol header class according to bits.
|
118
121
|
ELF_sym = {
|
119
122
|
32 => ELF32_sym,
|
120
123
|
64 => ELF64_sym
|
data/lib/elftools/util.rb
CHANGED
@@ -47,7 +47,7 @@ module ELFTools
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# Read from stream until reach a null-byte.
|
50
|
-
# @param [
|
50
|
+
# @param [#pos=, #read] stream Streaming object
|
51
51
|
# @param [Integer] offset Start from here.
|
52
52
|
# @return [String] Result string will never contain null byte.
|
53
53
|
# @example
|
@@ -80,9 +80,9 @@ module ELFTools
|
|
80
80
|
# The return value will be objects in +enum+ with attribute
|
81
81
|
# +.type+ equals to +type+.
|
82
82
|
def select_by_type(enum, type)
|
83
|
-
enum.select do |
|
84
|
-
if
|
85
|
-
yield
|
83
|
+
enum.select do |obj|
|
84
|
+
if obj.type == type
|
85
|
+
yield obj if block_given?
|
86
86
|
true
|
87
87
|
end
|
88
88
|
end
|
data/lib/elftools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elftools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.9'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.9'
|
97
111
|
description: |2
|
98
112
|
A light weight ELF parser. elftools is designed to be a low-level ELF parser.
|
99
113
|
Inspired by https://github.com/eliben/pyelftools.
|