ruby-macho 0.0.7 → 0.0.8
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/lib/macho/fat_file.rb +12 -1
- data/lib/macho/load_commands.rb +6 -0
- data/lib/macho/macho_file.rb +66 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b104665e169f8988913d6032d3755032d814a2f
|
4
|
+
data.tar.gz: fc3f95ed644f84e913a78709227e178f33e9e995
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 986523ca44a54d65a2d1624b31cbd612f520bab44ffaf405971052174224e9fedde4aabf1aa5d91fe451ee58cde5d892d95030bf6dad8f4688389fe8fc3f18dd
|
7
|
+
data.tar.gz: b5e6ffe8212660e32ed089d7dba2294818257aeb523b8eac8a3d4d66b9a549a210b40037109c26ff2cd31e47c7921fbe3389153b86dff30816efab83a061cbd4
|
data/lib/macho/fat_file.rb
CHANGED
@@ -48,12 +48,23 @@ module MachO
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def linked_dylibs
|
51
|
-
dylibs = machos.map(&:linked_dylibs)
|
51
|
+
dylibs = machos.map(&:linked_dylibs).flatten
|
52
52
|
|
53
53
|
# can machos inside fat binaries have different dylibs?
|
54
54
|
dylibs.uniq!
|
55
55
|
end
|
56
56
|
|
57
|
+
# stub
|
58
|
+
def change_dylib(old_path, new_path)
|
59
|
+
machos.each do |macho|
|
60
|
+
macho.change_install_name(old_path, new_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
synchronize_raw_data
|
64
|
+
end
|
65
|
+
|
66
|
+
alias :change_install_name :change_dylib
|
67
|
+
|
57
68
|
def write(filename)
|
58
69
|
File.open(filename, "wb") { |f| f.write(@raw_data) }
|
59
70
|
end
|
data/lib/macho/load_commands.rb
CHANGED
@@ -163,6 +163,12 @@ module MachO
|
|
163
163
|
SEG_UNIXSTACK = "__UNIXSTACK"
|
164
164
|
SEG_IMPORT = "__IMPORT"
|
165
165
|
|
166
|
+
# constant bits for flags in SegmentCommand, SegmentCommand64
|
167
|
+
SG_HIGHVM = 0x1
|
168
|
+
SG_FVMLIB = 0x2
|
169
|
+
SG_NORELOC = 0x4
|
170
|
+
SG_PROTECTED_VERSION_1 = 0x8
|
171
|
+
|
166
172
|
# Mach-O load command structure
|
167
173
|
# this is the most generic load command - only cmd ID and size are
|
168
174
|
# represented, and no actual data. used when a more specific class
|
data/lib/macho/macho_file.rb
CHANGED
@@ -217,11 +217,74 @@ module MachO
|
|
217
217
|
dylibs
|
218
218
|
end
|
219
219
|
|
220
|
-
#
|
221
|
-
def change_dylib
|
222
|
-
|
220
|
+
# TODO: genericize change_dylib and dylib_id= for DRYness
|
221
|
+
def change_dylib(old_path, new_path)
|
222
|
+
idx = linked_dylibs.index(old_path)
|
223
|
+
raise DylibUnknownError.new(old_path) if idx.nil?
|
224
|
+
|
225
|
+
# this is a bit of a hack - since there is a 1-1 ordered association
|
226
|
+
# between linked_dylibs and command('LC_LOAD_DYLIB'), we can use
|
227
|
+
# their indices interchangeably to avoid having to loop.
|
228
|
+
dylib_cmd = command('LC_LOAD_DYLIB')[idx]
|
229
|
+
|
230
|
+
if magic32?
|
231
|
+
cmd_round = 4
|
232
|
+
else
|
233
|
+
cmd_round = 8
|
234
|
+
end
|
235
|
+
|
236
|
+
new_sizeofcmds = header[:sizeofcmds]
|
237
|
+
old_install_name = old_path.dup
|
238
|
+
new_install_name = new_path.dup
|
239
|
+
|
240
|
+
old_pad = MachO.round(old_install_name.size, cmd_round) - old_install_name.size
|
241
|
+
new_pad = MachO.round(new_install_name.size, cmd_round) - new_install_name.size
|
242
|
+
|
243
|
+
old_install_name << "\x00" * old_pad
|
244
|
+
new_install_name << "\x00" * new_pad
|
245
|
+
|
246
|
+
new_size = DylibCommand.bytesize + new_install_name.size
|
247
|
+
new_sizeofcmds += new_size - dylib_cmd.cmdsize
|
248
|
+
|
249
|
+
low_fileoff = 2**64
|
250
|
+
|
251
|
+
segments.each do |seg|
|
252
|
+
sections(seg).each do |sect|
|
253
|
+
if sect.size != 0 && !sect.flag?(S_ZEROFILL) &&
|
254
|
+
!sect.flag?(S_THREAD_LOCAL_ZEROFILL) &&
|
255
|
+
sect.offset < low_fileoff
|
256
|
+
|
257
|
+
low_fileoff = sect.offset
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
if new_sizeofcmds + header.bytesize > low_fileoff
|
263
|
+
raise HeaderPadError.new(@filename)
|
264
|
+
end
|
265
|
+
|
266
|
+
set_sizeofcmds(new_sizeofcmds)
|
267
|
+
|
268
|
+
@raw_data[dylib_cmd.offset + 4, 4] = [new_size].pack("V")
|
269
|
+
|
270
|
+
@raw_data.slice!(dylib_cmd.offset + dylib_cmd.name...dylib_cmd.offset + dylib_cmd.class.bytesize + old_install_name.size)
|
271
|
+
|
272
|
+
@raw_data.insert(dylib_cmd.offset + dylib_cmd.name, new_install_name)
|
273
|
+
|
274
|
+
null_pad = old_install_name.size - new_install_name.size
|
275
|
+
|
276
|
+
if null_pad < 0
|
277
|
+
@raw_data.slice!(new_sizeofcmds + header.bytesize, null_pad.abs)
|
278
|
+
else
|
279
|
+
@raw_data.insert(new_sizeofcmds + header.bytesize, "\x00" * null_pad)
|
280
|
+
end
|
281
|
+
|
282
|
+
header = get_mach_header
|
283
|
+
load_commands = get_load_commands
|
223
284
|
end
|
224
285
|
|
286
|
+
alias :change_install_name :change_dylib
|
287
|
+
|
225
288
|
# get all sections in a segment by name
|
226
289
|
def sections(segment)
|
227
290
|
sections = []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-macho
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Woodruff
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A library for viewing and manipulating Mach-O files in Ruby.
|
14
14
|
email: william@tuffbizz.com
|