ruby-macho 0.2.2 → 0.2.3
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/LICENSE +2 -2
- data/README.md +4 -9
- data/lib/macho.rb +2 -2
- data/lib/macho/exceptions.rb +104 -73
- data/lib/macho/fat_file.rb +273 -228
- data/lib/macho/headers.rb +342 -265
- data/lib/macho/load_commands.rb +1009 -999
- data/lib/macho/macho_file.rb +509 -529
- data/lib/macho/open.rb +23 -14
- data/lib/macho/sections.rb +157 -157
- data/lib/macho/structure.rb +33 -17
- data/lib/macho/tools.rb +55 -55
- data/lib/macho/utils.rb +42 -30
- metadata +3 -4
data/lib/macho/load_commands.rb
CHANGED
@@ -1,1001 +1,1011 @@
|
|
1
1
|
module MachO
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
2
|
+
# load commands added after OS X 10.1 need to be bitwise ORed with
|
3
|
+
# LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
|
4
|
+
LC_REQ_DYLD = 0x80000000
|
5
|
+
|
6
|
+
# association of load commands to symbol representations
|
7
|
+
# @api private
|
8
|
+
LOAD_COMMANDS = {
|
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,
|
56
|
+
0x2f => :LC_VERSION_MIN_TVOS,
|
57
|
+
0x30 => :LC_VERSION_MIN_WATCHOS,
|
58
|
+
}.freeze
|
59
|
+
|
60
|
+
# load commands responsible for loading dylibs
|
61
|
+
# @api private
|
62
|
+
DYLIB_LOAD_COMMANDS = [
|
63
|
+
:LC_LOAD_DYLIB,
|
64
|
+
:LC_LOAD_WEAK_DYLIB,
|
65
|
+
:LC_REEXPORT_DYLIB,
|
66
|
+
:LC_LAZY_LOAD_DYLIB,
|
67
|
+
:LC_LOAD_UPWARD_DYLIB,
|
68
|
+
].freeze
|
69
|
+
|
70
|
+
# association of load command symbols to string representations of classes
|
71
|
+
# @api private
|
72
|
+
LC_STRUCTURES = {
|
73
|
+
:LC_SEGMENT => "SegmentCommand",
|
74
|
+
:LC_SYMTAB => "SymtabCommand",
|
75
|
+
:LC_SYMSEG => "LoadCommand", # obsolete
|
76
|
+
:LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such
|
77
|
+
:LC_UNIXTHREAD => "ThreadCommand",
|
78
|
+
:LC_LOADFVMLIB => "LoadCommand", # obsolete
|
79
|
+
:LC_IDFVMLIB => "LoadCommand", # obsolete
|
80
|
+
:LC_IDENT => "LoadCommand", # obsolete
|
81
|
+
:LC_FVMFILE => "LoadCommand", # reserved for internal use only
|
82
|
+
:LC_PREPAGE => "LoadCommand", # reserved for internal use only
|
83
|
+
:LC_DYSYMTAB => "DysymtabCommand",
|
84
|
+
:LC_LOAD_DYLIB => "DylibCommand",
|
85
|
+
:LC_ID_DYLIB => "DylibCommand",
|
86
|
+
:LC_LOAD_DYLINKER => "DylinkerCommand",
|
87
|
+
:LC_ID_DYLINKER => "DylinkerCommand",
|
88
|
+
:LC_PREBOUND_DYLIB => "PreboundDylibCommand",
|
89
|
+
:LC_ROUTINES => "RoutinesCommand",
|
90
|
+
:LC_SUB_FRAMEWORK => "SubFrameworkCommand",
|
91
|
+
:LC_SUB_UMBRELLA => "SubUmbrellaCommand",
|
92
|
+
:LC_SUB_CLIENT => "SubClientCommand",
|
93
|
+
:LC_SUB_LIBRARY => "SubLibraryCommand",
|
94
|
+
:LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
|
95
|
+
:LC_PREBIND_CKSUM => "PrebindCksumCommand",
|
96
|
+
:LC_LOAD_WEAK_DYLIB => "DylibCommand",
|
97
|
+
:LC_SEGMENT_64 => "SegmentCommand64",
|
98
|
+
:LC_ROUTINES_64 => "RoutinesCommand64",
|
99
|
+
:LC_UUID => "UUIDCommand",
|
100
|
+
:LC_RPATH => "RpathCommand",
|
101
|
+
:LC_CODE_SIGNATURE => "LinkeditDataCommand",
|
102
|
+
:LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
|
103
|
+
:LC_REEXPORT_DYLIB => "DylibCommand",
|
104
|
+
:LC_LAZY_LOAD_DYLIB => "DylibCommand",
|
105
|
+
:LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
|
106
|
+
:LC_DYLD_INFO => "DyldInfoCommand",
|
107
|
+
:LC_DYLD_INFO_ONLY => "DyldInfoCommand",
|
108
|
+
:LC_LOAD_UPWARD_DYLIB => "DylibCommand",
|
109
|
+
:LC_VERSION_MIN_MACOSX => "VersionMinCommand",
|
110
|
+
:LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
|
111
|
+
:LC_FUNCTION_STARTS => "LinkeditDataCommand",
|
112
|
+
:LC_DYLD_ENVIRONMENT => "DylinkerCommand",
|
113
|
+
:LC_MAIN => "EntryPointCommand",
|
114
|
+
:LC_DATA_IN_CODE => "LinkeditDataCommand",
|
115
|
+
:LC_SOURCE_VERSION => "SourceVersionCommand",
|
116
|
+
:LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
|
117
|
+
:LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
|
118
|
+
:LC_LINKER_OPTION => "LinkerOptionCommand",
|
119
|
+
:LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand",
|
120
|
+
:LC_VERSION_MIN_TVOS => "VersionMinCommand",
|
121
|
+
:LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
|
122
|
+
}.freeze
|
123
|
+
|
124
|
+
# association of segment name symbols to names
|
125
|
+
# @api private
|
126
|
+
SEGMENT_NAMES = {
|
127
|
+
:SEG_PAGEZERO => "__PAGEZERO",
|
128
|
+
:SEG_TEXT => "__TEXT",
|
129
|
+
:SEG_DATA => "__DATA",
|
130
|
+
:SEG_OBJC => "__OBJC",
|
131
|
+
:SEG_ICON => "__ICON",
|
132
|
+
:SEG_LINKEDIT => "__LINKEDIT",
|
133
|
+
:SEG_UNIXSTACK => "__UNIXSTACK",
|
134
|
+
:SEG_IMPORT => "__IMPORT",
|
135
|
+
}.freeze
|
136
|
+
|
137
|
+
# association of segment flag symbols to values
|
138
|
+
# @api private
|
139
|
+
SEGMENT_FLAGS = {
|
140
|
+
:SG_HIGHVM => 0x1,
|
141
|
+
:SG_FVMLIB => 0x2,
|
142
|
+
:SG_NORELOC => 0x4,
|
143
|
+
:SG_PROTECTED_VERSION_1 => 0x8,
|
144
|
+
}.freeze
|
145
|
+
|
146
|
+
# Mach-O load command structure
|
147
|
+
# This is the most generic load command - only cmd ID and size are
|
148
|
+
# represented, and no actual data. Used when a more specific class
|
149
|
+
# isn't available/implemented.
|
150
|
+
class LoadCommand < MachOStructure
|
151
|
+
# @return [Fixnum] the offset in the file the command was created from
|
152
|
+
attr_reader :offset
|
153
|
+
|
154
|
+
# @return [Fixnum] the load command's identifying number
|
155
|
+
attr_reader :cmd
|
156
|
+
|
157
|
+
# @return [Fixnum] the size of the load command, in bytes
|
158
|
+
attr_reader :cmdsize
|
159
|
+
|
160
|
+
FORMAT = "L=2"
|
161
|
+
SIZEOF = 8
|
162
|
+
|
163
|
+
# Creates a new LoadCommand given an offset and binary string
|
164
|
+
# @param raw_data [String] the raw Mach-O data
|
165
|
+
# @param endianness [Symbol] the endianness of the command (:big or :little)
|
166
|
+
# @param offset [Fixnum] the offset to initialize with
|
167
|
+
# @param bin [String] the binary string to initialize with
|
168
|
+
# @return [MachO::LoadCommand] the new load command
|
169
|
+
# @api private
|
170
|
+
def self.new_from_bin(raw_data, endianness, offset, bin)
|
171
|
+
format = specialize_format(self::FORMAT, endianness)
|
172
|
+
|
173
|
+
self.new(raw_data, offset, *bin.unpack(format))
|
174
|
+
end
|
175
|
+
|
176
|
+
# @param raw_data [String] the raw Mach-O data
|
177
|
+
# @param offset [Fixnum] the offset to initialize with
|
178
|
+
# @param cmd [Fixnum] the load command's identifying number
|
179
|
+
# @param cmdsize [Fixnum] the size of the load command in bytes
|
180
|
+
# @api private
|
181
|
+
def initialize(raw_data, offset, cmd, cmdsize)
|
182
|
+
@raw_data = raw_data
|
183
|
+
@offset = offset
|
184
|
+
@cmd = cmd
|
185
|
+
@cmdsize = cmdsize
|
186
|
+
end
|
187
|
+
|
188
|
+
# @return [Symbol] a symbol representation of the load command's identifying number
|
189
|
+
def type
|
190
|
+
LOAD_COMMANDS[cmd]
|
191
|
+
end
|
192
|
+
|
193
|
+
alias :to_sym :type
|
194
|
+
|
195
|
+
# @return [String] a string representation of the load command's identifying number
|
196
|
+
def to_s
|
197
|
+
type.to_s
|
198
|
+
end
|
199
|
+
|
200
|
+
# Represents a Load Command string. A rough analogue to the lc_str
|
201
|
+
# struct used internally by OS X. This class allows ruby-macho to
|
202
|
+
# pretend that strings stored in LCs are immediately available without
|
203
|
+
# explicit operations on the raw Mach-O data.
|
204
|
+
class LCStr
|
205
|
+
# @param raw_data [String] the raw Mach-O data.
|
206
|
+
# @param lc [MachO::LoadCommand] the load command
|
207
|
+
# @param lc_str [Fixnum] the offset to the beginning of the string
|
208
|
+
# @api private
|
209
|
+
def initialize(raw_data, lc, lc_str)
|
210
|
+
@raw_data = raw_data
|
211
|
+
@lc = lc
|
212
|
+
@lc_str = lc_str
|
213
|
+
@str = @raw_data.slice(@lc.offset + @lc_str...@lc.offset + @lc.cmdsize).delete("\x00")
|
214
|
+
end
|
215
|
+
|
216
|
+
# @return [String] a string representation of the LCStr
|
217
|
+
def to_s
|
218
|
+
@str
|
219
|
+
end
|
220
|
+
|
221
|
+
# @return [Fixnum] the offset to the beginning of the string in the load command
|
222
|
+
def to_i
|
223
|
+
@lc_str
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# A load command containing a single 128-bit unique random number identifying
|
229
|
+
# an object produced by static link editor. Corresponds to LC_UUID.
|
230
|
+
class UUIDCommand < LoadCommand
|
231
|
+
# @return [Array<Fixnum>] the UUID
|
232
|
+
attr_reader :uuid
|
233
|
+
|
234
|
+
FORMAT = "L=2a16"
|
235
|
+
SIZEOF = 24
|
236
|
+
|
237
|
+
# @api private
|
238
|
+
def initialize(raw_data, offset, cmd, cmdsize, uuid)
|
239
|
+
super(raw_data, offset, cmd, cmdsize)
|
240
|
+
@uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
|
241
|
+
end
|
242
|
+
|
243
|
+
# @return [String] a string representation of the UUID
|
244
|
+
def uuid_string
|
245
|
+
hexes = uuid.map { |e| "%02x" % e }
|
246
|
+
segs = [
|
247
|
+
hexes[0..3].join, hexes[4..5].join, hexes[6..7].join,
|
248
|
+
hexes[8..9].join, hexes[10..15].join
|
249
|
+
]
|
250
|
+
|
251
|
+
segs.join("-")
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# A load command indicating that part of this file is to be mapped into
|
256
|
+
# the task's address space. Corresponds to LC_SEGMENT.
|
257
|
+
class SegmentCommand < LoadCommand
|
258
|
+
# @return [String] the name of the segment
|
259
|
+
attr_reader :segname
|
260
|
+
|
261
|
+
# @return [Fixnum] the memory address of the segment
|
262
|
+
attr_reader :vmaddr
|
263
|
+
|
264
|
+
# @return [Fixnum] the memory size of the segment
|
265
|
+
attr_reader :vmsize
|
266
|
+
|
267
|
+
# @return [Fixnum] the file offset of the segment
|
268
|
+
attr_reader :fileoff
|
269
|
+
|
270
|
+
# @return [Fixnum] the amount to map from the file
|
271
|
+
attr_reader :filesize
|
272
|
+
|
273
|
+
# @return [Fixnum] the maximum VM protection
|
274
|
+
attr_reader :maxprot
|
275
|
+
|
276
|
+
# @return [Fixnum] the initial VM protection
|
277
|
+
attr_reader :initprot
|
278
|
+
|
279
|
+
# @return [Fixnum] the number of sections in the segment
|
280
|
+
attr_reader :nsects
|
281
|
+
|
282
|
+
# @return [Fixnum] any flags associated with the segment
|
283
|
+
attr_reader :flags
|
284
|
+
|
285
|
+
FORMAT = "L=2a16L=4l=2L=2"
|
286
|
+
SIZEOF = 56
|
287
|
+
|
288
|
+
# @api private
|
289
|
+
def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
290
|
+
filesize, maxprot, initprot, nsects, flags)
|
291
|
+
super(raw_data, offset, cmd, cmdsize)
|
292
|
+
@segname = segname.delete("\x00")
|
293
|
+
@vmaddr = vmaddr
|
294
|
+
@vmsize = vmsize
|
295
|
+
@fileoff = fileoff
|
296
|
+
@filesize = filesize
|
297
|
+
@maxprot = maxprot
|
298
|
+
@initprot = initprot
|
299
|
+
@nsects = nsects
|
300
|
+
@flags = flags
|
301
|
+
end
|
302
|
+
|
303
|
+
# @example
|
304
|
+
# puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
|
305
|
+
# @param flag [Symbol] a segment flag symbol
|
306
|
+
# @return [Boolean] true if `flag` is present in the segment's flag field
|
307
|
+
def flag?(flag)
|
308
|
+
flag = SEGMENT_FLAGS[flag]
|
309
|
+
return false if flag.nil?
|
310
|
+
flags & flag == flag
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
# A load command indicating that part of this file is to be mapped into
|
315
|
+
# the task's address space. Corresponds to LC_SEGMENT_64.
|
316
|
+
class SegmentCommand64 < LoadCommand
|
317
|
+
# @return [String] the name of the segment
|
318
|
+
attr_reader :segname
|
319
|
+
|
320
|
+
# @return [Fixnum] the memory address of the segment
|
321
|
+
attr_reader :vmaddr
|
322
|
+
|
323
|
+
# @return [Fixnum] the memory size of the segment
|
324
|
+
attr_reader :vmsize
|
325
|
+
|
326
|
+
# @return [Fixnum] the file offset of the segment
|
327
|
+
attr_reader :fileoff
|
328
|
+
|
329
|
+
# @return [Fixnum] the amount to map from the file
|
330
|
+
attr_reader :filesize
|
331
|
+
|
332
|
+
# @return [Fixnum] the maximum VM protection
|
333
|
+
attr_reader :maxprot
|
334
|
+
|
335
|
+
# @return [Fixnum] the initial VM protection
|
336
|
+
attr_reader :initprot
|
337
|
+
|
338
|
+
# @return [Fixnum] the number of sections in the segment
|
339
|
+
attr_reader :nsects
|
340
|
+
|
341
|
+
# @return [Fixnum] any flags associated with the segment
|
342
|
+
attr_reader :flags
|
343
|
+
|
344
|
+
FORMAT = "L=2a16Q=4l=2L=2"
|
345
|
+
SIZEOF = 72
|
346
|
+
|
347
|
+
# @api private
|
348
|
+
def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
349
|
+
filesize, maxprot, initprot, nsects, flags)
|
350
|
+
super(raw_data, offset, cmd, cmdsize)
|
351
|
+
@segname = segname.delete("\x00")
|
352
|
+
@vmaddr = vmaddr
|
353
|
+
@vmsize = vmsize
|
354
|
+
@fileoff = fileoff
|
355
|
+
@filesize = filesize
|
356
|
+
@maxprot = maxprot
|
357
|
+
@initprot = initprot
|
358
|
+
@nsects = nsects
|
359
|
+
@flags = flags
|
360
|
+
end
|
361
|
+
|
362
|
+
# @example
|
363
|
+
# puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
|
364
|
+
# @param flag [Symbol] a segment flag symbol
|
365
|
+
# @return [Boolean] true if `flag` is present in the segment's flag field
|
366
|
+
def flag?(flag)
|
367
|
+
flag = SEGMENT_FLAGS[flag]
|
368
|
+
return false if flag.nil?
|
369
|
+
flags & flag == flag
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# A load command representing some aspect of shared libraries, depending
|
374
|
+
# on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
|
375
|
+
# and LC_REEXPORT_DYLIB.
|
376
|
+
class DylibCommand < LoadCommand
|
377
|
+
# @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
|
378
|
+
attr_reader :name
|
379
|
+
|
380
|
+
# @return [Fixnum] the library's build time stamp
|
381
|
+
attr_reader :timestamp
|
382
|
+
|
383
|
+
# @return [Fixnum] the library's current version number
|
384
|
+
attr_reader :current_version
|
385
|
+
|
386
|
+
# @return [Fixnum] the library's compatibility version number
|
387
|
+
attr_reader :compatibility_version
|
388
|
+
|
389
|
+
FORMAT = "L=6"
|
390
|
+
SIZEOF = 24
|
391
|
+
|
392
|
+
# @api private
|
393
|
+
def initialize(raw_data, offset, cmd, cmdsize, name, timestamp, current_version,
|
394
|
+
compatibility_version)
|
395
|
+
super(raw_data, offset, cmd, cmdsize)
|
396
|
+
@name = LCStr.new(raw_data, self, name)
|
397
|
+
@timestamp = timestamp
|
398
|
+
@current_version = current_version
|
399
|
+
@compatibility_version = compatibility_version
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
# A load command representing some aspect of the dynamic linker, depending
|
404
|
+
# on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
|
405
|
+
# LC_DYLD_ENVIRONMENT.
|
406
|
+
class DylinkerCommand < LoadCommand
|
407
|
+
# @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
|
408
|
+
attr_reader :name
|
409
|
+
|
410
|
+
FORMAT = "L=3"
|
411
|
+
SIZEOF = 12
|
412
|
+
|
413
|
+
# @api private
|
414
|
+
def initialize(raw_data, offset, cmd, cmdsize, name)
|
415
|
+
super(raw_data, offset, cmd, cmdsize)
|
416
|
+
@name = LCStr.new(raw_data, self, name)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
# A load command used to indicate dynamic libraries used in prebinding.
|
421
|
+
# Corresponds to LC_PREBOUND_DYLIB.
|
422
|
+
class PreboundDylibCommand < LoadCommand
|
423
|
+
# @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
|
424
|
+
attr_reader :name
|
425
|
+
|
426
|
+
# @return [Fixnum] the number of modules in the library
|
427
|
+
attr_reader :nmodules
|
428
|
+
|
429
|
+
# @return [Fixnum] a bit vector of linked modules
|
430
|
+
attr_reader :linked_modules
|
431
|
+
|
432
|
+
FORMAT = "L=5"
|
433
|
+
SIZEOF = 20
|
434
|
+
|
435
|
+
# @api private
|
436
|
+
def initialize(raw_data, offset, cmd, cmdsize, name, nmodules, linked_modules)
|
437
|
+
super(raw_data, offset, cmd, cmdsize)
|
438
|
+
@name = LCStr.new(raw_data, self, name)
|
439
|
+
@nmodules = nmodules
|
440
|
+
@linked_modules = linked_modules
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
# A load command used to represent threads.
|
445
|
+
# @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize)
|
446
|
+
class ThreadCommand < LoadCommand
|
447
|
+
FORMAT = "L=2"
|
448
|
+
SIZEOF = 8
|
449
|
+
end
|
450
|
+
|
451
|
+
# A load command containing the address of the dynamic shared library
|
452
|
+
# initialization routine and an index into the module table for the module
|
453
|
+
# that defines the routine. Corresponds to LC_ROUTINES.
|
454
|
+
class RoutinesCommand < LoadCommand
|
455
|
+
# @return [Fixnum] the address of the initialization routine
|
456
|
+
attr_reader :init_address
|
457
|
+
|
458
|
+
# @return [Fixnum] the index into the module table that the init routine is defined in
|
459
|
+
attr_reader :init_module
|
460
|
+
|
461
|
+
# @return [void]
|
462
|
+
attr_reader :reserved1
|
463
|
+
|
464
|
+
# @return [void]
|
465
|
+
attr_reader :reserved2
|
466
|
+
|
467
|
+
# @return [void]
|
468
|
+
attr_reader :reserved3
|
469
|
+
|
470
|
+
# @return [void]
|
471
|
+
attr_reader :reserved4
|
472
|
+
|
473
|
+
# @return [void]
|
474
|
+
attr_reader :reserved5
|
475
|
+
|
476
|
+
# @return [void]
|
477
|
+
attr_reader :reserved6
|
478
|
+
|
479
|
+
FORMAT = "L=10"
|
480
|
+
SIZEOF = 40
|
481
|
+
|
482
|
+
# @api private
|
483
|
+
def initialize(raw_data, offset, cmd, cmdsize, init_address, init_module,
|
484
|
+
reserved1, reserved2, reserved3, reserved4, reserved5,
|
485
|
+
reserved6)
|
486
|
+
super(raw_data, offset, cmd, cmdsize)
|
487
|
+
@init_address = init_address
|
488
|
+
@init_module = init_module
|
489
|
+
@reserved1 = reserved1
|
490
|
+
@reserved2 = reserved2
|
491
|
+
@reserved3 = reserved3
|
492
|
+
@reserved4 = reserved4
|
493
|
+
@reserved5 = reserved5
|
494
|
+
@reserved6 = reserved6
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
# A load command containing the address of the dynamic shared library
|
499
|
+
# initialization routine and an index into the module table for the module
|
500
|
+
# that defines the routine. Corresponds to LC_ROUTINES_64.
|
501
|
+
class RoutinesCommand64 < LoadCommand
|
502
|
+
# @return [Fixnum] the address of the initialization routine
|
503
|
+
attr_reader :init_address
|
504
|
+
|
505
|
+
# @return [Fixnum] the index into the module table that the init routine is defined in
|
506
|
+
attr_reader :init_module
|
507
|
+
|
508
|
+
# @return [void]
|
509
|
+
attr_reader :reserved1
|
510
|
+
|
511
|
+
# @return [void]
|
512
|
+
attr_reader :reserved2
|
513
|
+
|
514
|
+
# @return [void]
|
515
|
+
attr_reader :reserved3
|
516
|
+
|
517
|
+
# @return [void]
|
518
|
+
attr_reader :reserved4
|
519
|
+
|
520
|
+
# @return [void]
|
521
|
+
attr_reader :reserved5
|
522
|
+
|
523
|
+
# @return [void]
|
524
|
+
attr_reader :reserved6
|
525
|
+
|
526
|
+
FORMAT = "L=2Q=8"
|
527
|
+
SIZEOF = 72
|
528
|
+
|
529
|
+
# @api private
|
530
|
+
def initialize(raw_data, offset, cmd, cmdsize, init_address, init_module,
|
531
|
+
reserved1, reserved2, reserved3, reserved4, reserved5,
|
532
|
+
reserved6)
|
533
|
+
super(raw_data, offset, cmd, cmdsize)
|
534
|
+
@init_address = init_address
|
535
|
+
@init_module = init_module
|
536
|
+
@reserved1 = reserved1
|
537
|
+
@reserved2 = reserved2
|
538
|
+
@reserved3 = reserved3
|
539
|
+
@reserved4 = reserved4
|
540
|
+
@reserved5 = reserved5
|
541
|
+
@reserved6 = reserved6
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
# A load command signifying membership of a subframework containing the name
|
546
|
+
# of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
|
547
|
+
class SubFrameworkCommand < LoadCommand
|
548
|
+
# @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr
|
549
|
+
attr_reader :umbrella
|
550
|
+
|
551
|
+
FORMAT = "L=3"
|
552
|
+
SIZEOF = 12
|
553
|
+
|
554
|
+
# @api private
|
555
|
+
def initialize(raw_data, offset, cmd, cmdsize, umbrella)
|
556
|
+
super(raw_data, offset, cmd, cmdsize)
|
557
|
+
@umbrella = LCStr.new(raw_data, self, umbrella)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
# A load command signifying membership of a subumbrella containing the name
|
562
|
+
# of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
|
563
|
+
class SubUmbrellaCommand < LoadCommand
|
564
|
+
# @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr
|
565
|
+
attr_reader :sub_umbrella
|
566
|
+
|
567
|
+
FORMAT = "L=3"
|
568
|
+
SIZEOF = 12
|
569
|
+
|
570
|
+
# @api private
|
571
|
+
def initialize(raw_data, offset, cmd, cmdsize, sub_umbrella)
|
572
|
+
super(raw_data, offset, cmd, cmdsize)
|
573
|
+
@sub_umbrella = LCStr.new(raw_data, self, sub_umbrella)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
# A load command signifying a sublibrary of a shared library. Corresponds
|
578
|
+
# to LC_SUB_LIBRARY.
|
579
|
+
class SubLibraryCommand < LoadCommand
|
580
|
+
# @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr
|
581
|
+
attr_reader :sub_library
|
582
|
+
|
583
|
+
FORMAT = "L=3"
|
584
|
+
SIZEOF = 12
|
585
|
+
|
586
|
+
# @api private
|
587
|
+
def initialize(raw_data, offset, cmd, cmdsize, sub_library)
|
588
|
+
super(raw_data, offset, cmd, cmdsize)
|
589
|
+
@sub_library = LCStr.new(raw_data, self, sub_library)
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
# A load command signifying a shared library that is a subframework of
|
594
|
+
# an umbrella framework. Corresponds to LC_SUB_CLIENT.
|
595
|
+
class SubClientCommand < LoadCommand
|
596
|
+
# @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr
|
597
|
+
attr_reader :sub_client
|
598
|
+
|
599
|
+
FORMAT = "L=3"
|
600
|
+
SIZEOF = 12
|
601
|
+
|
602
|
+
# @api private
|
603
|
+
def initialize(raw_data, offset, cmd, cmdsize, sub_client)
|
604
|
+
super(raw_data, offset, cmd, cmdsize)
|
605
|
+
@sub_client = LCStr.new(raw_data, self, sub_client)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
# A load command containing the offsets and sizes of the link-edit 4.3BSD
|
610
|
+
# "stab" style symbol table information. Corresponds to LC_SYMTAB.
|
611
|
+
class SymtabCommand < LoadCommand
|
612
|
+
# @return [Fixnum] the symbol table's offset
|
613
|
+
attr_reader :symoff
|
614
|
+
|
615
|
+
# @return [Fixnum] the number of symbol table entries
|
616
|
+
attr_reader :nsyms
|
617
|
+
|
618
|
+
# @return the string table's offset
|
619
|
+
attr_reader :stroff
|
620
|
+
|
621
|
+
# @return the string table size in bytes
|
622
|
+
attr_reader :strsize
|
623
|
+
|
624
|
+
FORMAT = "L=6"
|
625
|
+
SIZEOF = 24
|
626
|
+
|
627
|
+
# @api private
|
628
|
+
def initialize(raw_data, offset, cmd, cmdsize, symoff, nsyms, stroff, strsize)
|
629
|
+
super(raw_data, offset, cmd, cmdsize)
|
630
|
+
@symoff = symoff
|
631
|
+
@nsyms = nsyms
|
632
|
+
@stroff = stroff
|
633
|
+
@strsize = strsize
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
# A load command containing symbolic information needed to support data
|
638
|
+
# structures used by the dynamic link editor. Corresponds to LC_DYSYMTAB.
|
639
|
+
class DysymtabCommand < LoadCommand
|
640
|
+
# @return [Fixnum] the index to local symbols
|
641
|
+
attr_reader :ilocalsym
|
642
|
+
|
643
|
+
# @return [Fixnum] the number of local symbols
|
644
|
+
attr_reader :nlocalsym
|
645
|
+
|
646
|
+
# @return [Fixnum] the index to externally defined symbols
|
647
|
+
attr_reader :iextdefsym
|
648
|
+
|
649
|
+
# @return [Fixnum] the number of externally defined symbols
|
650
|
+
attr_reader :nextdefsym
|
651
|
+
|
652
|
+
# @return [Fixnum] the index to undefined symbols
|
653
|
+
attr_reader :iundefsym
|
654
|
+
|
655
|
+
# @return [Fixnum] the number of undefined symbols
|
656
|
+
attr_reader :nundefsym
|
657
|
+
|
658
|
+
# @return [Fixnum] the file offset to the table of contents
|
659
|
+
attr_reader :tocoff
|
660
|
+
|
661
|
+
# @return [Fixnum] the number of entries in the table of contents
|
662
|
+
attr_reader :ntoc
|
663
|
+
|
664
|
+
# @return [Fixnum] the file offset to the module table
|
665
|
+
attr_reader :modtaboff
|
666
|
+
|
667
|
+
# @return [Fixnum] the number of entries in the module table
|
668
|
+
attr_reader :nmodtab
|
669
|
+
|
670
|
+
# @return [Fixnum] the file offset to the referenced symbol table
|
671
|
+
attr_reader :extrefsymoff
|
672
|
+
|
673
|
+
# @return [Fixnum] the number of entries in the referenced symbol table
|
674
|
+
attr_reader :nextrefsyms
|
675
|
+
|
676
|
+
# @return [Fixnum] the file offset to the indirect symbol table
|
677
|
+
attr_reader :indirectsymoff
|
678
|
+
|
679
|
+
# @return [Fixnum] the number of entries in the indirect symbol table
|
680
|
+
attr_reader :nindirectsyms
|
681
|
+
|
682
|
+
# @return [Fixnum] the file offset to the external relocation entries
|
683
|
+
attr_reader :extreloff
|
684
|
+
|
685
|
+
# @return [Fixnum] the number of external relocation entries
|
686
|
+
attr_reader :nextrel
|
687
|
+
|
688
|
+
# @return [Fixnum] the file offset to the local relocation entries
|
689
|
+
attr_reader :locreloff
|
690
|
+
|
691
|
+
# @return [Fixnum] the number of local relocation entries
|
692
|
+
attr_reader :nlocrel
|
693
|
+
|
694
|
+
|
695
|
+
FORMAT = "L=20"
|
696
|
+
SIZEOF = 80
|
697
|
+
|
698
|
+
# ugh
|
699
|
+
# @api private
|
700
|
+
def initialize(raw_data, offset, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
|
701
|
+
nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
|
702
|
+
nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
|
703
|
+
nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
|
704
|
+
super(raw_data, offset, cmd, cmdsize)
|
705
|
+
@ilocalsym = ilocalsym
|
706
|
+
@nlocalsym = nlocalsym
|
707
|
+
@iextdefsym = iextdefsym
|
708
|
+
@nextdefsym = nextdefsym
|
709
|
+
@iundefsym = iundefsym
|
710
|
+
@nundefsym = nundefsym
|
711
|
+
@tocoff = tocoff
|
712
|
+
@ntoc = ntoc
|
713
|
+
@modtaboff = modtaboff
|
714
|
+
@nmodtab = nmodtab
|
715
|
+
@extrefsymoff = extrefsymoff
|
716
|
+
@nextrefsyms = nextrefsyms
|
717
|
+
@indirectsymoff = indirectsymoff
|
718
|
+
@nindirectsyms = nindirectsyms
|
719
|
+
@extreloff = extreloff
|
720
|
+
@nextrel = nextrel
|
721
|
+
@locreloff = locreloff
|
722
|
+
@nlocrel = nlocrel
|
723
|
+
end
|
724
|
+
end
|
725
|
+
|
726
|
+
# A load command containing the offset and number of hints in the two-level
|
727
|
+
# namespace lookup hints table. Corresponds to LC_TWOLEVEL_HINTS.
|
728
|
+
class TwolevelHintsCommand < LoadCommand
|
729
|
+
# @return [Fixnum] the offset to the hint table
|
730
|
+
attr_reader :htoffset
|
731
|
+
|
732
|
+
# @return [Fixnum] the number of hints in the hint table
|
733
|
+
attr_reader :nhints
|
734
|
+
|
735
|
+
FORMAT = "L=4"
|
736
|
+
SIZEOF = 16
|
737
|
+
|
738
|
+
# @api private
|
739
|
+
def initialize(raw_data, offset, cmd, cmdsize, htoffset, nhints)
|
740
|
+
super(raw_data, offset, cmd, cmdsize)
|
741
|
+
@htoffset = htoffset
|
742
|
+
@nhints = nhints
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
# A load command containing the value of the original checksum for prebound
|
747
|
+
# files, or zero. Corresponds to LC_PREBIND_CKSUM.
|
748
|
+
class PrebindCksumCommand < LoadCommand
|
749
|
+
# @return [Fixnum] the checksum or 0
|
750
|
+
attr_reader :cksum
|
751
|
+
|
752
|
+
FORMAT = "L=3"
|
753
|
+
SIZEOF = 12
|
754
|
+
|
755
|
+
# @api private
|
756
|
+
def initialize(raw_data, offset, cmd, cmdsize, cksum)
|
757
|
+
super(raw_data, offset, cmd, cmdsize)
|
758
|
+
@cksum = cksum
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
# A load command representing an rpath, which specifies a path that should
|
763
|
+
# be added to the current run path used to find @rpath prefixed dylibs.
|
764
|
+
# Corresponds to LC_RPATH.
|
765
|
+
class RpathCommand < LoadCommand
|
766
|
+
# @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr
|
767
|
+
attr_reader :path
|
768
|
+
|
769
|
+
FORMAT = "L=3"
|
770
|
+
SIZEOF = 12
|
771
|
+
|
772
|
+
# @api private
|
773
|
+
def initialize(raw_data, offset, cmd, cmdsize, path)
|
774
|
+
super(raw_data, offset, cmd, cmdsize)
|
775
|
+
@path = LCStr.new(raw_data, self, path)
|
776
|
+
end
|
777
|
+
end
|
778
|
+
|
779
|
+
# A load command representing the offsets and sizes of a blob of data in
|
780
|
+
# the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
|
781
|
+
# LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
|
782
|
+
class LinkeditDataCommand < LoadCommand
|
783
|
+
# @return [Fixnum] offset to the data in the __LINKEDIT segment
|
784
|
+
attr_reader :dataoff
|
785
|
+
|
786
|
+
# @return [Fixnum] size of the data in the __LINKEDIT segment
|
787
|
+
attr_reader :datasize
|
788
|
+
|
789
|
+
FORMAT = "L=4"
|
790
|
+
SIZEOF = 16
|
791
|
+
|
792
|
+
# @api private
|
793
|
+
def initialize(raw_data, offset, cmd, cmdsize, dataoff, datasize)
|
794
|
+
super(raw_data, offset, cmd, cmdsize)
|
795
|
+
@dataoff = dataoff
|
796
|
+
@datasize = datasize
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
# A load command representing the offset to and size of an encrypted
|
801
|
+
# segment. Corresponds to LC_ENCRYPTION_INFO.
|
802
|
+
class EncryptionInfoCommand < LoadCommand
|
803
|
+
# @return [Fixnum] the offset to the encrypted segment
|
804
|
+
attr_reader :cryptoff
|
805
|
+
|
806
|
+
# @return [Fixnum] the size of the encrypted segment
|
807
|
+
attr_reader :cryptsize
|
808
|
+
|
809
|
+
# @return [Fixnum] the encryption system, or 0 if not encrypted yet
|
810
|
+
attr_reader :cryptid
|
811
|
+
|
812
|
+
FORMAT = "L=5"
|
813
|
+
SIZEOF = 20
|
814
|
+
|
815
|
+
# @api private
|
816
|
+
def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid)
|
817
|
+
super(raw_data, offset, cmd, cmdsize)
|
818
|
+
@cryptoff = cryptoff
|
819
|
+
@cryptsize = cryptsize
|
820
|
+
@cryptid = cryptid
|
821
|
+
end
|
822
|
+
end
|
823
|
+
|
824
|
+
# A load command representing the offset to and size of an encrypted
|
825
|
+
# segment. Corresponds to LC_ENCRYPTION_INFO_64.
|
826
|
+
class EncryptionInfoCommand64 < LoadCommand
|
827
|
+
# @return [Fixnum] the offset to the encrypted segment
|
828
|
+
attr_reader :cryptoff
|
829
|
+
|
830
|
+
# @return [Fixnum] the size of the encrypted segment
|
831
|
+
attr_reader :cryptsize
|
832
|
+
|
833
|
+
# @return [Fixnum] the encryption system, or 0 if not encrypted yet
|
834
|
+
attr_reader :cryptid
|
835
|
+
|
836
|
+
# @return [Fixnum] 64-bit padding value
|
837
|
+
attr_reader :pad
|
838
|
+
|
839
|
+
FORMAT = "L=6"
|
840
|
+
SIZEOF = 24
|
841
|
+
|
842
|
+
# @api private
|
843
|
+
def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
|
844
|
+
super(raw_data, offset, cmd, cmdsize)
|
845
|
+
@cryptoff = cryptoff
|
846
|
+
@cryptsize = cryptsize
|
847
|
+
@cryptid = cryptid
|
848
|
+
@pad = pad
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
# A load command containing the minimum OS version on which the binary
|
853
|
+
# was built to run. Corresponds to LC_VERSION_MIN_MACOSX and LC_VERSION_MIN_IPHONEOS.
|
854
|
+
class VersionMinCommand < LoadCommand
|
855
|
+
# @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
|
856
|
+
attr_reader :version
|
857
|
+
|
858
|
+
# @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8
|
859
|
+
attr_reader :sdk
|
860
|
+
|
861
|
+
FORMAT = "L=4"
|
862
|
+
SIZEOF = 16
|
863
|
+
|
864
|
+
# @api private
|
865
|
+
def initialize(raw_data, offset, cmd, cmdsize, version, sdk)
|
866
|
+
super(raw_data, offset, cmd, cmdsize)
|
867
|
+
@version = version
|
868
|
+
@sdk = sdk
|
869
|
+
end
|
870
|
+
|
871
|
+
# A string representation of the binary's minimum OS version.
|
872
|
+
# @return [String] a string representing the minimum OS version.
|
873
|
+
def version_string
|
874
|
+
binary = "%032b" % version
|
875
|
+
segs = [
|
876
|
+
binary[0..15], binary[16..23], binary[24..31]
|
877
|
+
].map { |s| s.to_i(2) }
|
878
|
+
|
879
|
+
segs.join(".")
|
880
|
+
end
|
881
|
+
|
882
|
+
# A string representation of the binary's SDK version.
|
883
|
+
# @return [String] a string representing the SDK version.
|
884
|
+
def sdk_string
|
885
|
+
binary = "%032b" % sdk
|
886
|
+
segs = [
|
887
|
+
binary[0..15], binary[16..23], binary[24..31]
|
888
|
+
].map { |s| s.to_i(2) }
|
889
|
+
|
890
|
+
segs.join(".")
|
891
|
+
end
|
892
|
+
end
|
893
|
+
|
894
|
+
# A load command containing the file offsets and sizes of the new
|
895
|
+
# compressed form of the information dyld needs to load the image.
|
896
|
+
# Corresponds to LC_DYLD_INFO and LC_DYLD_INFO_ONLY.
|
897
|
+
class DyldInfoCommand < LoadCommand
|
898
|
+
# @return [Fixnum] the file offset to the rebase information
|
899
|
+
attr_reader :rebase_off
|
900
|
+
|
901
|
+
# @return [Fixnum] the size of the rebase information
|
902
|
+
attr_reader :rebase_size
|
903
|
+
|
904
|
+
# @return [Fixnum] the file offset to the binding information
|
905
|
+
attr_reader :bind_off
|
906
|
+
|
907
|
+
# @return [Fixnum] the size of the binding information
|
908
|
+
attr_reader :bind_size
|
909
|
+
|
910
|
+
# @return [Fixnum] the file offset to the weak binding information
|
911
|
+
attr_reader :weak_bind_off
|
912
|
+
|
913
|
+
# @return [Fixnum] the size of the weak binding information
|
914
|
+
attr_reader :weak_bind_size
|
915
|
+
|
916
|
+
# @return [Fixnum] the file offset to the lazy binding information
|
917
|
+
attr_reader :lazy_bind_off
|
918
|
+
|
919
|
+
# @return [Fixnum] the size of the lazy binding information
|
920
|
+
attr_reader :lazy_bind_size
|
921
|
+
|
922
|
+
# @return [Fixnum] the file offset to the export information
|
923
|
+
attr_reader :export_off
|
924
|
+
|
925
|
+
# @return [Fixnum] the size of the export information
|
926
|
+
attr_reader :export_size
|
927
|
+
|
928
|
+
FORMAT = "L=12"
|
929
|
+
SIZEOF = 48
|
930
|
+
|
931
|
+
# @api private
|
932
|
+
def initialize(raw_data, offset, cmd, cmdsize, rebase_off, rebase_size, bind_off,
|
933
|
+
bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
|
934
|
+
lazy_bind_size, export_off, export_size)
|
935
|
+
super(raw_data, offset, cmd, cmdsize)
|
936
|
+
@rebase_off = rebase_off
|
937
|
+
@rebase_size = rebase_size
|
938
|
+
@bind_off = bind_off
|
939
|
+
@bind_size = bind_size
|
940
|
+
@weak_bind_off = weak_bind_off
|
941
|
+
@weak_bind_size = weak_bind_size
|
942
|
+
@lazy_bind_off = lazy_bind_off
|
943
|
+
@lazy_bind_size = lazy_bind_size
|
944
|
+
@export_off = export_off
|
945
|
+
@export_size = export_size
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
# A load command containing linker options embedded in object files.
|
950
|
+
# Corresponds to LC_LINKER_OPTION.
|
951
|
+
class LinkerOptionCommand < LoadCommand
|
952
|
+
# @return [Fixnum] the number of strings
|
953
|
+
attr_reader :count
|
954
|
+
|
955
|
+
FORMAT = "L=3"
|
956
|
+
SIZEOF = 12
|
957
|
+
|
958
|
+
# @api private
|
959
|
+
def initialize(raw_data, offset, cmd, cmdsize, count)
|
960
|
+
super(raw_data, offset, cmd, cmdsize)
|
961
|
+
@count = count
|
962
|
+
end
|
963
|
+
end
|
964
|
+
|
965
|
+
# A load command specifying the offset of main(). Corresponds to LC_MAIN.
|
966
|
+
class EntryPointCommand < LoadCommand
|
967
|
+
# @return [Fixnum] the file (__TEXT) offset of main()
|
968
|
+
attr_reader :entryoff
|
969
|
+
|
970
|
+
# @return [Fixnum] if not 0, the initial stack size.
|
971
|
+
attr_reader :stacksize
|
972
|
+
|
973
|
+
FORMAT = "L=2Q=2"
|
974
|
+
SIZEOF = 24
|
975
|
+
|
976
|
+
# @api private
|
977
|
+
def initialize(raw_data, offset, cmd, cmdsize, entryoff, stacksize)
|
978
|
+
super(raw_data, offset, cmd, cmdsize)
|
979
|
+
@entryoff = entryoff
|
980
|
+
@stacksize = stacksize
|
981
|
+
end
|
982
|
+
end
|
983
|
+
|
984
|
+
# A load command specifying the version of the sources used to build the
|
985
|
+
# binary. Corresponds to LC_SOURCE_VERSION.
|
986
|
+
class SourceVersionCommand < LoadCommand
|
987
|
+
# @return [Fixnum] the version packed as a24.b10.c10.d10.e10
|
988
|
+
attr_reader :version
|
989
|
+
|
990
|
+
FORMAT = "L=2Q=1"
|
991
|
+
SIZEOF = 16
|
992
|
+
|
993
|
+
# @api private
|
994
|
+
def initialize(raw_data, offset, cmd, cmdsize, version)
|
995
|
+
super(raw_data, offset, cmd, cmdsize)
|
996
|
+
@version = version
|
997
|
+
end
|
998
|
+
|
999
|
+
# A string representation of the sources used to build the binary.
|
1000
|
+
# @return [String] a string representation of the version
|
1001
|
+
def version_string
|
1002
|
+
binary = "%064b" % version
|
1003
|
+
segs = [
|
1004
|
+
binary[0..23], binary[24..33], binary[34..43], binary[44..53],
|
1005
|
+
binary[54..63]
|
1006
|
+
].map { |s| s.to_i(2) }
|
1007
|
+
|
1008
|
+
segs.join(".")
|
1009
|
+
end
|
1010
|
+
end
|
1001
1011
|
end
|