@@ -275,7 +275,8 @@ void CreateHeaderTypes(Ref<BinaryView> view)
275
275
{" SG_HIGHVM" , SG_HIGHVM},
276
276
{" SG_FVMLIB" , SG_FVMLIB},
277
277
{" SG_NORELOC" , SG_NORELOC},
278
- {" SG_PROTECTED_VERSION_1" , SG_PROTECTED_VERSION_1}
278
+ {" SG_PROTECTED_VERSION_1" , SG_PROTECTED_VERSION_1},
279
+ {" SG_READ_ONLY_DATA" , SG_READ_ONLY_DATA},
279
280
// clang-format on
280
281
});
281
282
@@ -313,6 +314,54 @@ void CreateHeaderTypes(Ref<BinaryView> view)
313
314
// clang-format on
314
315
});
315
316
317
+ // TODO: These three enums are technically a single field 32-bit field in the struct. The upper 24 bits are bit
318
+ // flags while the lower 8 bits are mutually exclusive. This prevents Binary Ninja from rendering them in an ORd
319
+ // form. The upper 24 bits are split into two enums because a 24 bit enum field isn't handle correctly either.
320
+ auto sectionTypeEnum = BuildEnum (view, " section_type_t" , 1 ,
321
+ {
322
+ {" S_REGULAR" , S_REGULAR},
323
+ {" S_ZEROFILL" , S_ZEROFILL},
324
+ {" S_CSTRING_LITERALS" , S_CSTRING_LITERALS},
325
+ {" S_4BYTE_LITERALS" , S_4BYTE_LITERALS},
326
+ {" S_8BYTE_LITERALS" , S_8BYTE_LITERALS},
327
+ {" S_LITERAL_POINTERS" , S_LITERAL_POINTERS},
328
+ {" S_NON_LAZY_SYMBOL_POINTERS" , S_NON_LAZY_SYMBOL_POINTERS},
329
+ {" S_LAZY_SYMBOL_POINTERS" , S_LAZY_SYMBOL_POINTERS},
330
+ {" S_SYMBOL_STUBS" , S_SYMBOL_STUBS},
331
+ {" S_MOD_INIT_FUNC_POINTERS" , S_MOD_INIT_FUNC_POINTERS},
332
+ {" S_MOD_TERM_FUNC_POINTERS" , S_MOD_TERM_FUNC_POINTERS},
333
+ {" S_COALESCED" , S_COALESCED},
334
+ {" S_GB_ZEROFILL" , S_GB_ZEROFILL},
335
+ {" S_INTERPOSING" , S_INTERPOSING},
336
+ {" S_16BYTE_LITERALS" , S_16BYTE_LITERALS},
337
+ {" S_DTRACE_DOF" , S_DTRACE_DOF},
338
+ {" S_LAZY_DYLIB_SYMBOL_POINTERS" , S_LAZY_DYLIB_SYMBOL_POINTERS},
339
+ {" S_THREAD_LOCAL_REGULAR" , S_THREAD_LOCAL_REGULAR},
340
+ {" S_THREAD_LOCAL_ZEROFILL" , S_THREAD_LOCAL_ZEROFILL},
341
+ {" S_THREAD_LOCAL_VARIABLES" , S_THREAD_LOCAL_VARIABLES},
342
+ {" S_THREAD_LOCAL_VARIABLE_POINTERS" , S_THREAD_LOCAL_VARIABLE_POINTERS},
343
+ {" S_THREAD_LOCAL_INIT_FUNCTION_POINTERS" , S_THREAD_LOCAL_INIT_FUNCTION_POINTERS},
344
+ {" S_INIT_FUNC_OFFSETS" , S_INIT_FUNC_OFFSETS},
345
+ });
346
+
347
+ auto sectionAttributesSysEnum = BuildEnum (view, " section_attr_sys_t" , 1 ,
348
+ {
349
+ {" S_ATTR_DEBUG" , (S_ATTR_DEBUG >> 24 ) & 0xff },
350
+ {" S_ATTR_SELF_MODIFYING_CODE" , (S_ATTR_SELF_MODIFYING_CODE >> 24 ) & 0xff },
351
+ {" S_ATTR_LIVE_SUPPORT" , (S_ATTR_LIVE_SUPPORT >> 24 ) & 0xff },
352
+ {" S_ATTR_NO_DEAD_STRIP" , (S_ATTR_NO_DEAD_STRIP >> 24 ) & 0xff },
353
+ {" S_ATTR_STRIP_STATIC_SYMS" , (S_ATTR_STRIP_STATIC_SYMS >> 24 ) & 0xff },
354
+ {" S_ATTR_NO_TOC" , (S_ATTR_NO_TOC >> 24 ) & 0xff },
355
+ {" S_ATTR_PURE_INSTRUCTIONS" , (S_ATTR_PURE_INSTRUCTIONS >> 24 ) & 0xff },
356
+ });
357
+
358
+ auto sectionAttributesUserEnum = BuildEnum (view, " section_attr_user_t" , 2 ,
359
+ {
360
+ {" S_ATTR_LOC_RELOC" , (S_ATTR_LOC_RELOC >> 8 ) & 0xffff },
361
+ {" S_ATTR_EXT_RELOC" , (S_ATTR_EXT_RELOC >> 8 ) & 0xffff },
362
+ {" S_ATTR_SOME_INSTRUCTIONS" , (S_ATTR_SOME_INSTRUCTIONS >> 8 ) & 0xffff },
363
+ });
364
+
316
365
auto sectionType = BuildStruct (view, " section" , true ,
317
366
{
318
367
// clang-format off
@@ -324,7 +373,9 @@ void CreateHeaderTypes(Ref<BinaryView> view)
324
373
{" align" , Type::IntegerType (4 , false )},
325
374
{" reloff" , Type::IntegerType (4 , false )},
326
375
{" nreloc" , Type::IntegerType (4 , false )},
327
- {" flags" , Type::IntegerType (4 , false )},
376
+ {" type" , sectionTypeEnum},
377
+ {" attrs_user" , sectionAttributesUserEnum},
378
+ {" attrs_sys" , sectionAttributesSysEnum},
328
379
{" reserved1" , Type::IntegerType (4 , false )},
329
380
{" reserved2" , Type::IntegerType (4 , false )}
330
381
// clang-format on
@@ -341,7 +392,9 @@ void CreateHeaderTypes(Ref<BinaryView> view)
341
392
{" align" , Type::IntegerType (4 , false )},
342
393
{" reloff" , Type::IntegerType (4 , false )},
343
394
{" nreloc" , Type::IntegerType (4 , false )},
344
- {" flags" , Type::IntegerType (4 , false )},
395
+ {" type" , sectionTypeEnum},
396
+ {" attrs_user" , sectionAttributesUserEnum},
397
+ {" attrs_sys" , sectionAttributesSysEnum},
345
398
{" reserved1" , Type::IntegerType (4 , false )},
346
399
{" reserved2" , Type::IntegerType (4 , false )},
347
400
{" reserved3" , Type::IntegerType (4 , false )}
@@ -499,14 +552,22 @@ void CreateHeaderTypes(Ref<BinaryView> view)
499
552
// clang-format on
500
553
});
501
554
555
+ QualifiedName filesetEntryIdName (" fileset_entry_id" );
556
+ std::string filesetEntryIdId = Type::GenerateAutoTypeId (" macho" , filesetEntryIdName);
557
+ auto filesetEntryIdType = Type::NamedType (view,
558
+ view->DefineType (filesetEntryIdId, filesetEntryIdName,
559
+ TypeBuilder::PointerType (4 , Type::IntegerType (1 , true ))
560
+ .SetPointerBase (RelativeToVariableAddressPointerBaseType, -24 )
561
+ .Finalize ()));
562
+
502
563
auto filesetEntryCommandType = BuildStruct (view, " fileset_entry_command" , false ,
503
564
{
504
565
// clang-format off
505
566
{" cmd" , cmdTypeEnum},
506
567
{" cmdsize" , Type::IntegerType (4 , false )},
507
568
{" vmaddr" , Type::IntegerType (8 , false )},
508
569
{" fileoff" , Type::IntegerType (8 , false )},
509
- {" entry_id" , Type::IntegerType ( 4 , false ) },
570
+ {" entry_id" , filesetEntryIdType },
510
571
{" reserved" , Type::IntegerType (4 , false )}
511
572
// clang-format on
512
573
});
@@ -521,6 +582,103 @@ void CreateHeaderTypes(Ref<BinaryView> view)
521
582
// The 'state' field is intentionally ignored.
522
583
// clang-format off
523
584
});
585
+
586
+ auto platformTypeEnum = BuildEnum (view, " macho_platform_t" , 4 ,
587
+ {
588
+ // clang-format off
589
+ {" MACHO_PLATFORM_MACOS" , MACHO_PLATFORM_MACOS},
590
+ {" MACHO_PLATFORM_IOS" , MACHO_PLATFORM_IOS},
591
+ {" MACHO_PLATFORM_TVOS" , MACHO_PLATFORM_TVOS},
592
+ {" MACHO_PLATFORM_WATCHOS" , MACHO_PLATFORM_WATCHOS},
593
+ {" MACHO_PLATFORM_BRIDGEOS" , MACHO_PLATFORM_BRIDGEOS},
594
+ {" MACHO_PLATFORM_MACCATALYST" , MACHO_PLATFORM_MACCATALYST},
595
+ {" MACHO_PLATFORM_IOSSIMULATOR" , MACHO_PLATFORM_IOSSIMULATOR},
596
+ {" MACHO_PLATFORM_TVOSSIMULATOR" , MACHO_PLATFORM_TVOSSIMULATOR},
597
+ {" MACHO_PLATFORM_WATCHOSSIMULATOR" , MACHO_PLATFORM_WATCHOSSIMULATOR},
598
+ {" MACHO_PLATFORM_DRIVERKIT" , MACHO_PLATFORM_DRIVERKIT},
599
+ {" MACHO_PLATFORM_VISIONOS" , MACHO_PLATFORM_VISIONOS},
600
+ {" MACHO_PLATFORM_VISIONOSSIMULATOR" , MACHO_PLATFORM_VISIONOSSIMULATOR},
601
+ {" MACHO_PLATFORM_FIRMWARE" , MACHO_PLATFORM_FIRMWARE},
602
+ {" MACHO_PLATFORM_SEPOS" , MACHO_PLATFORM_SEPOS},
603
+ {" MACHO_PLATFORM_MACOS_EXCLAVECORE" , MACHO_PLATFORM_MACOS_EXCLAVECORE},
604
+ {" MACHO_PLATFORM_MACOS_EXCLAVEKIT" , MACHO_PLATFORM_MACOS_EXCLAVEKIT},
605
+ {" MACHO_PLATFORM_IOS_EXCLAVECORE" , MACHO_PLATFORM_IOS_EXCLAVECORE},
606
+ {" MACHO_PLATFORM_IOS_EXCLAVEKIT" , MACHO_PLATFORM_IOS_EXCLAVEKIT},
607
+ {" MACHO_PLATFORM_TVOS_EXCLAVECORE" , MACHO_PLATFORM_TVOS_EXCLAVECORE},
608
+ {" MACHO_PLATFORM_TVOS_EXCLAVEKIT" , MACHO_PLATFORM_TVOS_EXCLAVEKIT},
609
+ {" MACHO_PLATFORM_WATCHOS_EXCLAVECORE" , MACHO_PLATFORM_WATCHOS_EXCLAVECORE},
610
+ {" MACHO_PLATFORM_WATCHOS_EXCLAVEKIT" , MACHO_PLATFORM_WATCHOS_EXCLAVEKIT},
611
+ {" MACHO_PLATFORM_VISIONOS_EXCLAVECORE" , MACHO_PLATFORM_VISIONOS_EXCLAVECORE},
612
+ {" MACHO_PLATFORM_VISIONOS_EXCLAVEKIT" , MACHO_PLATFORM_VISIONOS_EXCLAVEKIT}
613
+ // clang-format on
614
+ });
615
+
616
+ auto buildToolEnum = BuildEnum (view, " macho_build_tool_t" , 4 ,
617
+ {
618
+ // clang-format off
619
+ {" MACHO_TOOL_CLANG" , MACHO_TOOL_CLANG},
620
+ {" MACHO_TOOL_SWIFT" , MACHO_TOOL_SWIFT},
621
+ {" MACHO_TOOL_LD" , MACHO_TOOL_LD},
622
+ {" MACHO_TOOL_LLD" , MACHO_TOOL_LLD},
623
+ {" MACHO_TOOL_METAL" , MACHO_TOOL_METAL},
624
+ {" MACHO_TOOL_AIRLLD" , MACHO_TOOL_AIRLLD},
625
+ {" MACHO_TOOL_AIRNT" , MACHO_TOOL_AIRNT},
626
+ {" MACHO_TOOL_AIRNT_PLUGIN" , MACHO_TOOL_AIRNT_PLUGIN},
627
+ {" MACHO_TOOL_AIRPACK" , MACHO_TOOL_AIRPACK},
628
+ {" MACHO_TOOL_GPUARCHIVER" , MACHO_TOOL_GPUARCHIVER},
629
+ {" MACHO_TOOL_METAL_FRAMEWORK" , MACHO_TOOL_METAL_FRAMEWORK},
630
+ // clang-format on
631
+ });
632
+
633
+ auto buildToolVersionType = BuildStruct (view, " build_tool_version" , false ,
634
+ {
635
+ // clang-format off
636
+ {" tool" , buildToolEnum},
637
+ {" version" , Type::IntegerType (4 , false )}
638
+ // clang-format on
639
+ });
640
+
641
+ auto buildVersionCommandType = BuildStruct (view, " build_version_command" , false ,
642
+ {
643
+ // clang-format off
644
+ {" cmd" , cmdTypeEnum},
645
+ {" cmdsize" , Type::IntegerType (4 , false )},
646
+ {" platform" , platformTypeEnum},
647
+ {" minos" , Type::IntegerType (4 , false )},
648
+ {" sdk" , Type::IntegerType (4 , false )},
649
+ {" ntools" , Type::IntegerType (4 , false )},
650
+ {" tools" , Type::ArrayType (buildToolVersionType, 0 )}
651
+ // clang-format on
652
+ });
653
+
654
+ auto sourceVersionCommandType = BuildStruct (view, " source_version_command" , false ,
655
+ {
656
+ // clang-format off
657
+ {" cmd" , cmdTypeEnum},
658
+ {" cmdsize" , Type::IntegerType (4 , false )},
659
+ {" version" , Type::IntegerType (8 , false )}
660
+ // clang-format on
661
+ });
662
+
663
+ auto entryPointCommandType = BuildStruct (view, " entry_point_command" , false ,
664
+ {
665
+ // clang-format off
666
+ {" cmd" , cmdTypeEnum},
667
+ {" cmdsize" , Type::IntegerType (4 , false )},
668
+ {" entryoff" , Type::IntegerType (8 , false )},
669
+ {" stacksize" , Type::IntegerType (8 , false )}
670
+ // clang-format on
671
+ });
672
+
673
+ // Used for the various LC_LOAD_* commands that have only a single string field.
674
+ auto stringCommandType = BuildStruct (view, " string_command" , false ,
675
+ {
676
+ // clang-format off
677
+ {" cmd" , cmdTypeEnum},
678
+ {" cmdsize" , Type::IntegerType (4 , false )},
679
+ {" value" , lcStringType}
680
+ // clang-format on
681
+ });
524
682
}
525
683
526
684
void ApplyHeaderTypes (Ref<BinaryView> view, Ref<Logger> logger, const BinaryReader& incomingReader,
@@ -609,6 +767,9 @@ void ApplyHeaderTypes(Ref<BinaryView> view, Ref<Logger> logger, const BinaryRead
609
767
case LC_DYLIB_CODE_SIGN_DRS:
610
768
case LC_DYLD_EXPORTS_TRIE:
611
769
case LC_DYLD_CHAINED_FIXUPS:
770
+ case LC_ATOM_INFO:
771
+ case LC_FUNCTION_VARIANTS:
772
+ case LC_FUNCTION_VARIANT_FIXUPS:
612
773
view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" linkedit_data_command" )));
613
774
break ;
614
775
case LC_ENCRYPTION_INFO:
@@ -623,8 +784,14 @@ void ApplyHeaderTypes(Ref<BinaryView> view, Ref<Logger> logger, const BinaryRead
623
784
view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" dyld_info_command" )));
624
785
break ;
625
786
case LC_FILESET_ENTRY:
626
- view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" fileset_entry_command" )));
787
+ {
788
+ auto type = Type::NamedType (view, QualifiedName (" fileset_entry_command" ));
789
+ view->DefineDataVariable (cmdAddr, type);
790
+ if (load.cmdsize - type->GetWidth () <= 150 )
791
+ view->DefineDataVariable (cmdAddr + type->GetWidth (),
792
+ Type::ArrayType (Type::IntegerType (1 , true ), load.cmdsize - type->GetWidth ()));
627
793
break ;
794
+ }
628
795
case LC_UNIXTHREAD:
629
796
{
630
797
view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" unix_thread_command" )));
@@ -633,6 +800,40 @@ void ApplyHeaderTypes(Ref<BinaryView> view, Ref<Logger> logger, const BinaryRead
633
800
view->DefineDataVariable (reader.GetOffset (), Type::ArrayType (Type::IntegerType (8 , true ), count));
634
801
break ;
635
802
}
803
+ case LC_BUILD_VERSION:
804
+ {
805
+ view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" build_version_command" )));
806
+ reader.SeekRelative (12 );
807
+ uint32_t count = reader.Read32 ();
808
+ view->DefineDataVariable (
809
+ reader.GetOffset (), Type::ArrayType (Type::NamedType (view, QualifiedName (" build_tool_version" )), count));
810
+ break ;
811
+ }
812
+ case LC_SOURCE_VERSION:
813
+ view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" source_version_command" )));
814
+ break ;
815
+ case LC_MAIN:
816
+ view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" entry_point_command" )));
817
+ break ;
818
+ case LC_DYLD_ENVIRONMENT:
819
+ case LC_ID_DYLINKER:
820
+ case LC_LOAD_DYLINKER:
821
+ case LC_RPATH:
822
+ case LC_SUB_CLIENT:
823
+ case LC_SUB_FRAMEWORK:
824
+ case LC_SUB_LIBRARY:
825
+ case LC_SUB_UMBRELLA:
826
+ case LC_TARGET_TRIPLE:
827
+ {
828
+ Ref<Type> type = Type::NamedType (view, QualifiedName (" string_command" ));
829
+ view->DefineDataVariable (cmdAddr, type);
830
+
831
+ if (load.cmdsize - type->GetWidth () <= 150 )
832
+ view->DefineDataVariable (cmdAddr + type->GetWidth (),
833
+ Type::ArrayType (Type::IntegerType (1 , true ), load.cmdsize - type->GetWidth ()));
834
+
835
+ break ;
836
+ }
636
837
default :
637
838
view->DefineDataVariable (cmdAddr, Type::NamedType (view, QualifiedName (" load_command" )));
638
839
break ;
0 commit comments