ruby-macho 4.0.0 → 4.1.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/macho/load_commands.rb +102 -3
- data/lib/macho/macho_file.rb +10 -4
- data/lib/macho/structure.rb +2 -2
- data/lib/macho.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf1e87b27661d19099f8a7160c774dab716e37be7dec050f84c701e9fc6c1ea6
|
4
|
+
data.tar.gz: 18d7705d4204bd10bd593b7ab8759058d2cea94eadeed9d7edce06b96d303a9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c6007d3ef6a175bf58c6b900a42aacdfd557d1f283f3e144828c25a3207f4791ef031c3313ace7a4f807b62ecf05ffb7944ca39d746d6446d23d20c0c4a6166
|
7
|
+
data.tar.gz: d7345efc2941999717f803ae9740067ee4a53cec738fd44c0ea5cee610f1b7d28bac8bf572f5558ff02f63a590ce323f024b9e2fd6e55977fc521dcb39ca2c03
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@ ruby-macho
|
|
2
2
|
================
|
3
3
|
|
4
4
|
[](http://badge.fury.io/rb/ruby-macho)
|
5
|
-
[](https://github.com/Homebrew/ruby-macho/actions/workflows/tests.yml)
|
6
6
|
[](https://codecov.io/gh/Homebrew/ruby-macho)
|
7
7
|
|
8
8
|
A Ruby library for examining and modifying Mach-O files.
|
data/lib/macho/load_commands.rb
CHANGED
@@ -65,6 +65,7 @@ module MachO
|
|
65
65
|
(LC_REQ_DYLD | 0x33) => :LC_DYLD_EXPORTS_TRIE,
|
66
66
|
(LC_REQ_DYLD | 0x34) => :LC_DYLD_CHAINED_FIXUPS,
|
67
67
|
(LC_REQ_DYLD | 0x35) => :LC_FILESET_ENTRY,
|
68
|
+
0x36 => :LC_ATOM_INFO,
|
68
69
|
}.freeze
|
69
70
|
|
70
71
|
# association of symbol representations to load command constants
|
@@ -110,7 +111,7 @@ module MachO
|
|
110
111
|
# "reserved for internal use only", no public struct
|
111
112
|
:LC_PREPAGE => "LoadCommand",
|
112
113
|
:LC_DYSYMTAB => "DysymtabCommand",
|
113
|
-
:LC_LOAD_DYLIB => "
|
114
|
+
:LC_LOAD_DYLIB => "DylibUseCommand",
|
114
115
|
:LC_ID_DYLIB => "DylibCommand",
|
115
116
|
:LC_LOAD_DYLINKER => "DylinkerCommand",
|
116
117
|
:LC_ID_DYLINKER => "DylinkerCommand",
|
@@ -122,7 +123,7 @@ module MachO
|
|
122
123
|
:LC_SUB_LIBRARY => "SubLibraryCommand",
|
123
124
|
:LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
|
124
125
|
:LC_PREBIND_CKSUM => "PrebindCksumCommand",
|
125
|
-
:LC_LOAD_WEAK_DYLIB => "
|
126
|
+
:LC_LOAD_WEAK_DYLIB => "DylibUseCommand",
|
126
127
|
:LC_SEGMENT_64 => "SegmentCommand64",
|
127
128
|
:LC_ROUTINES_64 => "RoutinesCommand64",
|
128
129
|
:LC_UUID => "UUIDCommand",
|
@@ -153,6 +154,7 @@ module MachO
|
|
153
154
|
:LC_DYLD_EXPORTS_TRIE => "LinkeditDataCommand",
|
154
155
|
:LC_DYLD_CHAINED_FIXUPS => "LinkeditDataCommand",
|
155
156
|
:LC_FILESET_ENTRY => "FilesetEntryCommand",
|
157
|
+
:LC_ATOM_INFO => "LinkeditDataCommand",
|
156
158
|
}.freeze
|
157
159
|
|
158
160
|
# association of segment name symbols to names
|
@@ -193,6 +195,20 @@ module MachO
|
|
193
195
|
:SG_READ_ONLY => 0x10,
|
194
196
|
}.freeze
|
195
197
|
|
198
|
+
# association of dylib use flag symbols to values
|
199
|
+
# @api private
|
200
|
+
DYLIB_USE_FLAGS = {
|
201
|
+
:DYLIB_USE_WEAK_LINK => 0x1,
|
202
|
+
:DYLIB_USE_REEXPORT => 0x2,
|
203
|
+
:DYLIB_USE_UPWARD => 0x4,
|
204
|
+
:DYLIB_USE_DELAYED_INIT => 0x8,
|
205
|
+
}.freeze
|
206
|
+
|
207
|
+
# the marker used to denote a newer style dylib use command.
|
208
|
+
# the value is the timestamp 24 January 1984 18:12:16
|
209
|
+
# @api private
|
210
|
+
DYLIB_USE_MARKER = 0x1a741800
|
211
|
+
|
196
212
|
# The top-level Mach-O load command structure.
|
197
213
|
#
|
198
214
|
# This is the most generic load command -- only the type ID and size are
|
@@ -231,6 +247,13 @@ module MachO
|
|
231
247
|
# cmd will be filled in, view and cmdsize will be left unpopulated
|
232
248
|
klass_arity = klass.min_args - 3
|
233
249
|
|
250
|
+
# macOS 15 introduces a new dylib load command that adds a flags field to the end.
|
251
|
+
# It uses the same commands with it dynamically being created if the dylib has a flags field
|
252
|
+
if klass == DylibUseCommand && (args[1] != DYLIB_USE_MARKER || args.size <= DylibCommand.min_args - 3)
|
253
|
+
klass = DylibCommand
|
254
|
+
klass_arity = klass.min_args - 3
|
255
|
+
end
|
256
|
+
|
234
257
|
raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity > args.size
|
235
258
|
|
236
259
|
klass.new(nil, cmd, nil, *args)
|
@@ -526,6 +549,23 @@ module MachO
|
|
526
549
|
# @return [Integer] the library's compatibility version number
|
527
550
|
field :compatibility_version, :uint32
|
528
551
|
|
552
|
+
# @example
|
553
|
+
# puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
|
554
|
+
# @param flag [Symbol] a dylib use command flag symbol
|
555
|
+
# @return [Boolean] true if `flag` applies to this dylib command
|
556
|
+
def flag?(flag)
|
557
|
+
case cmd
|
558
|
+
when LOAD_COMMAND_CONSTANTS[:LC_LOAD_WEAK_DYLIB]
|
559
|
+
flag == :DYLIB_USE_WEAK_LINK
|
560
|
+
when LOAD_COMMAND_CONSTANTS[:LC_REEXPORT_DYLIB]
|
561
|
+
flag == :DYLIB_USE_REEXPORT
|
562
|
+
when LOAD_COMMAND_CONSTANTS[:LC_LOAD_UPWARD_DYLIB]
|
563
|
+
flag == :DYLIB_USE_UPWARD
|
564
|
+
else
|
565
|
+
false
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
529
569
|
# @param context [SerializationContext]
|
530
570
|
# the context
|
531
571
|
# @return [String] the serialized fields of the load command
|
@@ -551,6 +591,65 @@ module MachO
|
|
551
591
|
end
|
552
592
|
end
|
553
593
|
|
594
|
+
# The newer format of load command representing some aspect of shared libraries,
|
595
|
+
# depending on filetype. Corresponds to LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB.
|
596
|
+
class DylibUseCommand < DylibCommand
|
597
|
+
# @return [Integer] any flags associated with this dylib use command
|
598
|
+
field :flags, :uint32
|
599
|
+
|
600
|
+
alias marker timestamp
|
601
|
+
|
602
|
+
# Instantiates a new DylibCommand or DylibUseCommand.
|
603
|
+
# macOS 15 and later use a new format for dylib commands (DylibUseCommand),
|
604
|
+
# which is determined based on a special timestamp and the name offset.
|
605
|
+
# @param view [MachO::MachOView] the load command's raw view
|
606
|
+
# @return [DylibCommand] the new dylib load command
|
607
|
+
# @api private
|
608
|
+
def self.new_from_bin(view)
|
609
|
+
dylib_command = DylibCommand.new_from_bin(view)
|
610
|
+
|
611
|
+
if dylib_command.timestamp == DYLIB_USE_MARKER &&
|
612
|
+
dylib_command.name.to_i == DylibUseCommand.bytesize
|
613
|
+
super(view)
|
614
|
+
else
|
615
|
+
dylib_command
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
# @example
|
620
|
+
# puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
|
621
|
+
# @param flag [Symbol] a dylib use command flag symbol
|
622
|
+
# @return [Boolean] true if `flag` applies to this dylib command
|
623
|
+
def flag?(flag)
|
624
|
+
flag = DYLIB_USE_FLAGS[flag]
|
625
|
+
|
626
|
+
return false if flag.nil?
|
627
|
+
|
628
|
+
flags & flag == flag
|
629
|
+
end
|
630
|
+
|
631
|
+
# @param context [SerializationContext]
|
632
|
+
# the context
|
633
|
+
# @return [String] the serialized fields of the load command
|
634
|
+
# @api private
|
635
|
+
def serialize(context)
|
636
|
+
format = Utils.specialize_format(self.class.format, context.endianness)
|
637
|
+
string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
|
638
|
+
context.alignment,
|
639
|
+
:name => name.to_s)
|
640
|
+
cmdsize = self.class.bytesize + string_payload.bytesize
|
641
|
+
[cmd, cmdsize, string_offsets[:name], marker, current_version,
|
642
|
+
compatibility_version, flags].pack(format) + string_payload
|
643
|
+
end
|
644
|
+
|
645
|
+
# @return [Hash] a hash representation of this {DylibUseCommand}
|
646
|
+
def to_h
|
647
|
+
{
|
648
|
+
"flags" => flags,
|
649
|
+
}.merge super
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
554
653
|
# A load command representing some aspect of the dynamic linker, depending
|
555
654
|
# on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
|
556
655
|
# LC_DYLD_ENVIRONMENT.
|
@@ -958,7 +1057,7 @@ module MachO
|
|
958
1057
|
# the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE,
|
959
1058
|
# LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
|
960
1059
|
# LC_DYLIB_CODE_SIGN_DRS, LC_LINKER_OPTIMIZATION_HINT, LC_DYLD_EXPORTS_TRIE,
|
961
|
-
# or
|
1060
|
+
# LC_DYLD_CHAINED_FIXUPS, or LC_ATOM_INFO.
|
962
1061
|
class LinkeditDataCommand < LoadCommand
|
963
1062
|
# @return [Integer] offset to the data in the __LINKEDIT segment
|
964
1063
|
field :dataoff, :uint32
|
data/lib/macho/macho_file.rb
CHANGED
@@ -411,9 +411,15 @@ module MachO
|
|
411
411
|
|
412
412
|
# Delete the given runtime path from the Mach-O.
|
413
413
|
# @example
|
414
|
-
#
|
415
|
-
#
|
416
|
-
#
|
414
|
+
# file1.rpaths # => ["/lib", "/usr/lib", "/lib"]
|
415
|
+
# file1.delete_rpath("/lib")
|
416
|
+
# file1.rpaths # => ["/usr/lib", "/lib"]
|
417
|
+
# file2.rpaths # => ["foo", "foo"]
|
418
|
+
# file2.delete_rpath("foo", :uniq => true)
|
419
|
+
# file2.rpaths # => []
|
420
|
+
# file3.rpaths # => ["foo", "bar", "foo"]
|
421
|
+
# file3.delete_rpath("foo", :last => true)
|
422
|
+
# file3.rpaths # => ["foo", "bar"]
|
417
423
|
# @param path [String] the runtime path to delete
|
418
424
|
# @param options [Hash]
|
419
425
|
# @option options [Boolean] :uniq (false) if true, also delete
|
@@ -421,7 +427,7 @@ module MachO
|
|
421
427
|
# instance (by offset) of the requested path, unless :last is true.
|
422
428
|
# Incompatible with :last.
|
423
429
|
# @option options [Boolean] :last (false) if true, delete the last
|
424
|
-
#
|
430
|
+
# instance (by offset) of the requested path. Incompatible with :uniq.
|
425
431
|
# @return void
|
426
432
|
# @raise [RpathUnknownError] if no such runtime path exists
|
427
433
|
# @raise [ArgumentError] if both :uniq and :last are true
|
data/lib/macho/structure.rb
CHANGED
@@ -131,7 +131,7 @@ module MachO
|
|
131
131
|
|
132
132
|
# @param name [Symbol] name of internal field
|
133
133
|
# @param type [Symbol] type of field in terms of binary size
|
134
|
-
# @param options [Hash] set of
|
134
|
+
# @param options [Hash] set of additional options
|
135
135
|
# Expected options
|
136
136
|
# :size [Integer] size in bytes
|
137
137
|
# :mask [Integer] bitmask
|
@@ -236,7 +236,7 @@ module MachO
|
|
236
236
|
# Generates a reader method for fields that need further unpacking.
|
237
237
|
# @param name [Symbol] name of internal field
|
238
238
|
# @param idx [Integer] the index of the field value in the @values array
|
239
|
-
# @param unpack [String] the format code used for
|
239
|
+
# @param unpack [String] the format code used for further binary unpacking
|
240
240
|
# @api private
|
241
241
|
def def_unpack_reader(name, idx, unpack)
|
242
242
|
define_method(name) do
|
data/lib/macho.rb
CHANGED
@@ -16,7 +16,7 @@ require_relative "macho/tools"
|
|
16
16
|
# The primary namespace for ruby-macho.
|
17
17
|
module MachO
|
18
18
|
# release version
|
19
|
-
VERSION = "4.
|
19
|
+
VERSION = "4.1.0"
|
20
20
|
|
21
21
|
# Opens the given filename as a MachOFile or FatFile, depending on its magic.
|
22
22
|
# @param filename [String] the file being opened
|
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: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Woodruff
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-06-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@yossarian.net
|
@@ -35,7 +35,7 @@ licenses:
|
|
35
35
|
- MIT
|
36
36
|
metadata:
|
37
37
|
rubygems_mfa_required: 'true'
|
38
|
-
post_install_message:
|
38
|
+
post_install_message:
|
39
39
|
rdoc_options: []
|
40
40
|
require_paths:
|
41
41
|
- lib
|
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
51
|
version: '0'
|
52
52
|
requirements: []
|
53
53
|
rubygems_version: 3.4.10
|
54
|
-
signing_key:
|
54
|
+
signing_key:
|
55
55
|
specification_version: 4
|
56
56
|
summary: ruby-macho - Mach-O file analyzer.
|
57
57
|
test_files: []
|