ruby-macho 0.1.6 → 0.1.8

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