@@ -35,49 +35,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
35
#define MODULE_NAME macho
36
36
37
37
// Check for Mach-O binary magic constant.
38
-
39
38
int is_macho_file_block (const uint32_t * magic )
40
39
{
41
40
return * magic == MH_MAGIC || * magic == MH_CIGAM || * magic == MH_MAGIC_64 ||
42
41
* magic == MH_CIGAM_64 ;
43
42
}
44
43
45
44
// Check if file is for 32-bit architecture.
46
-
47
- int macho_is_32 (const uint8_t * magic )
48
- {
49
- // Magic must be [CE]FAEDFE or FEEDFA[CE].
50
- return magic [0 ] == 0xce || magic [3 ] == 0xce ;
51
- }
52
-
53
- // Check if file is for big-endian architecture.
54
-
55
- int macho_is_big (const uint8_t * magic )
45
+ int macho_is_32 (uint32_t magic )
56
46
{
57
- // Magic must be [FE]EDFACE or [FE]EDFACF.
58
- return magic [0 ] == 0xfe ;
47
+ return magic == MH_MAGIC || magic == MH_CIGAM ;
59
48
}
60
49
61
50
// Check for Mach-O fat binary magic constant.
62
-
63
51
int is_fat_macho_file_block (const uint32_t * magic )
64
52
{
65
53
return * magic == FAT_MAGIC || * magic == FAT_CIGAM || * magic == FAT_MAGIC_64 ||
66
54
* magic == FAT_CIGAM_64 ;
67
55
}
68
56
69
57
// Check if file is 32-bit fat file.
70
-
71
- int macho_fat_is_32 (const uint8_t * magic )
58
+ int macho_fat_is_32 (const uint32_t * magic )
72
59
{
73
- // Magic must be CAFEBA[BE].
74
- return magic [3 ] == 0xbe ;
60
+ return yr_be32toh (* magic ) == FAT_MAGIC ;
75
61
}
76
62
77
63
static int should_swap_bytes (const uint32_t magic )
78
64
{
65
+ // In big-endian platforms byte swapping is needed for little-endian files
66
+ // but in little-endian platforms the files that need swapping are the
67
+ // the big-endian ones.
68
+ #if defined(WORDS_BIGENDIAN )
79
69
return magic == MH_CIGAM || magic == MH_CIGAM_64 || magic == FAT_CIGAM ||
80
70
magic == FAT_CIGAM_64 ;
71
+ #else
72
+ return magic == MH_MAGIC || magic == MH_MAGIC_64 || magic == FAT_MAGIC ||
73
+ magic == FAT_MAGIC_64 ;
74
+ #endif
81
75
}
82
76
83
77
static void swap_mach_header (yr_mach_header_64_t * mh )
@@ -90,7 +84,7 @@ static void swap_mach_header(yr_mach_header_64_t* mh)
90
84
mh -> sizeofcmds = yr_bswap32 (mh -> sizeofcmds );
91
85
mh -> flags = yr_bswap32 (mh -> flags );
92
86
93
- if (!macho_is_32 (( const uint8_t * ) & mh -> magic ))
87
+ if (!macho_is_32 (mh -> magic ))
94
88
mh -> reserved = yr_bswap32 (mh -> reserved );
95
89
}
96
90
@@ -222,8 +216,8 @@ void macho_handle_unixthread(
222
216
return ;
223
217
224
218
// command_size is the size indicated in yr_thread_command_t structure, but
225
- // limited to the data's size because we can't rely on the structure having a
226
- // valid size.
219
+ // limited to the data's size because we can't rely on the structure having
220
+ // a valid size.
227
221
uint32_t command_size = yr_min (size , ((yr_thread_command_t * ) data )-> cmdsize );
228
222
229
223
// command_size should be at least the size of yr_thread_command_t.
@@ -441,13 +435,16 @@ void macho_handle_segment(
441
435
442
436
yr_set_integer (sec .size , object , "segments[%i].sections[%i].size" , i , j );
443
437
444
- yr_set_integer (sec .offset , object , "segments[%i].sections[%i].offset" , i , j );
438
+ yr_set_integer (
439
+ sec .offset , object , "segments[%i].sections[%i].offset" , i , j );
445
440
446
441
yr_set_integer (sec .align , object , "segments[%i].sections[%i].align" , i , j );
447
442
448
- yr_set_integer (sec .reloff , object , "segments[%i].sections[%i].reloff" , i , j );
443
+ yr_set_integer (
444
+ sec .reloff , object , "segments[%i].sections[%i].reloff" , i , j );
449
445
450
- yr_set_integer (sec .nreloc , object , "segments[%i].sections[%i].nreloc" , i , j );
446
+ yr_set_integer (
447
+ sec .nreloc , object , "segments[%i].sections[%i].nreloc" , i , j );
451
448
452
449
yr_set_integer (sec .flags , object , "segments[%i].sections[%i].flags" , i , j );
453
450
@@ -528,13 +525,16 @@ void macho_handle_segment_64(
528
525
529
526
yr_set_integer (sec .size , object , "segments[%i].sections[%i].size" , i , j );
530
527
531
- yr_set_integer (sec .offset , object , "segments[%i].sections[%i].offset" , i , j );
528
+ yr_set_integer (
529
+ sec .offset , object , "segments[%i].sections[%i].offset" , i , j );
532
530
533
531
yr_set_integer (sec .align , object , "segments[%i].sections[%i].align" , i , j );
534
532
535
- yr_set_integer (sec .reloff , object , "segments[%i].sections[%i].reloff" , i , j );
533
+ yr_set_integer (
534
+ sec .reloff , object , "segments[%i].sections[%i].reloff" , i , j );
536
535
537
- yr_set_integer (sec .nreloc , object , "segments[%i].sections[%i].nreloc" , i , j );
536
+ yr_set_integer (
537
+ sec .nreloc , object , "segments[%i].sections[%i].nreloc" , i , j );
538
538
539
539
yr_set_integer (sec .flags , object , "segments[%i].sections[%i].flags" , i , j );
540
540
@@ -563,15 +563,20 @@ void macho_parse_file(
563
563
if (size < sizeof (yr_mach_header_64_t ))
564
564
return ;
565
565
566
- size_t header_size = macho_is_32 (data ) ? sizeof (yr_mach_header_32_t )
567
- : sizeof (yr_mach_header_64_t );
568
-
569
- // yr_mach_header_64_t is used for storing the header for both for 32-bits and
570
- // 64-bits files. yr_mach_header_64_t is exactly like yr_mach_header_32_t
571
- // but with an extra "reserved" field at the end.
566
+ // yr_mach_header_64_t is used for storing the header for both for 32-bits
567
+ // and 64-bits files. yr_mach_header_64_t is exactly like
568
+ // yr_mach_header_32_t but with an extra "reserved" field at the end.
572
569
yr_mach_header_64_t header ;
573
570
574
- memcpy (& header , data , header_size );
571
+ memcpy (& header , data , sizeof (yr_mach_header_64_t ));
572
+
573
+ // The magic number is always handled as big-endian. If the magic bytes are
574
+ // CA FE BA BE, then header.magic is 0xCAFEBABE.
575
+ header .magic = yr_be32toh (header .magic );
576
+
577
+ size_t header_size = (header .magic == MH_MAGIC || header .magic == MH_CIGAM )
578
+ ? sizeof (yr_mach_header_32_t )
579
+ : sizeof (yr_mach_header_64_t );
575
580
576
581
int should_swap = should_swap_bytes (header .magic );
577
582
@@ -587,7 +592,7 @@ void macho_parse_file(
587
592
yr_set_integer (header .flags , object , "flags" );
588
593
589
594
// The "reserved" field exists only in 64 bits files.
590
- if (!macho_is_32 (data ))
595
+ if (!macho_is_32 (header . magic ))
591
596
yr_set_integer (header .reserved , object , "reserved" );
592
597
593
598
// The first command parsing pass handles only segments.
@@ -652,7 +657,8 @@ void macho_parse_file(
652
657
switch (command_struct .cmd )
653
658
{
654
659
case LC_UNIXTHREAD :
655
- macho_handle_unixthread (command , size - parsed_size , base_address , object , context );
660
+ macho_handle_unixthread (
661
+ command , size - parsed_size , base_address , object , context );
656
662
break ;
657
663
case LC_MAIN :
658
664
macho_handle_main (command , size - parsed_size , object , context );
@@ -672,10 +678,11 @@ void macho_load_fat_arch_header(
672
678
uint32_t num ,
673
679
yr_fat_arch_64_t * arch )
674
680
{
675
- if (macho_fat_is_32 (data ))
681
+ if (macho_fat_is_32 (( uint32_t * ) data ))
676
682
{
677
683
yr_fat_arch_32_t * arch32 =
678
- (yr_fat_arch_32_t * ) (data + sizeof (yr_fat_header_t ) + (num * sizeof (yr_fat_arch_32_t )));
684
+ (yr_fat_arch_32_t * ) (data + sizeof (yr_fat_header_t ) +
685
+ (num * sizeof (yr_fat_arch_32_t )));
679
686
680
687
arch -> cputype = yr_be32toh (arch32 -> cputype );
681
688
arch -> cpusubtype = yr_be32toh (arch32 -> cpusubtype );
@@ -687,7 +694,8 @@ void macho_load_fat_arch_header(
687
694
else
688
695
{
689
696
yr_fat_arch_64_t * arch64 =
690
- (yr_fat_arch_64_t * ) (data + sizeof (yr_fat_header_t ) + (num * sizeof (yr_fat_arch_64_t )));
697
+ (yr_fat_arch_64_t * ) (data + sizeof (yr_fat_header_t ) +
698
+ (num * sizeof (yr_fat_arch_64_t )));
691
699
692
700
arch -> cputype = yr_be32toh (arch64 -> cputype );
693
701
arch -> cpusubtype = yr_be32toh (arch64 -> cpusubtype );
@@ -707,7 +715,7 @@ void macho_parse_fat_file(
707
715
{
708
716
size_t fat_arch_sz = sizeof (yr_fat_arch_64_t );
709
717
710
- if (macho_fat_is_32 (data ))
718
+ if (macho_fat_is_32 (( uint32_t * ) data ))
711
719
fat_arch_sz = sizeof (yr_fat_arch_32_t );
712
720
713
721
if (size < sizeof (yr_fat_header_t ))
@@ -810,10 +818,12 @@ void macho_set_definitions(YR_OBJECT* object)
810
818
yr_set_integer (CPU_SUBTYPE_PENTII_M3 , object , "CPU_SUBTYPE_PENTII_M3" );
811
819
yr_set_integer (CPU_SUBTYPE_PENTII_M5 , object , "CPU_SUBTYPE_PENTII_M5" );
812
820
yr_set_integer (CPU_SUBTYPE_CELERON , object , "CPU_SUBTYPE_CELERON" );
813
- yr_set_integer (CPU_SUBTYPE_CELERON_MOBILE , object , "CPU_SUBTYPE_CELERON_MOBILE" );
821
+ yr_set_integer (
822
+ CPU_SUBTYPE_CELERON_MOBILE , object , "CPU_SUBTYPE_CELERON_MOBILE" );
814
823
yr_set_integer (CPU_SUBTYPE_PENTIUM_3 , object , "CPU_SUBTYPE_PENTIUM_3" );
815
824
yr_set_integer (CPU_SUBTYPE_PENTIUM_3_M , object , "CPU_SUBTYPE_PENTIUM_3_M" );
816
- yr_set_integer (CPU_SUBTYPE_PENTIUM_3_XEON , object , "CPU_SUBTYPE_PENTIUM_3_XEON" );
825
+ yr_set_integer (
826
+ CPU_SUBTYPE_PENTIUM_3_XEON , object , "CPU_SUBTYPE_PENTIUM_3_XEON" );
817
827
yr_set_integer (CPU_SUBTYPE_PENTIUM_M , object , "CPU_SUBTYPE_PENTIUM_M" );
818
828
yr_set_integer (CPU_SUBTYPE_PENTIUM_4 , object , "CPU_SUBTYPE_PENTIUM_4" );
819
829
yr_set_integer (CPU_SUBTYPE_PENTIUM_4_M , object , "CPU_SUBTYPE_PENTIUM_4_M" );
@@ -843,7 +853,8 @@ void macho_set_definitions(YR_OBJECT* object)
843
853
yr_set_integer (CPU_SUBTYPE_POWERPC_602 , object , "CPU_SUBTYPE_POWERPC_602" );
844
854
yr_set_integer (CPU_SUBTYPE_POWERPC_603 , object , "CPU_SUBTYPE_POWERPC_603" );
845
855
yr_set_integer (CPU_SUBTYPE_POWERPC_603e , object , "CPU_SUBTYPE_POWERPC_603e" );
846
- yr_set_integer (CPU_SUBTYPE_POWERPC_603ev , object , "CPU_SUBTYPE_POWERPC_603ev" );
856
+ yr_set_integer (
857
+ CPU_SUBTYPE_POWERPC_603ev , object , "CPU_SUBTYPE_POWERPC_603ev" );
847
858
yr_set_integer (CPU_SUBTYPE_POWERPC_604 , object , "CPU_SUBTYPE_POWERPC_604" );
848
859
yr_set_integer (CPU_SUBTYPE_POWERPC_604e , object , "CPU_SUBTYPE_POWERPC_604e" );
849
860
yr_set_integer (CPU_SUBTYPE_POWERPC_620 , object , "CPU_SUBTYPE_POWERPC_620" );
@@ -881,7 +892,8 @@ void macho_set_definitions(YR_OBJECT* object)
881
892
yr_set_integer (MH_NOFIXPREBINDING , object , "MH_NOFIXPREBINDING" );
882
893
yr_set_integer (MH_PREBINDABLE , object , "MH_PREBINDABLE" );
883
894
yr_set_integer (MH_ALLMODSBOUND , object , "MH_ALLMODSBOUND" );
884
- yr_set_integer (MH_SUBSECTIONS_VIA_SYMBOLS , object , "MH_SUBSECTIONS_VIA_SYMBOLS" );
895
+ yr_set_integer (
896
+ MH_SUBSECTIONS_VIA_SYMBOLS , object , "MH_SUBSECTIONS_VIA_SYMBOLS" );
885
897
yr_set_integer (MH_CANONICAL , object , "MH_CANONICAL" );
886
898
yr_set_integer (MH_WEAK_DEFINES , object , "MH_WEAK_DEFINES" );
887
899
yr_set_integer (MH_BINDS_TO_WEAK , object , "MH_BINDS_TO_WEAK" );
@@ -914,7 +926,8 @@ void macho_set_definitions(YR_OBJECT* object)
914
926
yr_set_integer (S_CSTRING_LITERALS , object , "S_CSTRING_LITERALS" );
915
927
yr_set_integer (S_4BYTE_LITERALS , object , "S_4BYTE_LITERALS" );
916
928
yr_set_integer (S_8BYTE_LITERALS , object , "S_8BYTE_LITERALS" );
917
- yr_set_integer (S_NON_LAZY_SYMBOL_POINTERS , object , "S_NON_LAZY_SYMBOL_POINTERS" );
929
+ yr_set_integer (
930
+ S_NON_LAZY_SYMBOL_POINTERS , object , "S_NON_LAZY_SYMBOL_POINTERS" );
918
931
yr_set_integer (S_LAZY_SYMBOL_POINTERS , object , "S_LAZY_SYMBOL_POINTERS" );
919
932
yr_set_integer (S_LITERAL_POINTERS , object , "S_LITERAL_POINTERS" );
920
933
yr_set_integer (S_SYMBOL_STUBS , object , "S_SYMBOL_STUBS" );
@@ -946,7 +959,8 @@ void macho_set_definitions(YR_OBJECT* object)
946
959
yr_set_integer (S_ATTR_STRIP_STATIC_SYMS , object , "S_ATTR_STRIP_STATIC_SYMS" );
947
960
yr_set_integer (S_ATTR_NO_DEAD_STRIP , object , "S_ATTR_NO_DEAD_STRIP" );
948
961
yr_set_integer (S_ATTR_LIVE_SUPPORT , object , "S_ATTR_LIVE_SUPPORT" );
949
- yr_set_integer (S_ATTR_SELF_MODIFYING_CODE , object , "S_ATTR_SELF_MODIFYING_CODE" );
962
+ yr_set_integer (
963
+ S_ATTR_SELF_MODIFYING_CODE , object , "S_ATTR_SELF_MODIFYING_CODE" );
950
964
yr_set_integer (S_ATTR_DEBUG , object , "S_ATTR_DEBUG" );
951
965
yr_set_integer (S_ATTR_SOME_INSTRUCTIONS , object , "S_ATTR_SOME_INSTRUCTIONS" );
952
966
yr_set_integer (S_ATTR_EXT_RELOC , object , "S_ATTR_EXT_RELOC" );
@@ -1048,9 +1062,12 @@ define_function(ep_for_arch_subtype)
1048
1062
uint64_t entry_point = yr_get_integer (module , "file[%i].entry_point" , i );
1049
1063
uint64_t file_offset = yr_get_integer (module , "fat_arch[%i].offset" , i );
1050
1064
1051
- if (entry_point == YR_UNDEFINED ) {
1065
+ if (entry_point == YR_UNDEFINED )
1066
+ {
1052
1067
return_integer (YR_UNDEFINED );
1053
- } else {
1068
+ }
1069
+ else
1070
+ {
1054
1071
return_integer (file_offset + entry_point );
1055
1072
}
1056
1073
}
0 commit comments