ruby-macho 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/ruby-macho.svg)](http://badge.fury.io/rb/ruby-macho)
|
5
|
-
[![
|
5
|
+
[![CI](https://github.com/Homebrew/ruby-macho/actions/workflows/tests.yml/badge.svg)](https://github.com/Homebrew/ruby-macho/actions/workflows/tests.yml)
|
6
6
|
[![Coverage Status](https://codecov.io/gh/Homebrew/ruby-macho/branch/master/graph/badge.svg)](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: []
|