ruby-macho 0.1.6 → 0.1.8

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: 804e6a31dedb8f86966c6e53366730c1ac87c2c2
4
- data.tar.gz: 3a4f11ddc1807e34f158f22f446b561cbc5e9e07
3
+ metadata.gz: 16240f8ca67e156531a460441d739de7d63fbe9e
4
+ data.tar.gz: 9a4baa19c7d468ea968a1d0eac8f12941053fcf4
5
5
  SHA512:
6
- metadata.gz: 99c430de85ed1154fe02a70a0443535fdc5fd3e4a5b3a4d16e857dad770784977d0dfe73f6a75879408877b44ba86c73b4d1755ae782420f2364a1dd4acc3eb0
7
- data.tar.gz: d4877cb5eea705217b930175167a7f2330ef255e51cf403d12f13f174b61ad6e91f57bfdf554f379a0a8cb7651093128456a639f77fad874b66fdcb6f788cde1
6
+ metadata.gz: cbf7d99140e66376e18dfae8efc2e0b1d9d921e4f5ba3813a6cf09f478ec5a6de2a777b6b4b582afcf8427a005d3807c6b72f13862b4d7c0d30c476a8711d547
7
+ data.tar.gz: f2a8064e9246c8b1d5f671edc830a902023f754458a2cc6a4abed62dde247e698d1b955eff5c9e91f8951e66fe6d095fd6677f8a9a7e45f0c34acb435f2b2ed5
data/lib/macho.rb CHANGED
@@ -4,24 +4,13 @@ require "#{File.dirname(__FILE__)}/macho/load_commands"
4
4
  require "#{File.dirname(__FILE__)}/macho/sections"
5
5
  require "#{File.dirname(__FILE__)}/macho/macho_file"
6
6
  require "#{File.dirname(__FILE__)}/macho/fat_file"
7
+ require "#{File.dirname(__FILE__)}/macho/open"
7
8
  require "#{File.dirname(__FILE__)}/macho/exceptions"
8
9
  require "#{File.dirname(__FILE__)}/macho/utils"
9
10
  require "#{File.dirname(__FILE__)}/macho/tools"
10
11
 
11
12
  # The primary namespace for ruby-macho.
12
13
  module MachO
13
- # Opens the given filename as a MachOFile or FatFile, depending on its magic.
14
- # @param filename [String] the file being opened
15
- # @return [MachO::MachOFile] if the file is a Mach-O
16
- # @return [MachO::FatFile] if the file is a Fat file
17
- def self.open(filename)
18
- # open file and test magic instead of using exceptions for control?
19
- begin
20
- file = MachOFile.new(filename)
21
- rescue FatBinaryError
22
- file = FatFile.new(filename)
23
- end
24
-
25
- file
26
- end
14
+ # release version
15
+ VERSION = "0.1.8".freeze
27
16
  end
@@ -32,6 +32,64 @@ module MachO
32
32
  @raw_data
33
33
  end
34
34
 
35
+ # @return [Boolean] true if the Mach-O is of type `MH_OBJECT`, false otherwise
36
+ def object?
37
+ machos.first.object?
38
+ end
39
+
40
+ # @return [Boolean] true if the Mach-O is of type `MH_EXECUTE`, false otherwise
41
+ def executable?
42
+ machos.first.executable?
43
+ end
44
+
45
+ # @return [Boolean] true if the Mach-O is of type `MH_FVMLIB`, false otherwise
46
+ def fvmlib?
47
+ machos.first.fvmlib?
48
+ end
49
+
50
+ # @return [Boolean] true if the Mach-O is of type `MH_CORE`, false otherwise
51
+ def core?
52
+ machos.first.core?
53
+ end
54
+
55
+ # @return [Boolean] true if the Mach-O is of type `MH_PRELOAD`, false otherwise
56
+ def preload?
57
+ machos.first.preload?
58
+ end
59
+
60
+ # @return [Boolean] true if the Mach-O is of type `MH_DYLIB`, false otherwise
61
+ def dylib?
62
+ machos.first.dylib?
63
+ end
64
+
65
+ # @return [Boolean] true if the Mach-O is of type `MH_DYLINKER`, false otherwise
66
+ def dylinker?
67
+ machos.first.dylinker?
68
+ end
69
+
70
+ # @return [Boolean] true if the Mach-O is of type `MH_BUNDLE`, false otherwise
71
+ def bundle?
72
+ machos.first.bundle?
73
+ end
74
+
75
+ # @return [Boolean] true if the Mach-O is of type `MH_DSYM`, false otherwise
76
+ def dsym?
77
+ machos.first.dsym?
78
+ end
79
+
80
+ # @return [Boolean] true if the Mach-O is of type `MH_KEXT_BUNDLE`, false otherwise
81
+ def kext?
82
+ machos.first.kext?
83
+ end
84
+
85
+ def magic
86
+ header.magic
87
+ end
88
+
89
+ def magic_string
90
+ MH_MAGICS[magic]
91
+ end
92
+
35
93
  # The file's type. Assumed to be the same for every Mach-O within.
36
94
  # @return [String] the filetype
37
95
  def filetype
@@ -3,247 +3,107 @@ module MachO
3
3
  # LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
4
4
  LC_REQ_DYLD = 0x80000000
5
5
 
6
- # segment of this file to be mapped
7
- LC_SEGMENT = 0x1
8
-
9
- # link-edit stab symbol table info
10
- LC_SYMTAB = 0x2
11
-
12
- # link-edit gdb symbol table info (obsolete)
13
- LC_SYMSEG = 0x3
14
-
15
- # thread
16
- LC_THREAD = 0x4
17
-
18
- # unix thread (includes a stack)
19
- LC_UNIXTHREAD = 0x5
20
-
21
- # load a specified fixed VM shared library
22
- LC_LOADFVMLIB = 0x6
23
-
24
- # fixed VM shared library identification
25
- LC_IDFVMLIB = 0x7
26
-
27
- # object identification info (obsolete)
28
- LC_IDENT = 0x8
29
-
30
- # fixed VM file inclusion (internal use)
31
- LC_FVMFILE = 0x9
32
-
33
- # prepage command (internal use)
34
- LC_PREPAGE = 0xa
35
-
36
- # dynamic link-edit symbol table info
37
- LC_DYSYMTAB = 0xb
38
-
39
- # load a dynamically linked shared library
40
- LC_LOAD_DYLIB = 0xc
41
-
42
- # dynamically linked shared lib ident
43
- LC_ID_DYLIB = 0xd
44
-
45
- # load a dynamic linker
46
- LC_LOAD_DYLINKER = 0xe
47
-
48
- # dynamic linker identification
49
- LC_ID_DYLINKER = 0xf
50
-
51
- # modules prebound for a dynamically linked shared library
52
- LC_PREBOUND_DYLIB = 0x10
53
-
54
- # image routines
55
- LC_ROUTINES = 0x11
56
-
57
- # sub framework
58
- LC_SUB_FRAMEWORK = 0x12
59
-
60
- # sub umbrella
61
- LC_SUB_UMBRELLA = 0x13
62
-
63
- # sub umbrella
64
- LC_SUB_CLIENT = 0x14
65
-
66
- # sub umbrella
67
- LC_SUB_LIBRARY = 0x15
68
-
69
- # two-level namespace lookup hints
70
- LC_TWOLEVEL_HINTS = 0x16
71
-
72
- # prebind checksum
73
- LC_PREBIND_CKSUM = 0x17
74
-
75
- # load a dynamically linked shared library that is allowed to be missing (all symbols are weak imported).
76
- LC_LOAD_WEAK_DYLIB = (0x18 | LC_REQ_DYLD)
77
-
78
- # 64-bit segment of this file to be mapped
79
- LC_SEGMENT_64 = 0x19
80
-
81
- # 64-bit image routines
82
- LC_ROUTINES_64 = 0x1a
83
-
84
- # the uuid
85
- LC_UUID = 0x1b
86
-
87
- # runpath additions
88
- LC_RPATH = (0x1c | LC_REQ_DYLD)
89
-
90
- # local of code signature
91
- LC_CODE_SIGNATURE = 0x1d
92
-
93
- # local of info to split segments
94
- LC_SEGMENT_SPLIT_INFO = 0x1e
95
-
96
- # load and re-export dylib
97
- LC_REEXPORT_DYLIB = (0x1f | LC_REQ_DYLD)
98
-
99
- # delay load of dylib until first use
100
- LC_LAZY_LOAD_DYLIB = 0x20
101
-
102
- # encrypted segment information
103
- LC_ENCRYPTION_INFO = 0x21
104
-
105
- # compressed dyld information
106
- LC_DYLD_INFO = 0x22
107
-
108
- # compressed dyld information only
109
- LC_DYLD_INFO_ONLY = (0x22 | LC_REQ_DYLD)
110
-
111
- # load upward dylib
112
- LC_LOAD_UPWARD_DYLIB = (0x23 | LC_REQ_DYLD)
113
-
114
- # build for MacOSX min OS version
115
- LC_VERSION_MIN_MACOSX = 0x24
116
-
117
- # build for iPhoneOS min OS version
118
- LC_VERSION_MIN_IPHONEOS = 0x25
119
-
120
- # compressed table of function start addresses
121
- LC_FUNCTION_STARTS = 0x26
122
-
123
- # string for dyld to treat like environment variable
124
- LC_DYLD_ENVIRONMENT = 0x27
125
-
126
- # replacement for LC_UNIXTHREAD
127
- LC_MAIN = (0x28 | LC_REQ_DYLD)
128
-
129
- # table of non-instructions in __text
130
- LC_DATA_IN_CODE = 0x29
131
-
132
- # source version used to build binary
133
- LC_SOURCE_VERSION = 0x2a
134
-
135
- # Code signing DRs copied from linked dylibs
136
- LC_DYLIB_CODE_SIGN_DRS = 0x2b
137
-
138
- # 64-bit encrypted segment information
139
- LC_ENCRYPTION_INFO_64 = 0x2c
140
-
141
- # linker options in MH_OBJECT files
142
- LC_LINKER_OPTION = 0x2d
143
-
144
- # linker options in MH_OBJECT files
145
- LC_LINKER_OPTIMIZATION_HINT = 0x2e
146
-
147
6
  # association of load commands to string representations
7
+ # @api private
148
8
  LOAD_COMMANDS = {
149
- LC_SEGMENT => "LC_SEGMENT",
150
- LC_SYMTAB => "LC_SYMTAB",
151
- LC_SYMSEG => "LC_SYMSEG",
152
- LC_THREAD => "LC_THREAD",
153
- LC_UNIXTHREAD => "LC_UNIXTHREAD",
154
- LC_LOADFVMLIB => "LC_LOADFVMLIB",
155
- LC_IDFVMLIB => "LC_IDFVMLIB",
156
- LC_IDENT => "LC_IDENT",
157
- LC_FVMFILE => "LC_FVMFILE",
158
- LC_PREPAGE => "LC_PREPAGE",
159
- LC_DYSYMTAB => "LC_DYSYMTAB",
160
- LC_LOAD_DYLIB => "LC_LOAD_DYLIB",
161
- LC_ID_DYLIB => "LC_ID_DYLIB",
162
- LC_LOAD_DYLINKER => "LC_LOAD_DYLINKER",
163
- LC_ID_DYLINKER => "LC_ID_DYLINKER",
164
- LC_PREBOUND_DYLIB => "LC_PREBOUND_DYLIB",
165
- LC_ROUTINES => "LC_ROUTINES",
166
- LC_SUB_FRAMEWORK => "LC_SUB_FRAMEWORK",
167
- LC_SUB_UMBRELLA => "LC_SUB_UMBRELLA",
168
- LC_SUB_CLIENT => "LC_SUB_CLIENT",
169
- LC_SUB_LIBRARY => "LC_SUB_LIBRARY",
170
- LC_TWOLEVEL_HINTS => "LC_TWOLEVEL_HINTS",
171
- LC_PREBIND_CKSUM => "LC_PREBIND_CKSUM",
172
- LC_LOAD_WEAK_DYLIB => "LC_LOAD_WEAK_DYLIB",
173
- LC_SEGMENT_64 => "LC_SEGMENT_64",
174
- LC_ROUTINES_64 => "LC_ROUTINES_64",
175
- LC_UUID => "LC_UUID",
176
- LC_RPATH => "LC_RPATH",
177
- LC_CODE_SIGNATURE => "LC_CODE_SIGNATURE",
178
- LC_SEGMENT_SPLIT_INFO => "LC_SEGMENT_SPLIT_INFO",
179
- LC_REEXPORT_DYLIB => "LC_REEXPORT_DYLIB",
180
- LC_LAZY_LOAD_DYLIB => "LC_LAZY_LOAD_DYLIB",
181
- LC_ENCRYPTION_INFO => "LC_ENCRYPTION_INFO",
182
- LC_DYLD_INFO => "LC_DYLD_INFO",
183
- LC_DYLD_INFO_ONLY => "LC_DYLD_INFO_ONLY",
184
- LC_LOAD_UPWARD_DYLIB => "LC_LOAD_UPWARD_DYLIB",
185
- LC_VERSION_MIN_MACOSX => "LC_VERSION_MIN_MACOSX",
186
- LC_VERSION_MIN_IPHONEOS => "LC_VERSION_MIN_IPHONEOS",
187
- LC_FUNCTION_STARTS => "LC_FUNCTION_STARTS",
188
- LC_DYLD_ENVIRONMENT => "LC_DYLD_ENVIRONMENT",
189
- LC_MAIN => "LC_MAIN",
190
- LC_DATA_IN_CODE => "LC_DATA_IN_CODE",
191
- LC_SOURCE_VERSION => "LC_SOURCE_VERSION",
192
- LC_DYLIB_CODE_SIGN_DRS => "LC_DYLIB_CODE_SIGN_DRS",
193
- LC_ENCRYPTION_INFO_64 => "LC_ENCRYPTION_INFO_64",
194
- LC_LINKER_OPTION => "LC_LINKER_OPTION",
195
- LC_LINKER_OPTIMIZATION_HINT => "LC_LINKER_OPTIMIZATION_HINT"
9
+ 0x1 => :LC_SEGMENT,
10
+ 0x2 => :LC_SYMTAB,
11
+ 0x3 => :LC_SYMSEG,
12
+ 0x4 => :LC_THREAD,
13
+ 0x5 => :LC_UNIXTHREAD,
14
+ 0x6 => :LC_LOADFVMLIB,
15
+ 0x7 => :LC_IDFVMLIB,
16
+ 0x8 => :LC_IDENT,
17
+ 0x9 => :LC_FVMFILE,
18
+ 0xa => :LC_PREPAGE,
19
+ 0xb => :LC_DYSYMTAB,
20
+ 0xc => :LC_LOAD_DYLIB,
21
+ 0xd => :LC_ID_DYLIB,
22
+ 0xe => :LC_LOAD_DYLINKER,
23
+ 0xf => :LC_ID_DYLINKER,
24
+ 0x10 => :LC_PREBOUND_DYLIB,
25
+ 0x11 => :LC_ROUTINES,
26
+ 0x12 => :LC_SUB_FRAMEWORK,
27
+ 0x13 => :LC_SUB_UMBRELLA,
28
+ 0x14 => :LC_SUB_CLIENT,
29
+ 0x15 => :LC_SUB_LIBRARY,
30
+ 0x16 => :LC_TWOLEVEL_HINTS,
31
+ 0x17 => :LC_PREBIND_CKSUM,
32
+ (0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
33
+ 0x19 => :LC_SEGMENT_64,
34
+ 0x1a => :LC_ROUTINES_64,
35
+ 0x1b => :LC_UUID,
36
+ (0x1c | LC_REQ_DYLD) => :LC_RPATH,
37
+ 0x1d => :LC_CODE_SIGNATURE,
38
+ 0x1e => :LC_SEGMENT_SPLIT_INFO,
39
+ (0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
40
+ 0x20 => :LC_LAZY_LOAD_DYLIB,
41
+ 0x21 => :LC_ENCRYPTION_INFO,
42
+ 0x22 => :LC_DYLD_INFO,
43
+ (0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
44
+ (0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
45
+ 0x24 => :LC_VERSION_MIN_MACOSX,
46
+ 0x25 => :LC_VERSION_MIN_IPHONEOS,
47
+ 0x26 => :LC_FUNCTION_STARTS,
48
+ 0x27 => :LC_DYLD_ENVIRONMENT,
49
+ (0x28 | LC_REQ_DYLD) => :LC_MAIN,
50
+ 0x29 => :LC_DATA_IN_CODE,
51
+ 0x2a => :LC_SOURCE_VERSION,
52
+ 0x2b => :LC_DYLIB_CODE_SIGN_DRS,
53
+ 0x2c => :LC_ENCRYPTION_INFO_64,
54
+ 0x2d => :LC_LINKER_OPTION,
55
+ 0x2e => :LC_LINKER_OPTIMIZATION_HINT
196
56
  }
197
57
 
198
58
  # association of load commands to string representations of class names
199
59
  LC_STRUCTURES = {
200
- LC_SEGMENT => "SegmentCommand",
201
- LC_SYMTAB => "SymtabCommand",
202
- LC_SYMSEG => "LoadCommand", # obsolete
203
- LC_THREAD => "ThreadCommand",
204
- LC_UNIXTHREAD => "ThreadCommand",
205
- LC_LOADFVMLIB => "LoadCommand", # obsolete
206
- LC_IDFVMLIB => "LoadCommand", # obsolete
207
- LC_IDENT => "LoadCommand", # obsolete
208
- LC_FVMFILE => "LoadCommand", # reserved for internal use only
209
- LC_PREPAGE => "LoadCommand", # reserved for internal use only
210
- LC_DYSYMTAB => "DysymtabCommand",
211
- LC_LOAD_DYLIB => "DylibCommand",
212
- LC_ID_DYLIB => "DylibCommand",
213
- LC_LOAD_DYLINKER => "DylinkerCommand",
214
- LC_ID_DYLINKER => "DylinkerCommand",
215
- LC_PREBOUND_DYLIB => "PreboundDylibCommand",
216
- LC_ROUTINES => "RoutinesCommand",
217
- LC_SUB_FRAMEWORK => "SubFrameworkCommand",
218
- LC_SUB_UMBRELLA => "SubUmbrellaCommand",
219
- LC_SUB_CLIENT => "SubClientCommand",
220
- LC_SUB_LIBRARY => "SubLibraryCommand",
221
- LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
222
- LC_PREBIND_CKSUM => "PrebindCksumCommand",
223
- LC_LOAD_WEAK_DYLIB => "DylibCommand",
224
- LC_SEGMENT_64 => "SegmentCommand64",
225
- LC_ROUTINES_64 => "RoutinesCommand64",
226
- LC_UUID => "UUIDCommand",
227
- LC_RPATH => "RpathCommand",
228
- LC_CODE_SIGNATURE => "LinkeditDataCommand",
229
- LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
230
- LC_REEXPORT_DYLIB => "DylibCommand",
231
- LC_LAZY_LOAD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
232
- LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
233
- LC_DYLD_INFO => "DyldInfoCommand",
234
- LC_DYLD_INFO_ONLY => "DyldInfoCommand",
235
- LC_LOAD_UPWARD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
236
- LC_VERSION_MIN_MACOSX => "VersionMinCommand",
237
- LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
238
- LC_FUNCTION_STARTS => "LinkeditDataCommand",
239
- LC_DYLD_ENVIRONMENT => "DylinkerCommand",
240
- LC_MAIN => "EntryPointCommand",
241
- LC_DATA_IN_CODE => "LinkeditDataCommand",
242
- LC_SOURCE_VERSION => "SourceVersionCommand",
243
- LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
244
- LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
245
- LC_LINKER_OPTION => "LinkerOptionCommand",
246
- LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand"
60
+ :LC_SEGMENT => "SegmentCommand",
61
+ :LC_SYMTAB => "SymtabCommand",
62
+ :LC_SYMSEG => "LoadCommand", # obsolete
63
+ :LC_THREAD => "ThreadCommand",
64
+ :LC_UNIXTHREAD => "ThreadCommand",
65
+ :LC_LOADFVMLIB => "LoadCommand", # obsolete
66
+ :LC_IDFVMLIB => "LoadCommand", # obsolete
67
+ :LC_IDENT => "LoadCommand", # obsolete
68
+ :LC_FVMFILE => "LoadCommand", # reserved for internal use only
69
+ :LC_PREPAGE => "LoadCommand", # reserved for internal use only
70
+ :LC_DYSYMTAB => "DysymtabCommand",
71
+ :LC_LOAD_DYLIB => "DylibCommand",
72
+ :LC_ID_DYLIB => "DylibCommand",
73
+ :LC_LOAD_DYLINKER => "DylinkerCommand",
74
+ :LC_ID_DYLINKER => "DylinkerCommand",
75
+ :LC_PREBOUND_DYLIB => "PreboundDylibCommand",
76
+ :LC_ROUTINES => "RoutinesCommand",
77
+ :LC_SUB_FRAMEWORK => "SubFrameworkCommand",
78
+ :LC_SUB_UMBRELLA => "SubUmbrellaCommand",
79
+ :LC_SUB_CLIENT => "SubClientCommand",
80
+ :LC_SUB_LIBRARY => "SubLibraryCommand",
81
+ :LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
82
+ :LC_PREBIND_CKSUM => "PrebindCksumCommand",
83
+ :LC_LOAD_WEAK_DYLIB => "DylibCommand",
84
+ :LC_SEGMENT_64 => "SegmentCommand64",
85
+ :LC_ROUTINES_64 => "RoutinesCommand64",
86
+ :LC_UUID => "UUIDCommand",
87
+ :LC_RPATH => "RpathCommand",
88
+ :LC_CODE_SIGNATURE => "LinkeditDataCommand",
89
+ :LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
90
+ :LC_REEXPORT_DYLIB => "DylibCommand",
91
+ :LC_LAZY_LOAD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
92
+ :LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
93
+ :LC_DYLD_INFO => "DyldInfoCommand",
94
+ :LC_DYLD_INFO_ONLY => "DyldInfoCommand",
95
+ :LC_LOAD_UPWARD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
96
+ :LC_VERSION_MIN_MACOSX => "VersionMinCommand",
97
+ :LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
98
+ :LC_FUNCTION_STARTS => "LinkeditDataCommand",
99
+ :LC_DYLD_ENVIRONMENT => "DylinkerCommand",
100
+ :LC_MAIN => "EntryPointCommand",
101
+ :LC_DATA_IN_CODE => "LinkeditDataCommand",
102
+ :LC_SOURCE_VERSION => "SourceVersionCommand",
103
+ :LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
104
+ :LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
105
+ :LC_LINKER_OPTION => "LinkerOptionCommand",
106
+ :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand"
247
107
  }
248
108
 
249
109
  # pagezero segment name
@@ -319,9 +179,16 @@ module MachO
319
179
  @cmdsize = cmdsize
320
180
  end
321
181
 
182
+ # @return [Symbol] a symbol representation of the load command's identifying number
183
+ def type
184
+ LOAD_COMMANDS[cmd]
185
+ end
186
+
187
+ alias :to_sym :type
188
+
322
189
  # @return [String] a string representation of the load command's identifying number
323
190
  def to_s
324
- LOAD_COMMANDS[cmd]
191
+ type.to_s
325
192
  end
326
193
 
327
194
  # Represents a Load Command string. A rough analogue to the lc_str
@@ -382,7 +249,7 @@ module MachO
382
249
  # A load command indicating that part of this file is to be mapped into
383
250
  # the task's address space. Corresponds to LC_SEGMENT.
384
251
  class SegmentCommand < LoadCommand
385
- # @return [String] the name of the segment, including null padding bytes
252
+ # @return [String] the name of the segment
386
253
  attr_reader :segname
387
254
 
388
255
  # @return [Fixnum] the memory address of the segment
@@ -416,7 +283,7 @@ module MachO
416
283
  def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
417
284
  filesize, maxprot, initprot, nsects, flags)
418
285
  super(raw_data, offset, cmd, cmdsize)
419
- @segname = segname
286
+ @segname = segname.delete("\x00")
420
287
  @vmaddr = vmaddr
421
288
  @vmsize = vmsize
422
289
  @fileoff = fileoff
@@ -426,17 +293,12 @@ module MachO
426
293
  @nsects = nsects
427
294
  @flags = flags
428
295
  end
429
-
430
- # @return [String] the segment's name, with any trailing NULL characters removed
431
- def segment_name
432
- @segname.delete("\x00")
433
- end
434
296
  end
435
297
 
436
298
  # A load command indicating that part of this file is to be mapped into
437
299
  # the task's address space. Corresponds to LC_SEGMENT_64.
438
300
  class SegmentCommand64 < LoadCommand
439
- # @return [String] the name of the segment, including null padding bytes
301
+ # @return [String] the name of the segment
440
302
  attr_reader :segname
441
303
 
442
304
  # @return [Fixnum] the memory address of the segment
@@ -470,7 +332,7 @@ module MachO
470
332
  def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
471
333
  filesize, maxprot, initprot, nsects, flags)
472
334
  super(raw_data, offset, cmd, cmdsize)
473
- @segname = segname
335
+ @segname = segname.delete("\x00")
474
336
  @vmaddr = vmaddr
475
337
  @vmsize = vmsize
476
338
  @fileoff = fileoff
@@ -480,11 +342,6 @@ module MachO
480
342
  @nsects = nsects
481
343
  @flags = flags
482
344
  end
483
-
484
- # @return [String] the segment's name, with any trailing NULL characters removed
485
- def segment_name
486
- @segname.delete("\x00")
487
- end
488
345
  end
489
346
 
490
347
  # A load command representing some aspect of shared libraries, depending
@@ -58,21 +58,56 @@ module MachO
58
58
  MachO.magic64?(header.magic)
59
59
  end
60
60
 
61
+ # @return [Boolean] true if the Mach-O is of type `MH_OBJECT`, false otherwise
62
+ def object?
63
+ header.filetype == MH_OBJECT
64
+ end
65
+
61
66
  # @return [Boolean] true if the Mach-O is of type `MH_EXECUTE`, false otherwise
62
67
  def executable?
63
68
  header.filetype == MH_EXECUTE
64
69
  end
65
70
 
71
+ # @return [Boolean] true if the Mach-O is of type `MH_FVMLIB`, false otherwise
72
+ def fvmlib?
73
+ header.filetype == MH_FVMLIB
74
+ end
75
+
76
+ # @return [Boolean] true if the Mach-O is of type `MH_CORE`, false otherwise
77
+ def core?
78
+ header.filetype == MH_CORE
79
+ end
80
+
81
+ # @return [Boolean] true if the Mach-O is of type `MH_PRELOAD`, false otherwise
82
+ def preload?
83
+ header.filetype == MH_PRELOAD
84
+ end
85
+
66
86
  # @return [Boolean] true if the Mach-O is of type `MH_DYLIB`, false otherwise
67
87
  def dylib?
68
88
  header.filetype == MH_DYLIB
69
89
  end
70
90
 
91
+ # @return [Boolean] true if the Mach-O is of type `MH_DYLINKER`, false otherwise
92
+ def dylinker?
93
+ header.filetype == MH_DYLINKER
94
+ end
95
+
71
96
  # @return [Boolean] true if the Mach-O is of type `MH_BUNDLE`, false otherwise
72
97
  def bundle?
73
98
  header.filetype == MH_BUNDLE
74
99
  end
75
100
 
101
+ # @return [Boolean] true if the Mach-O is of type `MH_DSYM`, false otherwise
102
+ def dsym?
103
+ header.filetype == MH_DSYM
104
+ end
105
+
106
+ # @return [Boolean] true if the Mach-O is of type `MH_KEXT_BUNDLE`, false otherwise
107
+ def kext?
108
+ header.filetype == MH_KEXT_BUNDLE
109
+ end
110
+
76
111
  # @return [Fixnum] the Mach-O's magic number
77
112
  def magic
78
113
  header.magic
@@ -80,7 +115,7 @@ module MachO
80
115
 
81
116
  # @return [String] a string representation of the Mach-O's magic number
82
117
  def magic_string
83
- MH_MAGICS[header.magic]
118
+ MH_MAGICS[magic]
84
119
  end
85
120
 
86
121
  # @return [String] a string representation of the Mach-O's filetype
@@ -116,10 +151,11 @@ module MachO
116
151
  # All load commands of a given name.
117
152
  # @example
118
153
  # file.command("LC_LOAD_DYLIB")
119
- # file["LC_LOAD_DYLIB"]
154
+ # file[:LC_LOAD_DYLIB]
155
+ # @param [String, Symbol] name the load command ID
120
156
  # @return [Array<MachO::LoadCommand>] an array of LoadCommands corresponding to `name`
121
157
  def command(name)
122
- load_commands.select { |lc| lc.to_s == name }
158
+ load_commands.select { |lc| lc.type == name.to_sym }
123
159
  end
124
160
 
125
161
  alias :[] :command
@@ -129,9 +165,9 @@ module MachO
129
165
  # @return [Array<MachO::SegmentCommand64>] if the Mach-O is 64-bit
130
166
  def segments
131
167
  if magic32?
132
- command("LC_SEGMENT")
168
+ command(:LC_SEGMENT)
133
169
  else
134
- command("LC_SEGMENT_64")
170
+ command(:LC_SEGMENT_64)
135
171
  end
136
172
  end
137
173
 
@@ -144,7 +180,7 @@ module MachO
144
180
  return nil
145
181
  end
146
182
 
147
- dylib_id_cmd = command("LC_ID_DYLIB").first
183
+ dylib_id_cmd = command(:LC_ID_DYLIB).first
148
184
 
149
185
  dylib_id_cmd.name.to_s
150
186
  end
@@ -164,7 +200,7 @@ module MachO
164
200
  return nil
165
201
  end
166
202
 
167
- dylib_cmd = command("LC_ID_DYLIB").first
203
+ dylib_cmd = command(:LC_ID_DYLIB).first
168
204
  old_id = dylib_id
169
205
 
170
206
  set_name_in_dylib(dylib_cmd, old_id, new_id)
@@ -173,7 +209,7 @@ module MachO
173
209
  # All shared libraries linked to the Mach-O.
174
210
  # @return [Array<String>] an array of all shared libraries
175
211
  def linked_dylibs
176
- command("LC_LOAD_DYLIB").map(&:name).map(&:to_s)
212
+ command(:LC_LOAD_DYLIB).map(&:name).map(&:to_s)
177
213
  end
178
214
 
179
215
  # Changes the shared library `old_name` to `new_name`
@@ -184,7 +220,7 @@ module MachO
184
220
  # @return [void]
185
221
  # @raise [MachO::DylibUnknownError] if no shared library has the old name
186
222
  def change_install_name(old_name, new_name)
187
- dylib_cmd = command("LC_LOAD_DYLIB").find { |d| d.name.to_s == old_name }
223
+ dylib_cmd = command(:LC_LOAD_DYLIB).find { |d| d.name.to_s == old_name }
188
224
  raise DylibUnknownError.new(old_name) if dylib_cmd.nil?
189
225
 
190
226
  set_name_in_dylib(dylib_cmd, old_name, new_name)
@@ -256,7 +292,7 @@ module MachO
256
292
  ncmds = get_ncmds
257
293
  sizeofcmds = get_sizeofcmds
258
294
  flags = get_flags
259
-
295
+
260
296
  if MachO.magic32?(magic)
261
297
  MachHeader.new(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
262
298
  else
@@ -347,12 +383,13 @@ module MachO
347
383
 
348
384
  header.ncmds.times do
349
385
  cmd = @raw_data.slice(offset, 4).unpack("V").first
386
+ cmd_sym = LOAD_COMMANDS[cmd]
350
387
 
351
- raise LoadCommandError.new(cmd) unless LC_STRUCTURES.key?(cmd)
388
+ raise LoadCommandError.new(cmd) if cmd_sym.nil?
352
389
 
353
390
  # why do I do this? i don't like declaring constants below
354
391
  # classes, and i need them to resolve...
355
- klass = MachO.const_get "#{LC_STRUCTURES[cmd]}"
392
+ klass = MachO.const_get "#{LC_STRUCTURES[cmd_sym]}"
356
393
  command = klass.new_from_bin(@raw_data, offset, @raw_data.slice(offset, klass.bytesize))
357
394
 
358
395
  load_commands << command
data/lib/macho/open.rb ADDED
@@ -0,0 +1,16 @@
1
+ module MachO
2
+ # Opens the given filename as a MachOFile or FatFile, depending on its magic.
3
+ # @param filename [String] the file being opened
4
+ # @return [MachO::MachOFile] if the file is a Mach-O
5
+ # @return [MachO::FatFile] if the file is a Fat file
6
+ def self.open(filename)
7
+ # open file and test magic instead of using exceptions for control?
8
+ begin
9
+ file = MachOFile.new(filename)
10
+ rescue FatBinaryError
11
+ file = FatFile.new(filename)
12
+ end
13
+
14
+ file
15
+ end
16
+ end
@@ -1,44 +1,110 @@
1
1
  module MachO
2
- # the flags field of a section has two parts: a type and attributes
3
- SECTION_TYPE = 0x000000ff # type mask
4
- SECTION_ATTRIBUTES = 0xffffff00 # attributes mask
5
- SECTION_ATTRIBUTES_USR = 0xff000000 # user settable attributes mask
6
- SECTION_ATTRIBUTES_SYS = 0x00ffff00 # system settable attributes mask
2
+ # type mask
3
+ SECTION_TYPE = 0x000000ff
7
4
 
8
- # section types for the flags field
5
+ # attributes mask
6
+ SECTION_ATTRIBUTES = 0xffffff00
7
+
8
+ # user settable attributes mask
9
+ SECTION_ATTRIBUTES_USR = 0xff000000
10
+
11
+ # system settable attributes mask
12
+ SECTION_ATTRIBUTES_SYS = 0x00ffff00
13
+
14
+ # a regular section
9
15
  S_REGULAR = 0x0
16
+
17
+ # a zero fill on demand section
10
18
  S_ZEROFILL = 0x1
19
+
20
+ # a section with only literal C strings
11
21
  S_CSTRING_LITERALS = 0x2
22
+
23
+ # a section with only 4 byte literals
12
24
  S_4BYTE_LITERALS = 0x3
25
+
26
+ # a section with only 8 byte literals
13
27
  S_8BYTE_LITERALS = 0x4
28
+
29
+ # a section with only pointers to literals
14
30
  S_LITERAL_POINTERS = 0x5
31
+
32
+ # a section with only non-lazy symbol pointers
15
33
  S_NON_LAZY_SYMBOL_POINTERS = 0x6
34
+
35
+ # a section with only lazy symbol pointers
16
36
  S_LAZY_SYMBOL_POINTERS = 0x7
37
+
38
+ # a section with only symbol stubs (byte size of stub in reserved2 field)
17
39
  S_SYMBOL_STUBS = 0x8
40
+
41
+ # a section with only function pointers for initialization
18
42
  S_MOD_INIT_FUNC_POINTERS = 0x9
43
+
44
+ # a section with only function pointers for termination
19
45
  S_MOD_TERM_FUNC_POINTERS = 0xa
46
+
47
+ # a section with only symbols that are to be coalesced
20
48
  S_COALESCED = 0xb
49
+
50
+ # a zero fill on demand section that can be larger than 4GB
21
51
  S_GB_ZEROFILE = 0xc
52
+
53
+ # a section with only pairs of function pointers for interposing
22
54
  S_INTERPOSING = 0xd
55
+
56
+ # a section with only 16 byte literals
23
57
  S_16BYTE_LITERALS = 0xe
58
+
59
+ # a section containing DTrace Object Format
24
60
  S_DTRACE_DOF = 0xf
61
+
62
+ # a section with only lazy symbol pointers to lazy loaded dylibs
25
63
  S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10
64
+
65
+ # a template of initial values for thread local variables
26
66
  S_THREAD_LOCAL_REGULAR = 0x11
67
+
68
+ # a template of initial values for thread local variables
27
69
  S_THREAD_LOCAL_ZEROFILL = 0x12
70
+
71
+ # thread local variable descriptors
28
72
  S_THREAD_LOCAL_VARIABLES = 0x13
73
+
74
+ # pointers to thread local variable descriptors
29
75
  S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14
76
+
77
+ # functions to call to initialize thread local variable values
30
78
  S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15
31
79
 
32
- # section attributes for the flags field
80
+ # a section with only true machine instructions
33
81
  S_ATTR_PURE_INSTRUCTIONS = 0x80000000
82
+
83
+ # a section with coalesced symbols that are not to be in a ranlib table of contents
34
84
  S_ATTR_NO_TOC = 0x40000000
85
+
86
+ # static symbols in this section can be stripped in files with the MH_DYLDLINK flag
35
87
  S_ATTR_STRIP_STATIC_SYMS = 0x20000000
88
+
89
+ # no dead stripping
36
90
  S_ATTR_NO_DEAD_STRIP = 0x10000000
91
+
92
+ # blocks are live if they reference live blocks
37
93
  S_ATTR_LIVE_SUPPORT = 0x08000000
94
+
95
+ # used with i386 code stubs written on by dyld
38
96
  S_ATTR_SELF_MODIFYING_CODE = 0x04000000
97
+
98
+ # a debug section
39
99
  S_ATTR_DEBUG = 0x02000000
100
+
101
+ # a section containing some machine instructions
40
102
  S_ATTR_SOME_INSTRUCTIONS = 0x00000400
103
+
104
+ # a section containing external relocation entries
41
105
  S_ATTR_EXT_RELOC = 0x00000200
106
+
107
+ # a section containing local relocation entries
42
108
  S_ATTR_LOC_RELOC = 0x00000100
43
109
 
44
110
  # currently known section names
data/lib/macho/tools.rb CHANGED
@@ -13,6 +13,7 @@ module MachO
13
13
  # @param filename [String] the Mach-O or Fat binary being modified
14
14
  # @param new_id [String] the new dylib ID for the binary
15
15
  # @return [void]
16
+ # @todo unstub for fat files
16
17
  def self.change_dylib_id(filename, new_id)
17
18
  file = MachO.open(filename)
18
19
 
@@ -29,6 +30,7 @@ module MachO
29
30
  # @param old_name [String] the old shared library name
30
31
  # @param new_name [String] the new shared library name
31
32
  # @return [void]
33
+ # @todo unstub for fat files
32
34
  def self.change_install_name(filename, old_name, new_name)
33
35
  file = MachO.open(filename)
34
36
 
@@ -38,5 +40,33 @@ module MachO
38
40
  raise MachOError.new("changing install names for fat binaries is incomplete")
39
41
  end
40
42
  end
43
+
44
+ # Changes a runtime path in a Mach-O or Fat binary, overwriting the source file.
45
+ # @param filename [String] the Mach-O or Fat binary being modified
46
+ # @param old_path [String] the old runtime path
47
+ # @param new_path [String] the new runtime path
48
+ # @return [void]
49
+ # @todo unstub
50
+ def self.change_rpath(filename, old_path, new_path)
51
+ raise "stub"
52
+ end
53
+
54
+ # Add a runtime path to a Mach-O or Fat binary, overwriting the source file.
55
+ # @param filename [String] the Mach-O or Fat binary being modified
56
+ # @param new_path [String] the new runtime path
57
+ # @return [void]
58
+ # @todo unstub
59
+ def self.add_rpath(filename, new_path)
60
+ raise "stub"
61
+ end
62
+
63
+ # Delete a runtime path from a Mach-O or Fat binary, overwriting the source file.
64
+ # @param filename [String] the Mach-O or Fat binary being modified
65
+ # @param old_path [String] the old runtime path
66
+ # @return [void]
67
+ # @todo unstub
68
+ def self.delete_rpath(filename, old_path)
69
+ raise "stub"
70
+ end
41
71
  end
42
72
  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.6
4
+ version: 0.1.8
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-28 00:00:00.000000000 Z
11
+ date: 2015-11-04 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
@@ -25,6 +25,7 @@ files:
25
25
  - lib/macho/headers.rb
26
26
  - lib/macho/load_commands.rb
27
27
  - lib/macho/macho_file.rb
28
+ - lib/macho/open.rb
28
29
  - lib/macho/sections.rb
29
30
  - lib/macho/structure.rb
30
31
  - lib/macho/tools.rb