1 #pragma once 2 3 #include "Types.h" 4 5 namespace Macho 6 { 7 enum 8 { 9 MH_MAGIC = 0xFEEDFACE, 10 MH_MAGIC_64 = 0xFEEDFACF, 11 MH_CIGAM = 0xCEFAEDFE, 12 }; 13 14 enum CPU_ARCH 15 { 16 CPU_ARCH_ABI64 = 0x01000000, 17 }; 18 19 enum CPU_TYPE 20 { 21 CPU_TYPE_I386 = 0x07, 22 CPU_TYPE_ARM = 0x0C, 23 CPU_TYPE_ARM64 = CPU_ARCH_ABI64 | CPU_TYPE_ARM, 24 }; 25 26 enum CPU_SUBTYPE_I386 27 { 28 CPU_SUBTYPE_I386_ALL = 0x03, 29 }; 30 31 enum CPU_SUBTYPE_ARM 32 { 33 CPU_SUBTYPE_ARM_V6 = 0x06, 34 CPU_SUBTYPE_ARM_V7 = 0x09, 35 CPU_SUBTYPE_ARM_V7S = 0x0B 36 }; 37 38 enum CPU_SUBTYPE_ARM64 39 { 40 CPU_SUBTYPE_ARM64_ALL = 0, 41 }; 42 43 enum FILE_TYPE 44 { 45 MH_OBJECT = 0x01, 46 }; 47 48 enum HEADER_FLAGS 49 { 50 MH_SPLIT_SEGS = 0x0020, 51 MH_NOMULTIDEFS = 0x2000, 52 }; 53 54 enum SECTION_FLAGS 55 { 56 S_ATTR_SOME_INSTRUCTIONS = 0x00000400, 57 S_ATTR_PURE_INSTRUCTIONS = 0x80000000, 58 }; 59 60 enum LOAD_COMMAND 61 { 62 LC_SEGMENT = 0x0001, 63 LC_SYMTAB = 0x0002, 64 LC_SEGMENT_64 = 0x0019 65 }; 66 67 enum RELOC_TYPE 68 { 69 GENERIC_RELOC_VANILLA = 0, 70 GENERIC_RELOC_PAIR = 1, 71 72 ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA, 73 ARM_RELOC_PAIR = GENERIC_RELOC_PAIR, 74 ARM_RELOC_HALF = 8, 75 76 ARM64_RELOC_BRANCH26 = 2 77 }; 78 79 struct MACH_HEADER 80 { 81 uint32 magic; 82 uint32 cpuType; 83 uint32 cpuSubType; 84 uint32 fileType; 85 uint32 commandCount; 86 uint32 sizeofCommands; 87 uint32 flags; 88 }; 89 static_assert(sizeof(MACH_HEADER) == 0x1C, "Size of MACH_HEADER structure must be 28 bytes."); 90 91 struct MACH_HEADER_64 92 { 93 uint32 magic; 94 uint32 cpuType; 95 uint32 cpuSubType; 96 uint32 fileType; 97 uint32 commandCount; 98 uint32 sizeofCommands; 99 uint32 flags; 100 uint32 reserved; 101 }; 102 static_assert(sizeof(MACH_HEADER_64) == 0x20, "Size of MACH_HEADER_64 structure must be 32 bytes."); 103 104 struct COMMAND 105 { 106 uint32 cmd; 107 uint32 cmdSize; 108 }; 109 110 struct SEGMENT_COMMAND : public COMMAND 111 { 112 char name[0x10]; 113 uint32 vmAddress; 114 uint32 vmSize; 115 uint32 fileOffset; 116 uint32 fileSize; 117 uint32 maxProtection; 118 uint32 initProtection; 119 uint32 sectionCount; 120 uint32 flags; 121 }; 122 static_assert(sizeof(SEGMENT_COMMAND) == 0x38, "Size of SEGMENT_COMMAND structure must be 48 bytes."); 123 124 struct SEGMENT_COMMAND_64 : public COMMAND 125 { 126 char name[0x10]; 127 uint64 vmAddress; 128 uint64 vmSize; 129 uint64 fileOffset; 130 uint64 fileSize; 131 uint32 maxProtection; 132 uint32 initProtection; 133 uint32 sectionCount; 134 uint32 flags; 135 }; 136 static_assert(sizeof(SEGMENT_COMMAND_64) == 0x48, "Size of SEGMENT_COMMAND_64 structure must be 72 bytes."); 137 138 struct SECTION 139 { 140 char sectionName[0x10]; 141 char segmentName[0x10]; 142 uint32 address; 143 uint32 size; 144 uint32 offset; 145 uint32 align; 146 uint32 relocationOffset; 147 uint32 relocationCount; 148 uint32 flags; 149 uint32 reserved1; 150 uint32 reserved2; 151 }; 152 static_assert(sizeof(SECTION) == 0x44, "Size of SECTION structure must be 68 bytes."); 153 154 struct SECTION_64 155 { 156 char sectionName[16]; 157 char segmentName[16]; 158 uint64 address; 159 uint64 size; 160 uint32 offset; 161 uint32 align; 162 uint32 relocationOffset; 163 uint32 relocationCount; 164 uint32 flags; 165 uint32 reserved1; 166 uint32 reserved2; 167 uint32 reserved3; 168 }; 169 static_assert(sizeof(SECTION_64) == 0x50, "Size of SECTION_64 structure must be 80 bytes."); 170 171 struct SYMTAB_COMMAND : public COMMAND 172 { 173 uint32 symbolsOffset; 174 uint32 symbolCount; 175 uint32 stringsOffset; 176 uint32 stringsSize; 177 }; 178 static_assert(sizeof(SYMTAB_COMMAND) == 0x18, "Size of SYMTAB_COMMAND structure must be 24 bytes."); 179 180 struct NLIST 181 { 182 uint32 stringTableIndex; 183 uint8 type; 184 uint8 section; 185 uint16 desc; 186 uint32 value; 187 }; 188 static_assert(sizeof(NLIST) == 0xC, "Size of NLIST structure must be 12 bytes."); 189 190 struct NLIST_64 191 { 192 uint32 stringTableIndex; 193 uint8 type; 194 uint8 section; 195 uint16 desc; 196 uint64 value; 197 }; 198 static_assert(sizeof(NLIST_64) == 0x10, "Size of NLIST_64 structure must be 16 bytes."); 199 200 struct RELOCATION_INFO 201 { 202 uint32 address; 203 unsigned int symbolIndex : 24; 204 unsigned int pcRel : 1; 205 unsigned int length : 2; 206 unsigned int isExtern : 1; 207 unsigned int type : 4; 208 }; 209 static_assert(sizeof(RELOCATION_INFO) == 0x08, "Size of RELOCATION_INFO structure must be 8 bytes."); 210 } 211