ruby-macho 0.1.9 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 939f8d565fc3d98bd633414e797b2f8cd70c0df6
4
- data.tar.gz: 3ab244e120eba39d1f84a8b495de6c221f4fc8f0
3
+ metadata.gz: 513849997d23e143113243138d5924dc483a2a0b
4
+ data.tar.gz: 2e2d1256e5b42be47cdcb81c8981e35021c5fe6a
5
5
  SHA512:
6
- metadata.gz: bb2d31798f5d4b6fefd00a2c3e5c562595331015f9a44b9d3b5bcce84b43db3c473236222412bc1b26e358161df2451e15c8ea292c1c0fc433292afc9871772c
7
- data.tar.gz: 39bd050a693d85cd48e7ce3594d5cfd199732e171df7026474af03723bdd3c1a58108df08c078333fc0304ed84691c14a76bb15b6a168f8411f993e4e7b0b5d2
6
+ metadata.gz: 3e1bb350afe1cbbbfff4a50197886c4c7c6f4675f0de8e5480deafce7ee4986febd3b7d59c067753cea95ed4dc4a92b8e38d8c486344e3c7b2937bcaff22b800
7
+ data.tar.gz: dba7611dadf4672c0929bc5f3c8f70c60051b01c278cb0383209304526a780008a2b19c0e50848a42d962b78c43c11174dd7c0913f123bff88b8392c30acc9fe
@@ -74,4 +74,12 @@ module MachO
74
74
  super "No such dylib name: #{dylib}"
75
75
  end
76
76
  end
77
+
78
+ # Raised when attempting to change an rpath that doesn't exist.
79
+ class RpathUnknownError < MachOError
80
+ # @param path [String] the unknown runtime path
81
+ def initialize(path)
82
+ super "No such runtime path: #{path}"
83
+ end
84
+ end
77
85
  end
@@ -228,6 +228,27 @@ module MachO
228
228
 
229
229
  alias :change_dylib :change_install_name
230
230
 
231
+ # All runtime paths searched by the dynamic linker for the Mach-O.
232
+ # @return [Array<String>] an array of all runtime paths
233
+ def rpaths
234
+ command(:LC_RPATH).map(&:path).map(&:to_s)
235
+ end
236
+
237
+ # Changes the runtime path `old_path` to `new_path`
238
+ # @example
239
+ # file.change_rpath("/usr/lib", "/usr/local/lib")
240
+ # @param old_path [String] the old runtime path
241
+ # @param new_path [String] the new runtime path
242
+ # @return [void]
243
+ # @raise [MachO::RpathUnknownError] if no such old runtime path exists
244
+ # @api private
245
+ def change_rpath(old_path, new_path)
246
+ rpath_cmd = command(:LC_RPATH).find { |r| r.path.to_s == old_path }
247
+ raise RpathUnknownError.new(old_path) if rpath_cmd.nil?
248
+
249
+ set_path_in_rpath(rpath_cmd, old_path, new_path)
250
+ end
251
+
231
252
  # All sections of the segment `segment`.
232
253
  # @param segment [MachO::SegmentCommand, MachO::SegmentCommand64] the segment being inspected
233
254
  # @return [Array<MachO::Section>] if the Mach-O is 32-bit
@@ -408,14 +429,34 @@ module MachO
408
429
  @raw_data[20..23] = new_size
409
430
  end
410
431
 
411
- # Updates the `name` field in a DylibCommand, regardless of load command type
432
+ # Updates the `name` field in a DylibCommand.
412
433
  # @param dylib_cmd [MachO::DylibCommand] the dylib command
413
434
  # @param old_name [String] the old dylib name
414
435
  # @param new_name [String] the new dylib name
415
436
  # @return [void]
416
- # @raise [MachO::HeaderPadError] if the new name exceeds the header pad buffer
417
437
  # @private
418
438
  def set_name_in_dylib(dylib_cmd, old_name, new_name)
439
+ set_lc_str_in_cmd(dylib_cmd, dylib_cmd.name, old_name, new_name)
440
+ end
441
+
442
+ # Updates the `path` field in an RpathCommand.
443
+ # @param rpath_cmd [MachO::RpathCommand] the rpath command
444
+ # @param old_path [String] the old runtime name
445
+ # @param new_path [String] the new runtime name
446
+ # @return [void]
447
+ # @private
448
+ def set_path_in_rpath(rpath_cmd, old_path, new_path)
449
+ set_lc_str_in_cmd(rpath_cmd, rpath_cmd.path, old_path, new_path)
450
+ end
451
+
452
+ # Updates a generic LCStr field in any LoadCommand.
453
+ # @param cmd [MachO::LoadCommand] the load command
454
+ # @param lc_str [MachO::LoadCommand::LCStr] the load command string
455
+ # @param old_str [String] the old string
456
+ # @param new_str [String] the new string
457
+ # @raise [MachO::HeaderPadError] if the new name exceeds the header pad buffer
458
+ # @private
459
+ def set_lc_str_in_cmd(cmd, lc_str, old_str, new_str)
419
460
  if magic32?
420
461
  cmd_round = 4
421
462
  else
@@ -423,19 +464,19 @@ module MachO
423
464
  end
424
465
 
425
466
  new_sizeofcmds = header.sizeofcmds
426
- old_name = old_name.dup
427
- new_name = new_name.dup
467
+ old_str = old_str.dup
468
+ new_str = new_str.dup
428
469
 
429
- old_pad = MachO.round(old_name.size, cmd_round) - old_name.size
430
- new_pad = MachO.round(new_name.size, cmd_round) - new_name.size
470
+ old_pad = MachO.round(old_str.size + 1, cmd_round) - old_str.size
471
+ new_pad = MachO.round(new_str.size + 1, cmd_round) - new_str.size
431
472
 
432
473
  # pad the old and new IDs with null bytes to meet command bounds
433
- old_name << "\x00" * old_pad
434
- new_name << "\x00" * new_pad
474
+ old_str << "\x00" * old_pad
475
+ new_str << "\x00" * new_pad
435
476
 
436
- # calculate the new size of the DylibCommand and sizeofcmds in MH
437
- new_size = DylibCommand.bytesize + new_name.size
438
- new_sizeofcmds += new_size - dylib_cmd.cmdsize
477
+ # calculate the new size of the cmd and sizeofcmds in MH
478
+ new_size = cmd.class.bytesize + new_str.size
479
+ new_sizeofcmds += new_size - cmd.cmdsize
439
480
 
440
481
  low_fileoff = 2**64 # ULLONGMAX
441
482
 
@@ -458,17 +499,17 @@ module MachO
458
499
  # update sizeofcmds in mach_header
459
500
  set_sizeofcmds(new_sizeofcmds)
460
501
 
461
- # update cmdsize in the dylib_command
462
- @raw_data[dylib_cmd.offset + 4, 4] = [new_size].pack("V")
502
+ # update cmdsize in the cmd
503
+ @raw_data[cmd.offset + 4, 4] = [new_size].pack("V")
463
504
 
464
- # delete the old name
465
- @raw_data.slice!(dylib_cmd.offset + dylib_cmd.name.to_i...dylib_cmd.offset + dylib_cmd.class.bytesize + old_name.size)
505
+ # delete the old str
506
+ @raw_data.slice!(cmd.offset + lc_str.to_i...cmd.offset + cmd.class.bytesize + old_str.size)
466
507
 
467
- # insert the new id
468
- @raw_data.insert(dylib_cmd.offset + dylib_cmd.name.to_i, new_name)
508
+ # insert the new str
509
+ @raw_data.insert(cmd.offset + lc_str.to_i, new_str)
469
510
 
470
511
  # pad/unpad after new_sizeofcmds until offsets are corrected
471
- null_pad = old_name.size - new_name.size
512
+ null_pad = old_str.size - new_str.size
472
513
 
473
514
  if null_pad < 0
474
515
  @raw_data.slice!(new_sizeofcmds + header.class.bytesize, null_pad.abs)
data/lib/macho/tools.rb CHANGED
@@ -17,12 +17,8 @@ module MachO
17
17
  def self.change_dylib_id(filename, new_id)
18
18
  file = MachO.open(filename)
19
19
 
20
- if File.is_a? MachO::MachOFile
21
- file.dylib_id = new_id
22
- file.write!
23
- else
24
- raise MachOError.new("changing dylib ids for fat binaries is incomplete")
25
- end
20
+ file.dylib_id = new_id
21
+ file.write!
26
22
  end
27
23
 
28
24
  # Changes a shared library install name in a Mach-O or Fat binary, overwriting the source file.
@@ -34,11 +30,8 @@ module MachO
34
30
  def self.change_install_name(filename, old_name, new_name)
35
31
  file = MachO.open(filename)
36
32
 
37
- if File.is_a? MachO::MachOFile
38
- file.change_install_name(old_name, new_name)
39
- else
40
- raise MachOError.new("changing install names for fat binaries is incomplete")
41
- end
33
+ file.change_install_name(old_name, new_name)
34
+ file.write!
42
35
  end
43
36
 
44
37
  # Changes a runtime path in a Mach-O or Fat binary, overwriting the source file.
data/lib/macho.rb CHANGED
@@ -12,5 +12,5 @@ require "#{File.dirname(__FILE__)}/macho/tools"
12
12
  # The primary namespace for ruby-macho.
13
13
  module MachO
14
14
  # release version
15
- VERSION = "0.1.9".freeze
15
+ VERSION = "0.2.0".freeze
16
16
  end
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.1.9
4
+ version: 0.2.0
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-11-07 00:00:00.000000000 Z
11
+ date: 2015-11-11 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