1
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
//! Mach-O constants and flags.
use bitflags;
// =============================================================================
// Magic Numbers
// =============================================================================
/// 64-bit Mach-O magic (little-endian)
pub const MH_MAGIC_64: u32 = 0xFEEDFACF;
/// 64-bit Mach-O magic (big-endian, needs byte swap)
pub const MH_CIGAM_64: u32 = 0xCFFAEDFE;
/// 32-bit Mach-O magic (little-endian)
pub const MH_MAGIC: u32 = 0xFEEDFACE;
/// 32-bit Mach-O magic (big-endian)
pub const MH_CIGAM: u32 = 0xCEFAEDFE;
/// FAT binary magic
pub const FAT_MAGIC: u32 = 0xCAFEBABE;
// =============================================================================
// File Types
// =============================================================================
/// Object file
pub const MH_OBJECT: u32 = 0x1;
/// Executable
pub const MH_EXECUTE: u32 = 0x2;
/// Fixed VM shared library
pub const MH_FVMLIB: u32 = 0x3;
/// Core dump
pub const MH_CORE: u32 = 0x4;
/// Preloaded executable
pub const MH_PRELOAD: u32 = 0x5;
/// Dynamically bound shared library
pub const MH_DYLIB: u32 = 0x6;
/// Dynamic link editor
pub const MH_DYLINKER: u32 = 0x7;
/// Bundle
pub const MH_BUNDLE: u32 = 0x8;
/// Shared library stub
pub const MH_DYLIB_STUB: u32 = 0x9;
/// Debug symbols file
pub const MH_DSYM: u32 = 0xA;
/// Kernel extension bundle
pub const MH_KEXT_BUNDLE: u32 = 0xB;
/// File set (kernel cache)
pub const MH_FILESET: u32 = 0xC;
// =============================================================================
// CPU Types
// =============================================================================
/// 64-bit architecture flag
pub const CPU_ARCH_ABI64: u32 = 0x0100_0000;
/// ARM CPU type
pub const CPU_TYPE_ARM: u32 = 12;
/// ARM64 CPU type
pub const CPU_TYPE_ARM64: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64;
/// x86 CPU type
pub const CPU_TYPE_X86: u32 = 7;
/// x86_64 CPU type
pub const CPU_TYPE_X86_64: u32 = CPU_TYPE_X86 | CPU_ARCH_ABI64;
// =============================================================================
// CPU Subtypes
// =============================================================================
/// ARM64 all
pub const CPU_SUBTYPE_ARM64_ALL: u32 = 0;
/// ARM64 v8
pub const CPU_SUBTYPE_ARM64_V8: u32 = 1;
/// ARM64e (pointer authentication)
pub const CPU_SUBTYPE_ARM64E: u32 = 2;
// =============================================================================
// Load Commands
// =============================================================================
/// Load command requiring dynamic linker
pub const LC_REQ_DYLD: u32 = 0x8000_0000;
/// Segment of this file
pub const LC_SEGMENT: u32 = 0x1;
/// Link-edit symbol table info
pub const LC_SYMTAB: u32 = 0x2;
/// Link-edit thread local
pub const LC_SYMSEG: u32 = 0x3;
/// Thread
pub const LC_THREAD: u32 = 0x4;
/// Unix thread
pub const LC_UNIXTHREAD: u32 = 0x5;
/// Load a fixed VM shared library
pub const LC_LOADFVMLIB: u32 = 0x6;
/// Fixed VM shared library identification
pub const LC_IDFVMLIB: u32 = 0x7;
/// Object identification
pub const LC_IDENT: u32 = 0x8;
/// Fixed VM file inclusion
pub const LC_FVMFILE: u32 = 0x9;
/// Prepage command
pub const LC_PREPAGE: u32 = 0xA;
/// Dynamic link-edit symbol table info
pub const LC_DYSYMTAB: u32 = 0xB;
/// Load a dynamically linked shared library
pub const LC_LOAD_DYLIB: u32 = 0xC;
/// Dynamically linked shared lib identification
pub const LC_ID_DYLIB: u32 = 0xD;
/// Load a dynamic linker
pub const LC_LOAD_DYLINKER: u32 = 0xE;
/// Dynamic linker identification
pub const LC_ID_DYLINKER: u32 = 0xF;
/// Prebound modules
pub const LC_PREBOUND_DYLIB: u32 = 0x10;
/// Image routines
pub const LC_ROUTINES: u32 = 0x11;
/// Sub framework
pub const LC_SUB_FRAMEWORK: u32 = 0x12;
/// Sub umbrella
pub const LC_SUB_UMBRELLA: u32 = 0x13;
/// Sub client
pub const LC_SUB_CLIENT: u32 = 0x14;
/// Sub library
pub const LC_SUB_LIBRARY: u32 = 0x15;
/// Two-level namespace hints
pub const LC_TWOLEVEL_HINTS: u32 = 0x16;
/// Prebind checksum
pub const LC_PREBIND_CKSUM: u32 = 0x17;
/// Load a weak dynamically linked shared library
pub const LC_LOAD_WEAK_DYLIB: u32 = 0x18 | LC_REQ_DYLD;
/// 64-bit segment
pub const LC_SEGMENT_64: u32 = 0x19;
/// 64-bit image routines
pub const LC_ROUTINES_64: u32 = 0x1A;
/// UUID
pub const LC_UUID: u32 = 0x1B;
/// Runpath additions
pub const LC_RPATH: u32 = 0x1C | LC_REQ_DYLD;
/// Local of code signature
pub const LC_CODE_SIGNATURE: u32 = 0x1D;
/// Local of segment split info
pub const LC_SEGMENT_SPLIT_INFO: u32 = 0x1E;
/// Load and re-export dylib
pub const LC_REEXPORT_DYLIB: u32 = 0x1F | LC_REQ_DYLD;
/// Delay load of dylib
pub const LC_LAZY_LOAD_DYLIB: u32 = 0x20;
/// Encrypted segment information
pub const LC_ENCRYPTION_INFO: u32 = 0x21;
/// Compressed dyld info
pub const LC_DYLD_INFO: u32 = 0x22;
/// Compressed dyld info only
pub const LC_DYLD_INFO_ONLY: u32 = 0x22 | LC_REQ_DYLD;
/// Load upward dylib
pub const LC_LOAD_UPWARD_DYLIB: u32 = 0x23 | LC_REQ_DYLD;
/// Build for macOS min version
pub const LC_VERSION_MIN_MACOSX: u32 = 0x24;
/// Build for iOS min version
pub const LC_VERSION_MIN_IPHONEOS: u32 = 0x25;
/// Local of function starts
pub const LC_FUNCTION_STARTS: u32 = 0x26;
/// Environment variable string
pub const LC_DYLD_ENVIRONMENT: u32 = 0x27;
/// Main entry point (replacement for LC_UNIXTHREAD)
pub const LC_MAIN: u32 = 0x28 | LC_REQ_DYLD;
/// Table of non-instructions in __text
pub const LC_DATA_IN_CODE: u32 = 0x29;
/// Source version
pub const LC_SOURCE_VERSION: u32 = 0x2A;
/// Code signing DRs copied from linked dylibs
pub const LC_DYLIB_CODE_SIGN_DRS: u32 = 0x2B;
/// 64-bit encrypted segment information
pub const LC_ENCRYPTION_INFO_64: u32 = 0x2C;
/// Linker options
pub const LC_LINKER_OPTION: u32 = 0x2D;
/// Optimization hints
pub const LC_LINKER_OPTIMIZATION_HINT: u32 = 0x2E;
/// Build for tvOS min version
pub const LC_VERSION_MIN_TVOS: u32 = 0x2F;
/// Build for watchOS min version
pub const LC_VERSION_MIN_WATCHOS: u32 = 0x30;
/// Arbitrary data included within a Mach-O file
pub const LC_NOTE: u32 = 0x31;
/// Build for platform min version
pub const LC_BUILD_VERSION: u32 = 0x32;
/// Used with linkedit_data_command, payload is trie
pub const LC_DYLD_EXPORTS_TRIE: u32 = 0x33 | LC_REQ_DYLD;
/// Used with linkedit_data_command
pub const LC_DYLD_CHAINED_FIXUPS: u32 = 0x34 | LC_REQ_DYLD;
/// File set entry
pub const LC_FILESET_ENTRY: u32 = 0x35 | LC_REQ_DYLD;
/// Atom info
pub const LC_ATOM_INFO: u32 = 0x36;
// =============================================================================
// Section Types
// =============================================================================
/// Section types mask
pub const SECTION_TYPE: u32 = 0x0000_00FF;
/// Regular section
pub const S_REGULAR: u32 = 0x0;
/// Zero fill on demand
pub const S_ZEROFILL: u32 = 0x1;
/// Section with literal C strings
pub const S_CSTRING_LITERALS: u32 = 0x2;
/// Section with 4-byte literals
pub const S_4BYTE_LITERALS: u32 = 0x3;
/// Section with 8-byte literals
pub const S_8BYTE_LITERALS: u32 = 0x4;
/// Section with pointers to literals
pub const S_LITERAL_POINTERS: u32 = 0x5;
/// Section with non-lazy symbol pointers
pub const S_NON_LAZY_SYMBOL_POINTERS: u32 = 0x6;
/// Section with lazy symbol pointers
pub const S_LAZY_SYMBOL_POINTERS: u32 = 0x7;
/// Section with symbol stubs
pub const S_SYMBOL_STUBS: u32 = 0x8;
/// Section with only function pointers for initialization
pub const S_MOD_INIT_FUNC_POINTERS: u32 = 0x9;
/// Section with only function pointers for termination
pub const S_MOD_TERM_FUNC_POINTERS: u32 = 0xA;
/// Section contains symbols to be coalesced
pub const S_COALESCED: u32 = 0xB;
/// Zero fill on demand (>4GB)
pub const S_GB_ZEROFILL: u32 = 0xC;
/// Section with only pairs of function pointers for interposing
pub const S_INTERPOSING: u32 = 0xD;
/// Section with only 16-byte literals
pub const S_16BYTE_LITERALS: u32 = 0xE;
/// Section contains DTrace Object Format
pub const S_DTRACE_DOF: u32 = 0xF;
/// Section with only lazy symbol pointers to lazy loaded dylibs
pub const S_LAZY_DYLIB_SYMBOL_POINTERS: u32 = 0x10;
/// Thread local regular section
pub const S_THREAD_LOCAL_REGULAR: u32 = 0x11;
/// Thread local zerofill section
pub const S_THREAD_LOCAL_ZEROFILL: u32 = 0x12;
/// Thread local variable section
pub const S_THREAD_LOCAL_VARIABLES: u32 = 0x13;
/// Thread local variable pointer section
pub const S_THREAD_LOCAL_VARIABLE_POINTERS: u32 = 0x14;
/// Thread local init function pointer section
pub const S_THREAD_LOCAL_INIT_FUNCTION_POINTERS: u32 = 0x15;
/// Init function offsets
pub const S_INIT_FUNC_OFFSETS: u32 = 0x16;
// =============================================================================
// Section Attributes
// =============================================================================
/// Section attributes mask
pub const SECTION_ATTRIBUTES: u32 = 0xFFFF_FF00;
/// System attributes mask
pub const SECTION_ATTRIBUTES_SYS: u32 = 0x00FF_FF00;
/// User attributes mask
pub const SECTION_ATTRIBUTES_USR: u32 = 0xFF00_0000;
/// Section contains only true machine instructions
pub const S_ATTR_PURE_INSTRUCTIONS: u32 = 0x8000_0000;
/// Section contains coalesced symbols
pub const S_ATTR_NO_TOC: u32 = 0x4000_0000;
/// OK to strip static symbols
pub const S_ATTR_STRIP_STATIC_SYMS: u32 = 0x2000_0000;
/// No dead stripping
pub const S_ATTR_NO_DEAD_STRIP: u32 = 0x1000_0000;
/// Live support
pub const S_ATTR_LIVE_SUPPORT: u32 = 0x0800_0000;
/// Self modifying code
pub const S_ATTR_SELF_MODIFYING_CODE: u32 = 0x0400_0000;
/// Debug section
pub const S_ATTR_DEBUG: u32 = 0x0200_0000;
/// Section contains some machine instructions
pub const S_ATTR_SOME_INSTRUCTIONS: u32 = 0x0000_0400;
/// Section has external relocation entries
pub const S_ATTR_EXT_RELOC: u32 = 0x0000_0200;
/// Section has local relocation entries
pub const S_ATTR_LOC_RELOC: u32 = 0x0000_0100;
// =============================================================================
// Symbol Types
// =============================================================================
/// If any of these bits set, a symbolic debugging entry
pub const N_STAB: u8 = 0xE0;
/// Private external symbol bit
pub const N_PEXT: u8 = 0x10;
/// Mask for the type bits
pub const N_TYPE: u8 = 0x0E;
/// External symbol bit
pub const N_EXT: u8 = 0x01;
/// Undefined symbol
pub const N_UNDF: u8 = 0x0;
/// Absolute symbol
pub const N_ABS: u8 = 0x2;
/// Defined in section number n_sect
pub const N_SECT: u8 = 0xE;
/// Prebound undefined
pub const N_PBUD: u8 = 0xC;
/// Indirect
pub const N_INDR: u8 = 0xA;
// =============================================================================
// Indirect Symbol Table
// =============================================================================
/// Symbol is local
pub const INDIRECT_SYMBOL_LOCAL: u32 = 0x8000_0000;
/// Symbol is absolute
pub const INDIRECT_SYMBOL_ABS: u32 = 0x4000_0000;
// =============================================================================
// Header Flags
// =============================================================================
bitflags!