ruby-macho 0.1.1 → 0.1.2

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/macho/macho_file.rb +81 -118
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70e9e70c2eb3e759c76828051d5bca20c19f081b
4
- data.tar.gz: 7a626fcc61d6437dec0085c46843cf7a9574f9a1
3
+ metadata.gz: 634d3249001bb3d3bf5782055392c8feea3d15c8
4
+ data.tar.gz: bd854ada089451f23d4b253642bbb3eebcbba25f
5
5
  SHA512:
6
- metadata.gz: 6a110e3986ffbe60926702252a173082cd44bbb65824cbdd55648a969a2a54fb2afe9b60c5b761f978b8c2b11948887f052de67daab6d9b261085a199be58d38
7
- data.tar.gz: 5a7c81e82a7857fe6a2732605f9dc4fb3e139d2989673ad3fbe1632be85072e13432cdbaf0964024cc53cc3c63d29a7864152dea5296b170185e12132e1fafc6
6
+ metadata.gz: 06436af8d8c711a2eaa40f396020a80e15ff8f8de474e162f7f3e41d7b1a984d1218bec862d54f18bb9fe20675908ea8dfe1bcdd08b3d4bd50c8d0405daf06a5
7
+ data.tar.gz: cc4846d66dc58873417d1baae77c95c7ee4678f5861e98211cb52c4a6363280490473261de8b0143080a7aae71b97e20c0d85b6e0dac5647f106918a3de68c85
@@ -158,8 +158,8 @@ module MachO
158
158
  # Changes the Mach-O's dylib ID to `new_id`. Does nothing if not a dylib.
159
159
  # @example
160
160
  # file.dylib_id = "libFoo.dylib"
161
+ # @param new_id [String] the dylib's new ID
161
162
  # @return [void]
162
- # @todo refactor
163
163
  def dylib_id=(new_id)
164
164
  if !new_id.is_a?(String)
165
165
  raise ArgumentError.new("argument must be a String")
@@ -169,70 +169,10 @@ module MachO
169
169
  return nil
170
170
  end
171
171
 
172
- if magic32?
173
- cmd_round = 4
174
- else
175
- cmd_round = 8
176
- end
177
-
178
- new_sizeofcmds = header[:sizeofcmds]
179
- dylib_id_cmd = command('LC_ID_DYLIB').first
172
+ dylib_cmd = command('LC_ID_DYLIB').first
180
173
  old_id = dylib_id
181
- new_id = new_id.dup
182
-
183
- new_pad = MachO.round(new_id.size, cmd_round) - new_id.size
184
- old_pad = MachO.round(old_id.size, cmd_round) - old_id.size
185
-
186
- # pad the old and new IDs with null bytes to meet command bounds
187
- old_id << "\x00" * old_pad
188
- new_id << "\x00" * new_pad
189
-
190
- # calculate the new size of the DylibCommand and sizeofcmds in MH
191
- new_size = DylibCommand.bytesize + new_id.size
192
- new_sizeofcmds += new_size - dylib_id_cmd.cmdsize
193
-
194
- # calculate the low file offset (offset to first section data)
195
- low_fileoff = 2**64 # ULLONGMAX
196
-
197
- segments.each do |seg|
198
- sections(seg).each do |sect|
199
- if sect.size != 0 && !sect.flag?(S_ZEROFILL) &&
200
- !sect.flag?(S_THREAD_LOCAL_ZEROFILL) &&
201
- sect.offset < low_fileoff
202
-
203
- low_fileoff = sect.offset
204
- end
205
- end
206
- end
207
-
208
- if new_sizeofcmds + header.bytesize > low_fileoff
209
- raise HeaderPadError.new(@filename)
210
- end
211
-
212
- # update sizeofcmds in mach_header
213
- set_sizeofcmds(new_sizeofcmds)
214
-
215
- # update cmdsize in the dylib_command
216
- @raw_data[dylib_id_cmd.offset + 4, 4] = [new_size].pack("V")
217
-
218
- # delete the old id
219
- @raw_data.slice!(dylib_id_cmd.offset + dylib_id_cmd.name...dylib_id_cmd.offset + dylib_id_cmd.class.bytesize + old_id.size)
220
174
 
221
- # insert the new id
222
- @raw_data.insert(dylib_id_cmd.offset + dylib_id_cmd.name, new_id)
223
-
224
- # pad/unpad after new_sizeofcmds until offsets are corrected
225
- null_pad = old_id.size - new_id.size
226
-
227
- if null_pad < 0
228
- @raw_data.slice!(new_sizeofcmds + header.bytesize, null_pad.abs)
229
- else
230
- @raw_data.insert(new_sizeofcmds + header.bytesize, "\x00" * null_pad)
231
- end
232
-
233
- # synchronize fields with the raw data
234
- header = get_mach_header
235
- load_commands = get_load_commands
175
+ set_name_in_dylib(dylib_cmd, old_id, new_id)
236
176
  end
237
177
 
238
178
  # All shared libraries linked to the Mach-O.
@@ -254,8 +194,12 @@ module MachO
254
194
  dylibs
255
195
  end
256
196
 
197
+ # Changes the shared library `old_name` to `new_name`
198
+ # @example
199
+ # file.change_install_name("/usr/lib/libWhatever.dylib", "/usr/local/lib/libWhatever2.dylib")
200
+ # @param old_name [String] the shared library's old name
201
+ # @param new_name [String] the shared library's new name
257
202
  # @return [void]
258
- # @todo refactor
259
203
  def change_install_name(old_name, new_name)
260
204
  idx = linked_dylibs.index(old_name)
261
205
  raise DylibUnknownError.new(old_name) if idx.nil?
@@ -265,60 +209,7 @@ module MachO
265
209
  # their indices interchangeably to avoid having to loop.
266
210
  dylib_cmd = command('LC_LOAD_DYLIB')[idx]
267
211
 
268
- if magic32?
269
- cmd_round = 4
270
- else
271
- cmd_round = 8
272
- end
273
-
274
- new_sizeofcmds = header[:sizeofcmds]
275
- old_install_name = old_name.dup
276
- new_install_name = new_name.dup
277
-
278
- old_pad = MachO.round(old_install_name.size, cmd_round) - old_install_name.size
279
- new_pad = MachO.round(new_install_name.size, cmd_round) - new_install_name.size
280
-
281
- old_install_name << "\x00" * old_pad
282
- new_install_name << "\x00" * new_pad
283
-
284
- new_size = DylibCommand.bytesize + new_install_name.size
285
- new_sizeofcmds += new_size - dylib_cmd.cmdsize
286
-
287
- low_fileoff = 2**64
288
-
289
- segments.each do |seg|
290
- sections(seg).each do |sect|
291
- if sect.size != 0 && !sect.flag?(S_ZEROFILL) &&
292
- !sect.flag?(S_THREAD_LOCAL_ZEROFILL) &&
293
- sect.offset < low_fileoff
294
-
295
- low_fileoff = sect.offset
296
- end
297
- end
298
- end
299
-
300
- if new_sizeofcmds + header.bytesize > low_fileoff
301
- raise HeaderPadError.new(@filename)
302
- end
303
-
304
- set_sizeofcmds(new_sizeofcmds)
305
-
306
- @raw_data[dylib_cmd.offset + 4, 4] = [new_size].pack("V")
307
-
308
- @raw_data.slice!(dylib_cmd.offset + dylib_cmd.name...dylib_cmd.offset + dylib_cmd.class.bytesize + old_install_name.size)
309
-
310
- @raw_data.insert(dylib_cmd.offset + dylib_cmd.name, new_install_name)
311
-
312
- null_pad = old_install_name.size - new_install_name.size
313
-
314
- if null_pad < 0
315
- @raw_data.slice!(new_sizeofcmds + header.bytesize, null_pad.abs)
316
- else
317
- @raw_data.insert(new_sizeofcmds + header.bytesize, "\x00" * null_pad)
318
- end
319
-
320
- header = get_mach_header
321
- load_commands = get_load_commands
212
+ set_name_in_dylib(dylib_cmd, old_name, new_name)
322
213
  end
323
214
 
324
215
  alias :change_dylib :change_install_name
@@ -520,5 +411,77 @@ module MachO
520
411
  new_size = [size].pack("V")
521
412
  @raw_data[20..23] = new_size
522
413
  end
414
+
415
+ # Updates the `name` field in a DylibCommand, regardless of load command type
416
+ # @param dylib_cmd [MachO::DylibCommand] the dylib command
417
+ # @param old_name [String] the old dylib name
418
+ # @param new_name [String] the new dylib name
419
+ # @return [void]
420
+ # @private
421
+ def set_name_in_dylib(dylib_cmd, old_name, new_name)
422
+ if magic32?
423
+ cmd_round = 4
424
+ else
425
+ cmd_round = 8
426
+ end
427
+
428
+ new_sizeofcmds = header[:sizeofcmds]
429
+ old_name = old_name.dup
430
+ new_name = new_name.dup
431
+
432
+ old_pad = MachO.round(old_name.size, cmd_round) - old_name.size
433
+ new_pad = MachO.round(new_name.size, cmd_round) - new_name.size
434
+
435
+ # pad the old and new IDs with null bytes to meet command bounds
436
+ old_name << "\x00" * old_pad
437
+ new_name << "\x00" * new_pad
438
+
439
+ # calculate the new size of the DylibCommand and sizeofcmds in MH
440
+ new_size = DylibCommand.bytesize + new_name.size
441
+ new_sizeofcmds += new_size - dylib_cmd.cmdsize
442
+
443
+ low_fileoff = 2**64 # ULLONGMAX
444
+
445
+ # calculate the low file offset (offset to first section data)
446
+ segments.each do |seg|
447
+ sections(seg).each do |sect|
448
+ if sect.size != 0 && !sect.flag?(S_ZEROFILL) &&
449
+ !sect.flag?(S_THREAD_LOCAL_ZEROFILL) &&
450
+ sect.offset < low_fileoff
451
+
452
+ low_fileoff = sect.offset
453
+ end
454
+ end
455
+ end
456
+
457
+ if new_sizeofcmds + header.bytesize > low_fileoff
458
+ raise HeaderPadError.new(@filename)
459
+ end
460
+
461
+ # update sizeofcmds in mach_header
462
+ set_sizeofcmds(new_sizeofcmds)
463
+
464
+ # update cmdsize in the dylib_command
465
+ @raw_data[dylib_cmd.offset + 4, 4] = [new_size].pack("V")
466
+
467
+ # delete the old name
468
+ @raw_data.slice!(dylib_cmd.offset + dylib_cmd.name...dylib_cmd.offset + dylib_cmd.class.bytesize + old_name.size)
469
+
470
+ # insert the new id
471
+ @raw_data.insert(dylib_cmd.offset + dylib_cmd.name, new_name)
472
+
473
+ # pad/unpad after new_sizeofcmds until offsets are corrected
474
+ null_pad = old_name.size - new_name.size
475
+
476
+ if null_pad < 0
477
+ @raw_data.slice!(new_sizeofcmds + header.bytesize, null_pad.abs)
478
+ else
479
+ @raw_data.insert(new_sizeofcmds + header.bytesize, "\x00" * null_pad)
480
+ end
481
+
482
+ # synchronize fields with the raw data
483
+ @header = get_mach_header
484
+ @load_commands = get_load_commands
485
+ end
523
486
  end
524
487
  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.1
4
+ version: 0.1.2
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-24 00:00:00.000000000 Z
11
+ date: 2015-10-25 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