1 | /**************************************************************************/ |
2 | /* macho.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef MACOS_MACHO_H |
32 | #define MACOS_MACHO_H |
33 | |
34 | // Mach-O binary object file format parser and editor. |
35 | |
36 | #include "core/crypto/crypto.h" |
37 | #include "core/crypto/crypto_core.h" |
38 | #include "core/io/file_access.h" |
39 | #include "core/object/ref_counted.h" |
40 | |
41 | class MachO : public RefCounted { |
42 | struct { |
43 | uint32_t ; |
44 | uint32_t ; |
45 | uint32_t ; |
46 | uint32_t ; |
47 | uint32_t ; |
48 | uint32_t ; |
49 | }; |
50 | |
51 | enum LoadCommandID { |
52 | LC_SEGMENT = 0x00000001, |
53 | LC_SYMTAB = 0x00000002, |
54 | LC_SYMSEG = 0x00000003, |
55 | LC_THREAD = 0x00000004, |
56 | LC_UNIXTHREAD = 0x00000005, |
57 | LC_LOADFVMLIB = 0x00000006, |
58 | LC_IDFVMLIB = 0x00000007, |
59 | LC_IDENT = 0x00000008, |
60 | LC_FVMFILE = 0x00000009, |
61 | LC_PREPAGE = 0x0000000a, |
62 | LC_DYSYMTAB = 0x0000000b, |
63 | LC_LOAD_DYLIB = 0x0000000c, |
64 | LC_ID_DYLIB = 0x0000000d, |
65 | LC_LOAD_DYLINKER = 0x0000000e, |
66 | LC_ID_DYLINKER = 0x0000000f, |
67 | LC_PREBOUND_DYLIB = 0x00000010, |
68 | LC_ROUTINES = 0x00000011, |
69 | LC_SUB_FRAMEWORK = 0x00000012, |
70 | LC_SUB_UMBRELLA = 0x00000013, |
71 | LC_SUB_CLIENT = 0x00000014, |
72 | LC_SUB_LIBRARY = 0x00000015, |
73 | LC_TWOLEVEL_HINTS = 0x00000016, |
74 | LC_PREBIND_CKSUM = 0x00000017, |
75 | LC_LOAD_WEAK_DYLIB = 0x80000018, |
76 | LC_SEGMENT_64 = 0x00000019, |
77 | LC_ROUTINES_64 = 0x0000001a, |
78 | LC_UUID = 0x0000001b, |
79 | LC_RPATH = 0x8000001c, |
80 | LC_CODE_SIGNATURE = 0x0000001d, |
81 | LC_SEGMENT_SPLIT_INFO = 0x0000001e, |
82 | LC_REEXPORT_DYLIB = 0x8000001f, |
83 | LC_LAZY_LOAD_DYLIB = 0x00000020, |
84 | LC_ENCRYPTION_INFO = 0x00000021, |
85 | LC_DYLD_INFO = 0x00000022, |
86 | LC_DYLD_INFO_ONLY = 0x80000022, |
87 | LC_LOAD_UPWARD_DYLIB = 0x80000023, |
88 | LC_VERSION_MIN_MACOSX = 0x00000024, |
89 | LC_VERSION_MIN_IPHONEOS = 0x00000025, |
90 | LC_FUNCTION_STARTS = 0x00000026, |
91 | LC_DYLD_ENVIRONMENT = 0x00000027, |
92 | LC_MAIN = 0x80000028, |
93 | LC_DATA_IN_CODE = 0x00000029, |
94 | LC_SOURCE_VERSION = 0x0000002a, |
95 | LC_DYLIB_CODE_SIGN_DRS = 0x0000002b, |
96 | LC_ENCRYPTION_INFO_64 = 0x0000002c, |
97 | LC_LINKER_OPTION = 0x0000002d, |
98 | LC_LINKER_OPTIMIZATION_HINT = 0x0000002e, |
99 | LC_VERSION_MIN_TVOS = 0x0000002f, |
100 | LC_VERSION_MIN_WATCHOS = 0x00000030, |
101 | }; |
102 | |
103 | struct LoadCommandHeader { |
104 | uint32_t cmd; |
105 | uint32_t cmdsize; |
106 | }; |
107 | |
108 | struct LoadCommandSegment { |
109 | char segname[16]; |
110 | uint32_t vmaddr; |
111 | uint32_t vmsize; |
112 | uint32_t fileoff; |
113 | uint32_t filesize; |
114 | uint32_t maxprot; |
115 | uint32_t initprot; |
116 | uint32_t nsects; |
117 | uint32_t flags; |
118 | }; |
119 | |
120 | struct LoadCommandSegment64 { |
121 | char segname[16]; |
122 | uint64_t vmaddr; |
123 | uint64_t vmsize; |
124 | uint64_t fileoff; |
125 | uint64_t filesize; |
126 | uint32_t maxprot; |
127 | uint32_t initprot; |
128 | uint32_t nsects; |
129 | uint32_t flags; |
130 | }; |
131 | |
132 | struct Section { |
133 | char sectname[16]; |
134 | char segname[16]; |
135 | uint32_t addr; |
136 | uint32_t size; |
137 | uint32_t offset; |
138 | uint32_t align; |
139 | uint32_t reloff; |
140 | uint32_t nreloc; |
141 | uint32_t flags; |
142 | uint32_t reserved1; |
143 | uint32_t reserved2; |
144 | }; |
145 | |
146 | struct Section64 { |
147 | char sectname[16]; |
148 | char segname[16]; |
149 | uint64_t addr; |
150 | uint64_t size; |
151 | uint32_t offset; |
152 | uint32_t align; |
153 | uint32_t reloff; |
154 | uint32_t nreloc; |
155 | uint32_t flags; |
156 | uint32_t reserved1; |
157 | uint32_t reserved2; |
158 | uint32_t reserved3; |
159 | }; |
160 | |
161 | Ref<FileAccess> fa; |
162 | bool swap = false; |
163 | |
164 | uint64_t lc_limit = 0; |
165 | |
166 | uint64_t exe_limit = 0; |
167 | uint64_t exe_base = std::numeric_limits<uint64_t>::max(); // Start of first __text section. |
168 | uint32_t align = 0; |
169 | uint32_t cputype = 0; |
170 | uint32_t cpusubtype = 0; |
171 | |
172 | uint64_t link_edit_offset = 0; // __LINKEDIT segment offset. |
173 | uint64_t signature_offset = 0; // Load command offset. |
174 | |
175 | uint32_t seg_align(uint64_t p_vmaddr, uint32_t p_min, uint32_t p_max); |
176 | bool alloc_signature(uint64_t p_size); |
177 | |
178 | static inline size_t PAD(size_t s, size_t a) { |
179 | return (a - s % a); |
180 | } |
181 | |
182 | public: |
183 | static bool is_macho(const String &p_path); |
184 | |
185 | bool open_file(const String &p_path); |
186 | |
187 | uint64_t get_exe_base(); |
188 | uint64_t get_exe_limit(); |
189 | int32_t get_align(); |
190 | uint32_t get_cputype(); |
191 | uint32_t get_cpusubtype(); |
192 | uint64_t get_size(); |
193 | uint64_t get_code_limit(); |
194 | |
195 | uint64_t get_signature_offset(); |
196 | bool is_signed(); |
197 | |
198 | PackedByteArray get_cdhash_sha1(); |
199 | PackedByteArray get_cdhash_sha256(); |
200 | |
201 | PackedByteArray get_requirements(); |
202 | |
203 | const Ref<FileAccess> get_file() const; |
204 | Ref<FileAccess> get_file(); |
205 | |
206 | uint64_t get_signature_size(); |
207 | bool set_signature_size(uint64_t p_size); |
208 | }; |
209 | |
210 | #endif // MACOS_MACHO_H |
211 | |