ruby-macho 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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