patchelf 0.1.0 → 1.0.0
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 +1 -1
- data/lib/patchelf/cli.rb +19 -6
- data/lib/patchelf/exceptions.rb +9 -0
- data/lib/patchelf/mm.rb +3 -1
- data/lib/patchelf/patcher.rb +14 -4
- data/lib/patchelf/saver.rb +3 -2
- data/lib/patchelf/version.rb +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f510dcd400f1ea47ee4f7740f7f64a01e392b1e8230c4065aa3456541446ca6a
|
4
|
+
data.tar.gz: 3196e51a7a26fe50d83341a8552645e6855f880d2ba6ca337dc856424ec0bbdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a7595a75b43139c254f2b25c1f2a3effd97d4e0c8ad0227c6493eee043904a6ee73bdc16fd46ff2276bcd6b3b595878f1ea8e2bdba8b1c34e85131379db7687
|
7
|
+
data.tar.gz: b766c4045369095334d768002a07ff9a2d8b7193134b865e0b0d2e9443716cfc92927ca980fcf7e3053314d17ef1a63cc5fff017a5bcb8805a69ca2aae5c953a
|
data/README.md
CHANGED
@@ -134,4 +134,4 @@ patcher.save('ls.patch')
|
|
134
134
|
|
135
135
|
## Environment
|
136
136
|
|
137
|
-
patchelf.rb is implemented in pure Ruby, so it should work in all environments include Linux,
|
137
|
+
patchelf.rb is implemented in pure Ruby, so it should work in all environments include Linux, macOS, and Windows!
|
data/lib/patchelf/cli.rb
CHANGED
@@ -34,9 +34,24 @@ module PatchELF
|
|
34
34
|
return $stdout.puts option_parser unless parse(argv)
|
35
35
|
|
36
36
|
# Now the options are (hopefully) valid, let's process the ELF file.
|
37
|
-
|
37
|
+
begin
|
38
|
+
@patcher = PatchELF::Patcher.new(@options[:in_file])
|
39
|
+
rescue ELFTools::ELFError, Errno::ENOENT => e
|
40
|
+
return PatchELF::Logger.error(e.message)
|
41
|
+
end
|
38
42
|
patcher.use_rpath! if @options[:force_rpath]
|
39
|
-
|
43
|
+
readonly
|
44
|
+
patch_requests
|
45
|
+
patcher.save(@options[:out_file])
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def patcher
|
51
|
+
@patcher
|
52
|
+
end
|
53
|
+
|
54
|
+
def readonly
|
40
55
|
@options[:print].uniq.each do |s|
|
41
56
|
content = patcher.__send__(s)
|
42
57
|
next if content.nil?
|
@@ -44,7 +59,9 @@ module PatchELF
|
|
44
59
|
s = :rpath if @options[:force_rpath] && s == :runpath
|
45
60
|
$stdout.puts "#{s}: #{Array(content).join(' ')}"
|
46
61
|
end
|
62
|
+
end
|
47
63
|
|
64
|
+
def patch_requests
|
48
65
|
@options[:set].each do |sym, val|
|
49
66
|
patcher.__send__("#{sym}=".to_sym, val)
|
50
67
|
end
|
@@ -52,12 +69,8 @@ module PatchELF
|
|
52
69
|
@options[:needed].each do |type, val|
|
53
70
|
patcher.__send__("#{type}_needed".to_sym, *val)
|
54
71
|
end
|
55
|
-
|
56
|
-
patcher.save(@options[:out_file])
|
57
72
|
end
|
58
73
|
|
59
|
-
private
|
60
|
-
|
61
74
|
def parse(argv)
|
62
75
|
remain = option_parser.permute(argv)
|
63
76
|
return false if remain.first.nil?
|
data/lib/patchelf/mm.rb
CHANGED
@@ -25,7 +25,8 @@ module PatchELF
|
|
25
25
|
# 1. Set ELF headers' attributes (with ELFTools)
|
26
26
|
# 2. Invoke {Saver#inline_patch}
|
27
27
|
def malloc(size, &block)
|
28
|
-
|
28
|
+
raise ArgumentError, 'malloc\'s size most be positive.' if size <= 0
|
29
|
+
|
29
30
|
@request << [size, block]
|
30
31
|
end
|
31
32
|
|
@@ -133,6 +134,7 @@ module PatchELF
|
|
133
134
|
nil
|
134
135
|
end
|
135
136
|
|
137
|
+
# TODO
|
136
138
|
def new_load_method
|
137
139
|
raise NotImplementedError
|
138
140
|
end
|
data/lib/patchelf/patcher.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'elftools/elf_file'
|
5
5
|
|
6
|
+
require 'patchelf/exceptions'
|
6
7
|
require 'patchelf/logger'
|
7
8
|
require 'patchelf/saver'
|
8
9
|
|
@@ -15,11 +16,14 @@ module PatchELF
|
|
15
16
|
# Instantiate a {Patcher} object.
|
16
17
|
# @param [String] filename
|
17
18
|
# Filename of input ELF.
|
18
|
-
|
19
|
+
# @param [Boolean] logging
|
20
|
+
# Whether to use a (stderr-initialized) logger for errors
|
21
|
+
def initialize(filename, logging: true)
|
19
22
|
@in_file = filename
|
20
23
|
@elf = ELFTools::ELFFile.new(File.open(filename))
|
21
24
|
@set = {}
|
22
25
|
@rpath_sym = :runpath
|
26
|
+
@logging = logging
|
23
27
|
end
|
24
28
|
|
25
29
|
# @return [String?]
|
@@ -156,9 +160,15 @@ module PatchELF
|
|
156
160
|
|
157
161
|
private
|
158
162
|
|
163
|
+
def log_or_raise(msg)
|
164
|
+
raise PatchELF::PatchError, msg unless @logging
|
165
|
+
|
166
|
+
PatchELF::Logger.warn(msg)
|
167
|
+
end
|
168
|
+
|
159
169
|
def interpreter_
|
160
170
|
segment = @elf.segment_by_type(:interp)
|
161
|
-
return
|
171
|
+
return log_or_raise 'No interpreter found.' if segment.nil?
|
162
172
|
|
163
173
|
segment.interp_name
|
164
174
|
end
|
@@ -191,14 +201,14 @@ module PatchELF
|
|
191
201
|
return if segment.nil?
|
192
202
|
|
193
203
|
tag = segment.tag_by_type(type)
|
194
|
-
return
|
204
|
+
return log_or_raise log_msg if tag.nil?
|
195
205
|
|
196
206
|
tag.name
|
197
207
|
end
|
198
208
|
|
199
209
|
def dynamic_or_log
|
200
210
|
@elf.segment_by_type(:dynamic).tap do |s|
|
201
|
-
|
211
|
+
log_or_raise 'DYNAMIC segment not found, might be a statically-linked ELF?' if s.nil?
|
202
212
|
end
|
203
213
|
end
|
204
214
|
end
|
data/lib/patchelf/saver.rb
CHANGED
@@ -189,9 +189,10 @@ module PatchELF
|
|
189
189
|
@mm.malloc(need_size) do |off, vaddr|
|
190
190
|
new_str = strtab_string + @strtab_extend_requests.map(&:first).join("\x00") + "\x00"
|
191
191
|
inline_patch(off, new_str)
|
192
|
+
cur = strtab_string.size
|
192
193
|
@strtab_extend_requests.each do |str, block|
|
193
|
-
|
194
|
-
|
194
|
+
block.call(cur)
|
195
|
+
cur += str.size + 1
|
195
196
|
end
|
196
197
|
# Now patching strtab header
|
197
198
|
strtab.header.d_val = vaddr
|
data/lib/patchelf/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: patchelf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elftools
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: '0.17'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: '0.17'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: tty-platform
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- bin/patchelf.rb
|
123
123
|
- lib/patchelf.rb
|
124
124
|
- lib/patchelf/cli.rb
|
125
|
+
- lib/patchelf/exceptions.rb
|
125
126
|
- lib/patchelf/helper.rb
|
126
127
|
- lib/patchelf/logger.rb
|
127
128
|
- lib/patchelf/mm.rb
|
@@ -140,14 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
141
|
requirements:
|
141
142
|
- - ">="
|
142
143
|
- !ruby/object:Gem::Version
|
143
|
-
version: 2.
|
144
|
+
version: '2.3'
|
144
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
146
|
requirements:
|
146
147
|
- - ">="
|
147
148
|
- !ruby/object:Gem::Version
|
148
149
|
version: '0'
|
149
150
|
requirements: []
|
150
|
-
rubygems_version: 3.0.
|
151
|
+
rubygems_version: 3.0.3
|
151
152
|
signing_key:
|
152
153
|
specification_version: 4
|
153
154
|
summary: patchelf
|